001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http.annotation;
014
015import org.apache.juneau.httppart.*;
016
017/**
018 * Various reusable utility methods when working with annotations.
019 */
020public class AnnotationUtils {
021
022   //=================================================================================================================
023   // Methods for checking if annotations are empty.
024   //=================================================================================================================
025
026   /**
027    * Returns <jk>true</jk> if the specified annotation contains all default values.
028    *
029    * @param a The annotation to check.
030    * @return <jk>true</jk> if the specified annotation contains all default values.
031    */
032   public static boolean empty(Query a) {
033      if (a == null)
034         return true;
035      return
036         allEmpty(a.description(), a.d(), a._default(), a.df(), a.example(), a.ex(), a.api(), a._enum(), a.e())
037         && allEmpty(a.name(), a.n(), a.value(), a.type(), a.t(), a.format(), a.f(), a.pattern(), a.p(), a.collectionFormat(), a.cf(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo())
038         && allFalse(a.multi(), a.allowEmptyValue(), a.aev(), a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.required(), a.r(), a.uniqueItems(), a.ui(), a.skipIfEmpty(), a.sie())
039         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
040         && empty(a.items())
041         && a.parser() == HttpPartParser.Null.class
042         && a.serializer() == HttpPartSerializer.Null.class
043      ;
044   }
045
046   /**
047    * Returns <jk>true</jk> if the specified annotation contains all default values.
048    *
049    * @param a The annotation to check.
050    * @return <jk>true</jk> if the specified annotation contains all default values.
051    */
052   public static boolean empty(Header a) {
053      if (a == null)
054         return true;
055      return
056         allEmpty(a.description(), a.d(), a._default(), a.df(), a._enum(), a.e(), a.example(), a.ex(), a.api())
057         && allEmpty(a.name(), a.n(), a.value(), a.type(), a.t(), a.format(), a.f(), a.pattern(), a.p(), a.collectionFormat(), a.cf(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo())
058         && allFalse(a.multi(), a.allowEmptyValue(), a.aev(), a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.required(), a.r(), a.uniqueItems(), a.ui(), a.skipIfEmpty(), a.sie())
059         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
060         && empty(a.items())
061         && a.parser() == HttpPartParser.Null.class
062         && a.serializer() == HttpPartSerializer.Null.class
063      ;
064   }
065
066   /**
067    * Returns <jk>true</jk> if the specified annotation contains all default values.
068    *
069    * @param a The annotation to check.
070    * @return <jk>true</jk> if the specified annotation contains all default values.
071    */
072   public static boolean empty(FormData a) {
073      if (a == null)
074         return true;
075      return
076         allEmpty(a.description(), a.d(), a._default(), a.df(), a._enum(), a.e(), a.example(), a.ex(), a.api())
077         && allEmpty(a.name(), a.value(), a.n(), a.type(), a.t(), a.format(), a.f(), a.pattern(), a.p(), a.collectionFormat(), a.cf(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo())
078         && allFalse(a.multi(), a.allowEmptyValue(), a.aev(), a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.required(), a.r(), a.uniqueItems(), a.ui(), a.skipIfEmpty(), a.sie())
079         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
080         && empty(a.items())
081         && a.parser() == HttpPartParser.Null.class
082         && a.serializer() == HttpPartSerializer.Null.class
083      ;
084   }
085
086   /**
087    * Returns <jk>true</jk> if the specified annotation contains all default values.
088    *
089    * @param a The annotation to check.
090    * @return <jk>true</jk> if the specified annotation contains all default values.
091    */
092   public static boolean empty(Response a) {
093      if (a == null)
094         return true;
095      return
096         allEmpty(a.description(), a.d(), a.example(), a.ex(), a.examples(), a.exs(), a.api())
097         && a.code().length == 0
098         && a.value().length == 0
099         && a.headers().length == 0
100         && empty(a.schema())
101         && a.parser() == HttpPartParser.Null.class
102         && a.serializer() == HttpPartSerializer.Null.class
103      ;
104   }
105
106   /**
107    * Returns <jk>true</jk> if the specified annotation contains all default values.
108    *
109    * @param a The annotation to check.
110    * @return <jk>true</jk> if the specified annotation contains all default values.
111    */
112   public static boolean empty(ResponseHeader a) {
113      if (a == null)
114         return true;
115      return
116         allEmpty(a.description(), a.d(), a._default(), a.df(), a._enum(), a.e(), a.example(), a.ex(), a.api())
117         && allEmpty(a.name(), a.n(), a.value(), a.type(), a.t(), a.format(), a.f(), a.collectionFormat(), a.cf(), a.$ref(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo(), a.pattern(), a.p())
118         && allFalse(a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.uniqueItems(), a.ui())
119         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
120         && empty(a.items())
121         && a.code().length == 0
122         && a.serializer() == HttpPartSerializer.Null.class
123      ;
124   }
125
126   /**
127    * Returns <jk>true</jk> if the specified annotation contains all default values.
128    *
129    * @param a The annotation to check.
130    * @return <jk>true</jk> if the specified annotation contains all default values.
131    */
132   public static boolean empty(org.apache.juneau.jsonschema.annotation.Schema a) {
133      if (a == null)
134         return true;
135      return
136         allEmpty(a.value(), a.description(), a.d(), a._default(), a.df(), a._enum(), a.e(), a.allOf(), a.properties(), a.additionalProperties(), a.xml(), a.example(), a.ex(), a.examples(), a.exs())
137         && allEmpty(a.$ref(), a.format(), a.f(), a.title(), a.multipleOf(), a.mo(), a.maximum(), a.max(), a.minimum(), a.min(), a.pattern(), a.p(), a.type(), a.t(), a.discriminator(), a.collectionFormat(), a.cf(), a.on())
138         && allMinusOne(a.maxProperties(), a.maxp(), a.minProperties(), a.minp())
139         && allFalse(a.ignore(), a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.readOnly(), a.ro(), a.required(), a.r(), a.uniqueItems(), a.ui())
140         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
141         && empty(a.items())
142         && empty(a.externalDocs())
143      ;
144   }
145
146   /**
147    * Returns <jk>true</jk> if the specified annotation contains all default values.
148    *
149    * @param a The annotation to check.
150    * @return <jk>true</jk> if the specified annotation contains all default values.
151    */
152   public static boolean empty(org.apache.juneau.jsonschema.annotation.ExternalDocs a) {
153      if (a == null)
154         return true;
155      return
156         allEmpty(a.value(), a.description())
157         && allEmpty(a.url())
158      ;
159   }
160
161   /**
162    * Returns <jk>true</jk> if the specified annotation contains all default values.
163    *
164    * @param a The annotation to check.
165    * @return <jk>true</jk> if the specified annotation contains all default values.
166    */
167   public static boolean empty(Body a) {
168      if (a == null)
169         return true;
170      return
171         allEmpty(a.description(), a.d(), a.example(), a.ex(), a.examples(), a.exs(), a.api(), a.value())
172         && allFalse(a.required(), a.r())
173         && empty(a.schema())
174      ;
175   }
176
177   /**
178    * Returns <jk>true</jk> if the specified annotation contains all default values.
179    *
180    * @param a The annotation to check.
181    * @return <jk>true</jk> if the specified annotation contains all default values.
182    */
183   public static boolean empty(Contact a) {
184      if (a == null)
185         return true;
186      return
187         allEmpty(a.value())
188         && allEmpty(a.name(), a.url(), a.email())
189      ;
190   }
191
192   /**
193    * Returns <jk>true</jk> if the specified annotation contains all default values.
194    *
195    * @param a The annotation to check.
196    * @return <jk>true</jk> if the specified annotation contains all default values.
197    */
198   public static boolean empty(License a) {
199      if (a == null)
200         return true;
201      return
202         allEmpty(a.value())
203         && allEmpty(a.name(), a.url())
204      ;
205   }
206
207   /**
208    * Returns <jk>true</jk> if the specified annotation contains all default values.
209    *
210    * @param a The annotation to check.
211    * @return <jk>true</jk> if the specified annotation contains all default values.
212    */
213   public static boolean empty(org.apache.juneau.jsonschema.annotation.Items a) {
214      if (a == null)
215         return true;
216      return
217         allEmpty(a.value(), a._default(), a.df(), a._enum(), a.e())
218         && allEmpty(a.type(), a.t(), a.format(), a.f(), a.collectionFormat(), a.cf(), a.pattern(), a.p(), a.$ref(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo())
219         && allFalse(a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.uniqueItems(), a.ui())
220         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
221         && empty(a.items())
222      ;
223   }
224
225   /**
226    * Returns <jk>true</jk> if the specified annotation contains all default values.
227    *
228    * @param a The annotation to check.
229    * @return <jk>true</jk> if the specified annotation contains all default values.
230    */
231   public static boolean empty(org.apache.juneau.jsonschema.annotation.SubItems a) {
232      if (a == null)
233         return true;
234      return
235         allEmpty(a.value(), a._default(), a.df(), a._enum(), a.e(), a.items())
236         && allEmpty(a.type(), a.t(), a.format(), a.f(), a.collectionFormat(), a.cf(), a.pattern(), a.p(), a.$ref(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo())
237         && allFalse(a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.uniqueItems(), a.ui())
238         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
239      ;
240   }
241
242   /**
243    * Returns <jk>true</jk> if the specified annotation contains all default values.
244    *
245    * @param a The annotation to check.
246    * @return <jk>true</jk> if the specified annotation contains all default values.
247    */
248   public static boolean empty(Path a) {
249      if (a == null)
250         return true;
251      return
252         allEmpty(a.description(), a.d(), a._enum(), a.e(), a.example(), a.ex(), a.api())
253         && allEmpty(a.name(), a.value(), a.n(), a.type(), a.t(), a.format(), a.f(), a.pattern(), a.p(), a.maximum(), a.max(), a.minimum(), a.min(), a.multipleOf(), a.mo(), a.collectionFormat(), a.cf())
254         && allFalse(a.exclusiveMaximum(), a.emax(), a.exclusiveMinimum(), a.emin(), a.uniqueItems(), a.ui(), a.allowEmptyValue(), a.aev())
255         && allTrue(a.required(), a.r())
256         && allMinusOne(a.maxLength(), a.maxl(), a.minLength(), a.minl(), a.maxItems(), a.maxi(), a.minItems(), a.mini())
257         && empty(a.items())
258         && a.parser() == HttpPartParser.Null.class
259         && a.serializer() == HttpPartSerializer.Null.class
260      ;
261   }
262
263   /**
264    * Returns <jk>true</jk> if all the specified strings are empty or null.
265    *
266    * @param strings The strings to test.
267    * @return <jk>true</jk> if all the specified strings are empty or null.
268    */
269   protected static boolean allEmpty(String...strings) {
270      if (strings != null)
271         for (String s : strings)
272            if (s != null && ! s.isEmpty())
273               return false;
274      return true;
275   }
276
277   /**
278    * Returns <jk>true</jk> if all the specified string arrays are empty.
279    *
280    * @param strings The strings to test.
281    * @return <jk>true</jk> if all the specified string arrays are empty.
282    */
283   protected static boolean allEmpty(String[]...strings) {
284      for (String[] s : strings)
285         if (s != null && s.length > 0)
286            return false;
287      return true;
288   }
289
290   /**
291    * Returns <jk>true</jk> if all the specified booleans are false.
292    *
293    * @param booleans The booleans to test.
294    * @return <jk>true</jk> if all the specified booleans are false.
295    */
296   protected static boolean allFalse(boolean...booleans) {
297      for (boolean b : booleans)
298         if (b)
299            return false;
300      return true;
301   }
302
303   /**
304    * Returns <jk>true</jk> if all the specified booleans are true.
305    *
306    * @param booleans The booleans to test.
307    * @return <jk>true</jk> if all the specified booleans are true.
308    */
309   protected static boolean allTrue(boolean...booleans) {
310      for (boolean b : booleans)
311         if (! b)
312            return false;
313      return true;
314   }
315
316   /**
317    * Returns <jk>true</jk> if all the specified longs are -1.
318    *
319    * @param longs The booleans to test.
320    * @return <jk>true</jk> if all the specified longs are -1.
321    */
322   protected static boolean allMinusOne(long...longs) {
323      for (long i : longs)
324         if (i != -1)
325            return false;
326      return true;
327   }
328}