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   public static boolean empty(org.apache.juneau.jsonschema.annotation.ExternalDocs a) {
134      if (a == null)
135         return true;
136      return
137         allEmpty(a.value(), a.description())
138         && allEmpty(a.url());
139   }
140
141   /**
142    * Returns <jk>true</jk> if the specified annotation contains all default values.
143    *
144    * @param a The annotation to check.
145    * @return <jk>true</jk> if the specified annotation contains all default values.
146    */
147   public static boolean empty(Body a) {
148      if (a == null)
149         return true;
150      return
151         allEmpty(a.description(), a.example(), a.examples(), a.api(), a.value())
152         && allFalse(a.required())
153         && empty(a.schema());
154   }
155
156   /**
157    * Returns <jk>true</jk> if the specified annotation contains all default values.
158    *
159    * @param a The annotation to check.
160    * @return <jk>true</jk> if the specified annotation contains all default values.
161    */
162   public static boolean empty(Contact a) {
163      if (a == null)
164         return true;
165      return
166         allEmpty(a.value())
167         && allEmpty(a.name(), a.url(), a.email());
168   }
169
170   /**
171    * Returns <jk>true</jk> if the specified annotation contains all default values.
172    *
173    * @param a The annotation to check.
174    * @return <jk>true</jk> if the specified annotation contains all default values.
175    */
176   public static boolean empty(License a) {
177      if (a == null)
178         return true;
179      return
180         allEmpty(a.value())
181         && allEmpty(a.name(), a.url());
182   }
183
184   /**
185    * Returns <jk>true</jk> if the specified annotation contains all default values.
186    *
187    * @param a The annotation to check.
188    * @return <jk>true</jk> if the specified annotation contains all default values.
189    */
190   public static boolean empty(org.apache.juneau.jsonschema.annotation.Items a) {
191      if (a == null)
192         return true;
193      return
194         allEmpty(a.value(), a._default(), a._enum())
195         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
196         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
197         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
198         && empty(a.items());
199   }
200
201   /**
202    * Returns <jk>true</jk> if the specified annotation contains all default values.
203    *
204    * @param a The annotation to check.
205    * @return <jk>true</jk> if the specified annotation contains all default values.
206    */
207   public static boolean empty(org.apache.juneau.jsonschema.annotation.SubItems a) {
208      if (a == null)
209         return true;
210      return
211         allEmpty(a.value(), a._default(), a._enum(), a.items())
212         && allEmpty(a.type(), a.format(), a.collectionFormat(), a.pattern(), a.$ref(), a.maximum(), a.minimum(), a.multipleOf())
213         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
214         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems());
215   }
216
217   /**
218    * Returns <jk>true</jk> if the specified annotation contains all default values.
219    *
220    * @param a The annotation to check.
221    * @return <jk>true</jk> if the specified annotation contains all default values.
222    */
223   public static boolean empty(Path a) {
224      if (a == null)
225         return true;
226      return
227         allEmpty(a.description(), a._enum(), a.example(), a.api())
228         && allEmpty(a.name(), a.value(), a.type(), a.format(), a.pattern(), a.maximum(), a.minimum(), a.multipleOf())
229         && allFalse(a.exclusiveMaximum(), a.exclusiveMinimum(), a.uniqueItems())
230         && allMinusOne(a.maxLength(), a.minLength(), a.maxItems(), a.minItems())
231         && empty(a.items());
232   }
233
234   /**
235    * Returns <jk>true</jk> if all the specified strings are empty or null.
236    *
237    * @param strings The strings to test.
238    * @return <jk>true</jk> if all the specified strings are empty or null.
239    */
240   protected static boolean allEmpty(String...strings) {
241      if (strings != null)
242         for (String s : strings)
243            if (s != null && ! s.isEmpty())
244               return false;
245      return true;
246   }
247
248   /**
249    * Returns <jk>true</jk> if all the specified string arrays are empty.
250    *
251    * @param strings The strings to test.
252    * @return <jk>true</jk> if all the specified string arrays are empty.
253    */
254   protected static boolean allEmpty(String[]...strings) {
255      for (String[] s : strings)
256         if (s != null && s.length > 0)
257            return false;
258      return true;
259   }
260
261   /**
262    * Returns <jk>true</jk> if all the specified booleans are false.
263    *
264    * @param booleans The booleans to test.
265    * @return <jk>true</jk> if all the specified booleans are false.
266    */
267   protected static boolean allFalse(boolean...booleans) {
268      for (boolean b : booleans)
269         if (b)
270            return false;
271      return true;
272   }
273
274   /**
275    * Returns <jk>true</jk> if all the specified longs are -1.
276    *
277    * @param longs The booleans to test.
278    * @return <jk>true</jk> if all the specified longs are -1.
279    */
280   protected static boolean allMinusOne(long...longs) {
281      for (long i : longs)
282         if (i != -1)
283            return false;
284      return true;
285   }
286}