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