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.dto.swagger;
014
015import static org.apache.juneau.internal.BeanPropertyUtils.*;
016import static org.apache.juneau.internal.StringUtils.*;
017
018import java.util.*;
019
020import org.apache.juneau.annotation.*;
021import org.apache.juneau.internal.*;
022import org.apache.juneau.utils.*;
023
024/**
025 * The object provides metadata about the API.
026 *
027 * <p>
028 * The metadata can be used by the clients if needed, and can be presented
029 * in the Swagger-UI for convenience.
030 *
031 * <h5 class='section'>Example:</h5>
032 * <p class='bcode w800'>
033 *    <jc>// Construct using SwaggerBuilder.</jc>
034 *    Info x = <jsm>info</jsm>(<js>"Swagger Sample App"</js>, <js>"1.0.1"</js>)
035 *       .description(<js>"This is a sample server Petstore server."</js>)
036 *       .termsOfService(<js>"http://swagger.io/terms/"</js>)
037 *       .contact(
038 *          <jsm>contact</jsm>(<js>"API Support"</js>, <js>"http://www.swagger.io/support"</js>, <js>"support@swagger.io"</js>)
039 *       )
040 *       .license(
041 *          <jsm>license</jsm>(<js>"Apache 2.0"</js>, <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>)
042 *       );
043 *
044 *    <jc>// Serialize using JsonSerializer.</jc>
045 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
046 *
047 *    <jc>// Or just use toString() which does the same as above.</jc>
048 *    String json = x.toString();
049 * </p>
050 * <p class='bcode w800'>
051 *    <jc>// Output</jc>
052 *    {
053 *       <js>"title"</js>: <js>"Swagger Sample App"</js>,
054 *       <js>"description"</js>: <js>"This is a sample server Petstore server."</js>,
055 *       <js>"termsOfService"</js>: <js>"http://swagger.io/terms/"</js>,
056 *       <js>"contact"</js>: {
057 *          <js>"name"</js>: <js>"API Support"</js>,
058 *          <js>"url"</js>: <js>"http://www.swagger.io/support"</js>,
059 *          <js>"email"</js>: <js>"support@swagger.io"</js>
060 *       },
061 *       <js>"license"</js>: {
062 *          <js>"name"</js>: <js>"Apache 2.0"</js>,
063 *          <js>"url"</js>: <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>
064 *       },
065 *       <js>"version"</js>: <js>"1.0.1"</js>
066 *    }
067 * </p>
068 *
069 * <h5 class='section'>See Also:</h5>
070 * <ul class='doctree'>
071 *    <li class='link'>{@doc juneau-dto.Swagger}
072 * </ul>
073 */
074@Bean(properties="title,description,version,contact,license,termsOfService,*")
075public class Info extends SwaggerElement {
076
077   private String
078      title,
079      description,
080      termsOfService,
081      version;
082   private Contact contact;
083   private License license;
084
085   /**
086    * Default constructor.
087    */
088   public Info() {}
089
090   /**
091    * Copy constructor.
092    *
093    * @param copyFrom The object to copy.
094    */
095   public Info(Info copyFrom) {
096      super(copyFrom);
097
098      this.title = copyFrom.title;
099      this.description = copyFrom.description;
100      this.termsOfService = copyFrom.termsOfService;
101      this.version = copyFrom.version;
102      this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
103      this.license = copyFrom.license == null ? null : copyFrom.license.copy();
104   }
105
106   /**
107    * Make a deep copy of this object.
108    *
109    * @return A deep copy of this object.
110    */
111   public Info copy() {
112      return new Info(this);
113   }
114
115   /**
116    * Bean property getter:  <property>title</property>.
117    *
118    * <p>
119    * The title of the application.
120    *
121    * @return The property value, or <jk>null</jk> if it is not set.
122    */
123   public String getTitle() {
124      return title;
125   }
126
127   /**
128    * Bean property setter:  <property>title</property>.
129    *
130    * <p>
131    * The title of the application.
132    *
133    * @param value
134    *    The new value for this property.
135    *    <br>Property value is required.
136    * @return This object (for method chaining).
137    */
138   public Info setTitle(String value) {
139      title = value;
140      return this;
141   }
142
143   /**
144    * Same as {@link #setTitle(String)}.
145    *
146    * @param value
147    *    The new value for this property.
148    *    <br>Non-String values will be converted to String using <code>toString()</code>.
149    *    <br>Can be <jk>null</jk> to unset the property.
150    * @return This object (for method chaining).
151    */
152   public Info title(Object value) {
153      return setTitle(toStringVal(value));
154   }
155
156   /**
157    * Bean property getter:  <property>description</property>.
158    *
159    * <p>
160    * A short description of the application.
161    *
162    * @return The property value, or <jk>null</jk> if it is not set.
163    */
164   public String getDescription() {
165      return description;
166   }
167
168   /**
169    * Bean property setter:  <property>description</property>.
170    *
171    * <p>
172    * A short description of the application.
173    *
174    * @param value
175    *    The new value for this property.
176    *    <br>{@doc GFM} can be used for rich text representation.
177    *    <br>Can be <jk>null</jk> to unset the property.
178    * @return This object (for method chaining).
179    */
180   public Info setDescription(String value) {
181      description = value;
182      return this;
183   }
184
185   /**
186    * Same as {@link #setDescription(String)}.
187    *
188    * @param value
189    *    The new value for this property.
190    *    <br>Non-String values will be converted to String using <code>toString()</code>.
191    *    <br>{@doc GFM} can be used for rich text representation.
192    *    <br>Can be <jk>null</jk> to unset the property.
193    * @return This object (for method chaining).
194    */
195   public Info description(Object value) {
196      return setDescription(toStringVal(value));
197   }
198
199   /**
200    * Bean property getter:  <property>termsOfService</property>.
201    *
202    * <p>
203    * The Terms of Service for the API.
204    *
205    * @return The property value, or <jk>null</jk> if it is not set.
206    */
207   public String getTermsOfService() {
208      return termsOfService;
209   }
210
211   /**
212    * Bean property setter:  <property>termsOfService</property>.
213    *
214    * <p>
215    * The Terms of Service for the API.
216    *
217    * @param value
218    *    The new value for this property.
219    *    <br>Can be <jk>null</jk> to unset the property.
220    * @return This object (for method chaining).
221    */
222   public Info setTermsOfService(String value) {
223      termsOfService = value;
224      return this;
225   }
226
227   /**
228    * Same as {@link #setTermsOfService(String)}.
229    *
230    * @param value
231    *    The new value for this property.
232    *    <br>Non-String values will be converted to String using <code>toString()</code>.
233    *    <br>Can be <jk>null</jk> to unset the property.
234    * @return This object (for method chaining).
235    */
236   public Info termsOfService(Object value) {
237      return setTermsOfService(toStringVal(value));
238   }
239
240   /**
241    * Bean property getter:  <property>contact</property>.
242    *
243    * <p>
244    * The contact information for the exposed API.
245    *
246    * @return The property value, or <jk>null</jk> if it is not set.
247    */
248   public Contact getContact() {
249      return contact;
250   }
251
252   /**
253    * Bean property setter:  <property>contact</property>.
254    *
255    * <p>
256    * The contact information for the exposed API.
257    *
258    * @param value
259    *    The new value for this property.
260    *    <br>Can be <jk>null</jk> to unset the property.
261    * @return This object (for method chaining).
262    */
263   public Info setContact(Contact value) {
264      contact = value;
265      return this;
266   }
267
268   /**
269    * Same as {@link #setContact(Contact)}.
270    *
271    * @param value
272    *    The new value for this property.
273    *    <br>Valid types:
274    *    <ul>
275    *       <li>{@link Contact}
276    *       <li><code>String</code> - JSON object representation of {@link Contact}
277    *          <h5 class='figure'>Example:</h5>
278    *          <p class='bcode w800'>
279    *    contact(<js>"{name:'name',url:'url',...}"</js>);
280    *          </p>
281    *    </ul>
282    *    <br>Can be <jk>null</jk> to unset the property.
283    * @return This object (for method chaining).
284    */
285   public Info contact(Object value) {
286      return setContact(toType(value, Contact.class));
287   }
288
289   /**
290    * Bean property getter:  <property>license</property>.
291    *
292    * <p>
293    * The license information for the exposed API.
294    *
295    * @return The property value, or <jk>null</jk> if it is not set.
296    */
297   public License getLicense() {
298      return license;
299   }
300
301   /**
302    * Bean property setter:  <property>license</property>.
303    *
304    * <p>
305    * The license information for the exposed API.
306    *
307    * @param value
308    *    The new value for this property.
309    *    <br>Can be <jk>null</jk> to unset the property.
310    * @return This object (for method chaining).
311    */
312   public Info setLicense(License value) {
313      license = value;
314      return this;
315   }
316
317   /**
318    * Same as {@link #setLicense(License)}.
319    *
320    * @param value
321    *    The new value for this property.
322    *    <br>Valid types:
323    *    <ul>
324    *       <li>{@link License}
325    *       <li><code>String</code> - JSON object representation of {@link License}
326    *          <h5 class='figure'>Example:</h5>
327    *          <p class='bcode w800'>
328    *    license(<js>"{name:'name',url:'url',...}"</js>);
329    *          </p>
330    *    </ul>
331    *    <br>Can be <jk>null</jk> to unset the property.
332    * @return This object (for method chaining).
333    */
334   public Info license(Object value) {
335      return setLicense(toType(value, License.class));
336   }
337
338   /**
339    * Bean property getter:  <property>version</property>.
340    *
341    * <p>
342    * Provides the version of the application API (not to be confused with the specification version).
343    *
344    * @return The property value, or <jk>null</jk> if it is not set.
345    */
346   public String getVersion() {
347      return version;
348   }
349
350   /**
351    * Bean property setter:  <property>version</property>.
352    *
353    * <p>
354    * Provides the version of the application API (not to be confused with the specification version).
355    *
356    * @param value
357    *    The new value for this property.
358    *    <br>Property value is required.
359    * @return This object (for method chaining).
360    */
361   public Info setVersion(String value) {
362      version = value;
363      return this;
364   }
365
366   /**
367    * Same as {@link #setVersion(String)}.
368    *
369    * @param value
370    *    The new value for this property.
371    *    <br>Non-String values will be converted to String using <code>toString()</code>.
372    *    <br>Can be <jk>null</jk> to unset the property.
373    * @return This object (for method chaining).
374    */
375   public Info version(Object value) {
376      return setVersion(toStringVal(value));
377   }
378
379
380   /**
381    * Returns <jk>true</jk> if the title property is not null or empty.
382    *
383    * @return <jk>true</jk> if the title property is not null or empty.
384    */
385   public boolean hasTitle() {
386      return isNotEmpty(title);
387   }
388
389   /**
390    * Returns <jk>true</jk> if the description property is not null or empty.
391    *
392    * @return <jk>true</jk> if the description property is not null or empty.
393    */
394   public boolean hasDescription() {
395      return isNotEmpty(description);
396   }
397
398   /**
399    * Returns <jk>true</jk> if the version property is not null or empty.
400    *
401    * @return <jk>true</jk> if the version property is not null or empty.
402    */
403   public boolean hasVersion() {
404      return isNotEmpty(version);
405   }
406
407   /**
408    * Returns <jk>true</jk> if the termsOfService property is not null or empty.
409    *
410    * @return <jk>true</jk> if the termsOfService property is not null or empty.
411    */
412   public boolean hasTermsOfService() {
413      return isNotEmpty(termsOfService);
414   }
415
416   @Override /* SwaggerElement */
417   public <T> T get(String property, Class<T> type) {
418      if (property == null)
419         return null;
420      switch (property) {
421         case "title": return toType(getTitle(), type);
422         case "description": return toType(getDescription(), type);
423         case "termsOfService": return toType(getTermsOfService(), type);
424         case "contact": return toType(getContact(), type);
425         case "license": return toType(getLicense(), type);
426         case "version": return toType(getVersion(), type);
427         default: return super.get(property, type);
428      }
429   }
430
431   @Override /* SwaggerElement */
432   public Info set(String property, Object value) {
433      if (property == null)
434         return this;
435      switch (property) {
436         case "title": return title(value);
437         case "description": return description(value);
438         case "termsOfService": return termsOfService(value);
439         case "contact": return contact(value);
440         case "license": return license(value);
441         case "version": return version(value);
442         default:
443            super.set(property, value);
444            return this;
445      }
446   }
447
448   @Override /* SwaggerElement */
449   public Set<String> keySet() {
450      ASet<String> s = new ASet<String>()
451         .appendIf(title != null, "title")
452         .appendIf(description != null, "description")
453         .appendIf(termsOfService != null, "termsOfService")
454         .appendIf(contact != null, "contact")
455         .appendIf(license != null, "license")
456         .appendIf(version != null, "version");
457      return new MultiSet<>(s, super.keySet());
458   }
459}