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
015/**
016 * Various reusable utility methods when working with annotations.
017 */
018public class AnnotationUtils {
019
020   //=================================================================================================================
021   // Methods for checking if annotations are empty.
022   //=================================================================================================================
023
024   /**
025    * Returns <jk>true</jk> if the specified annotation contains all default values.
026    *
027    * @param a The annotation to check.
028    * @return <jk>true</jk> if the specified annotation contains all default values.
029    */
030   public static boolean empty(Query a) {
031      if (a == null)
032         return true;
033      return
034         allEmpty(a.description(), a._default(), a.example(), a.api())
035         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.pattern(), a.collectionFormat(), a.maximum(), a.minimum(), a.multipleOf())
036         && allFalse(a.allowEmptyValue(), a.exclusiveMaximum(), a.exclusiveMinimum(), a.required(), a.uniqueItems())
037         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
038         && empty(a.items());
039   }
040
041   /**
042    * Returns <jk>true</jk> if the specified annotation contains all default values.
043    *
044    * @param a The annotation to check.
045    * @return <jk>true</jk> if the specified annotation contains all default values.
046    */
047   public static boolean empty(Header a) {
048      if (a == null)
049         return true;
050      return
051         allEmpty(a.description(), a._default(), a._enum(), a.example(), a.api())
052         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.pattern(), a.collectionFormat(), a.maximum(), a.minimum(), a.multipleOf())
053         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.required(), a.uniqueItems())
054         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
055         && empty(a.items());
056   }
057
058   /**
059    * Returns <jk>true</jk> if the specified annotation contains all default values.
060    *
061    * @param a The annotation to check.
062    * @return <jk>true</jk> if the specified annotation contains all default values.
063    */
064   public static boolean empty(FormData a) {
065      if (a == null)
066         return true;
067      return
068         allEmpty(a.description(), a._default(), a._enum(), a.example(), a.api())
069         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.pattern(), a.collectionFormat(), a.maximum(), a.minimum(), a.multipleOf())
070         && allFalse(a.allowEmptyValue(), a.exclusiveMaximum(), a.exclusiveMinimum(), a.required(), a.uniqueItems())
071         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
072         && empty(a.items());
073   }
074
075   /**
076    * Returns <jk>true</jk> if the specified annotation contains all default values.
077    *
078    * @param a The annotation to check.
079    * @return <jk>true</jk> if the specified annotation contains all default values.
080    */
081   public static boolean empty(Response a) {
082      if (a == null)
083         return true;
084      return
085         allEmpty(a.description(), a.example(), a.examples(), a.api())
086         && a.headers().length == 0
087         && empty(a.schema())
088      ;
089   }
090
091   /**
092    * Returns <jk>true</jk> if the specified annotation contains all default values.
093    *
094    * @param a The annotation to check.
095    * @return <jk>true</jk> if the specified annotation contains all default values.
096    */
097   public static boolean empty(ResponseHeader a) {
098      if (a == null)
099         return true;
100      return
101         allEmpty(a.description(), a._default(), a._enum(), a.example(), a.api())
102         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.collectionFormat(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
103         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
104         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
105         && empty(a.items());
106   }
107
108   /**
109    * Returns <jk>true</jk> if the specified annotation contains all default values.
110    *
111    * @param a The annotation to check.
112    * @return <jk>true</jk> if the specified annotation contains all default values.
113    */
114   public static boolean empty(org.apache.juneau.jsonschema.annotation.Schema a) {
115      if (a == null)
116         return true;
117      return
118         allEmpty(a.value(), a.description(), a._default(), a._enum(), a.allOf(), a.properties(), a.additionalProperties(), a.xml(), a.example(), a.examples())
119         && allEmpty(a.$ref(), a.format(), a.title(), a.multipleOf(), a.maximum(), a.minimum(), a.pattern(), a.type(), a.discriminator())
120         && allMinusOne(a.maxProperties(), a.minProperties())
121         && allFalse(a.ignore(), a.exclusiveMaximum(), a.exclusiveMinimum(), a.readOnly(), a.required(), a.uniqueItems())
122         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
123         && empty(a.items())
124         && empty(a.externalDocs());
125   }
126
127   /**
128    * Returns <jk>true</jk> if the specified annotation contains all default values.
129    *
130    * @param a The annotation to check.
131    * @return <jk>true</jk> if the specified annotation contains all default values.
132    */
133   @Deprecated
134   public static boolean empty(org.apache.juneau.http.annotation.Schema a) {
135      if (a == null)
136         return true;
137      return
138         allEmpty(a.value(), a.description(), a._default(), a._enum(), a.allOf(), a.properties(), a.additionalProperties(), a.xml(), a.example(), a.examples())
139         && allEmpty(a.$ref(), a.format(), a.title(), a.multipleOf(), a.maximum(), a.minimum(), a.pattern(), a.type(), a.discriminator())
140         && allMinusOne(a.maxProperties(), a.minProperties())
141         && allFalse(a.ignore(), a.exclusiveMaximum(), a.exclusiveMinimum(), a.readOnly(), a.required(), a.uniqueItems())
142         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
143         && empty(a.items())
144         && empty(a.externalDocs());
145   }
146
147   /**
148    * Returns <jk>true</jk> if the specified annotation contains all default values.
149    *
150    * @param a The annotation to check.
151    * @return <jk>true</jk> if the specified annotation contains all default values.
152    */
153   public static boolean empty(org.apache.juneau.jsonschema.annotation.ExternalDocs a) {
154      if (a == null)
155         return true;
156      return
157         allEmpty(a.value(), a.description())
158         && allEmpty(a.url());
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   @Deprecated
168   public static boolean empty(org.apache.juneau.http.annotation.ExternalDocs a) {
169      if (a == null)
170         return true;
171      return
172         allEmpty(a.value(), a.description())
173         && allEmpty(a.url());
174   }
175
176   /**
177    * Returns <jk>true</jk> if the specified annotation contains all default values.
178    *
179    * @param a The annotation to check.
180    * @return <jk>true</jk> if the specified annotation contains all default values.
181    */
182   public static boolean empty(Body a) {
183      if (a == null)
184         return true;
185      return
186         allEmpty(a.description(), a.example(), a.examples(), a.api(), a.value())
187         && allFalse(a.required())
188         && empty(a.schema());
189   }
190
191   /**
192    * Returns <jk>true</jk> if the specified annotation contains all default values.
193    *
194    * @param a The annotation to check.
195    * @return <jk>true</jk> if the specified annotation contains all default values.
196    */
197   public static boolean empty(Contact a) {
198      if (a == null)
199         return true;
200      return
201         allEmpty(a.value())
202         && allEmpty(a.name(), a.url(), a.email());
203   }
204
205   /**
206    * Returns <jk>true</jk> if the specified annotation contains all default values.
207    *
208    * @param a The annotation to check.
209    * @return <jk>true</jk> if the specified annotation contains all default values.
210    */
211   public static boolean empty(License a) {
212      if (a == null)
213         return true;
214      return
215         allEmpty(a.value())
216         && allEmpty(a.name(), a.url());
217   }
218
219   /**
220    * Returns <jk>true</jk> if the specified annotation contains all default values.
221    *
222    * @param a The annotation to check.
223    * @return <jk>true</jk> if the specified annotation contains all default values.
224    */
225   public static boolean empty(org.apache.juneau.jsonschema.annotation.Items a) {
226      if (a == null)
227         return true;
228      return
229         allEmpty(a.value(), a._default(), a._enum())
230         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
231         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
232         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
233         && empty(a.items());
234   }
235
236   /**
237    * Returns <jk>true</jk> if the specified annotation contains all default values.
238    *
239    * @param a The annotation to check.
240    * @return <jk>true</jk> if the specified annotation contains all default values.
241    */
242   @Deprecated
243   public static boolean empty(org.apache.juneau.http.annotation.Items a) {
244      if (a == null)
245         return true;
246      return
247         allEmpty(a.value(), a._default(), a._enum())
248         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
249         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
250         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
251         && empty(a.items());
252   }
253
254   /**
255    * Returns <jk>true</jk> if the specified annotation contains all default values.
256    *
257    * @param a The annotation to check.
258    * @return <jk>true</jk> if the specified annotation contains all default values.
259    */
260   public static boolean empty(org.apache.juneau.jsonschema.annotation.SubItems a) {
261      if (a == null)
262         return true;
263      return
264         allEmpty(a.value(), a._default(), a._enum(), a.items())
265         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
266         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
267         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems());
268   }
269
270   /**
271    * Returns <jk>true</jk> if the specified annotation contains all default values.
272    *
273    * @param a The annotation to check.
274    * @return <jk>true</jk> if the specified annotation contains all default values.
275    */
276   @Deprecated
277   public static boolean empty(org.apache.juneau.http.annotation.SubItems a) {
278      if (a == null)
279         return true;
280      return
281         allEmpty(a.value(), a._default(), a._enum(), a.items())
282         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
283         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
284         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems());
285   }
286
287   /**
288    * Returns <jk>true</jk> if the specified annotation contains all default values.
289    *
290    * @param a The annotation to check.
291    * @return <jk>true</jk> if the specified annotation contains all default values.
292    */
293   public static boolean empty(Path a) {
294      if (a == null)
295         return true;
296      return
297         allEmpty(a.description(), a._enum(), a.example(), a.api())
298         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.pattern(), a.maximum(), a.minimum(), a.multipleOf())
299         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
300         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
301         && empty(a.items());
302   }
303
304   /**
305    * Returns <jk>true</jk> if all the specified strings are empty or null.
306    *
307    * @param strings The strings to test.
308    * @return <jk>true</jk> if all the specified strings are empty or null.
309    */
310   protected static boolean allEmpty(String...strings) {
311      if (strings != null)
312         for (String s : strings)
313            if (s != null && ! s.isEmpty())
314               return false;
315      return true;
316   }
317
318   /**
319    * Returns <jk>true</jk> if all the specified string arrays are empty.
320    *
321    * @param strings The strings to test.
322    * @return <jk>true</jk> if all the specified string arrays are empty.
323    */
324   protected static boolean allEmpty(String[]...strings) {
325      for (String[] s : strings)
326         if (s != null && s.length > 0)
327            return false;
328      return true;
329   }
330
331   /**
332    * Returns <jk>true</jk> if all the specified booleans are false.
333    *
334    * @param booleans The booleans to test.
335    * @return <jk>true</jk> if all the specified booleans are false.
336    */
337   protected static boolean allFalse(boolean...booleans) {
338      for (boolean b : booleans)
339         if (b)
340            return false;
341      return true;
342   }
343
344   /**
345    * Returns <jk>true</jk> if all the specified longs are -1.
346    *
347    * @param longs The booleans to test.
348    * @return <jk>true</jk> if all the specified longs are -1.
349    */
350   protected static boolean allMinusOne(long...longs) {
351      for (long i : longs)
352         if (i != -1)
353            return false;
354      return true;
355   }
356}