001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.swagger;
018
019import static org.apache.juneau.common.utils.Utils.*;
020import static org.apache.juneau.internal.CollectionUtils.*;
021import static org.apache.juneau.internal.ConverterUtils.*;
022
023import java.util.*;
024
025import org.apache.juneau.common.utils.*;
026import org.apache.juneau.internal.*;
027
028/**
029 * Provides metadata about the API.
030 *
031 * <p>
032 * The Info Object provides metadata about the API for Swagger 2.0. The metadata can be used by the clients if needed, 
033 * and can be presented in the Swagger-UI for convenience. This includes the title, version, description, terms of service, 
034 * contact information, and license.
035 *
036 * <h5 class='section'>Swagger Specification:</h5>
037 * <p>
038 * The Info Object is composed of the following fields:
039 * <ul class='spaced-list'>
040 *    <li><c>title</c> (string, REQUIRED) - The title of the API
041 *    <li><c>version</c> (string, REQUIRED) - The version of the OpenAPI document (not the API itself)
042 *    <li><c>description</c> (string) - A short description of the API
043 *    <li><c>termsOfService</c> (string) - A URL to the Terms of Service for the API
044 *    <li><c>contact</c> ({@link Contact}) - Contact information for the exposed API
045 *    <li><c>license</c> ({@link License}) - License information for the exposed API
046 * </ul>
047 *
048 * <h5 class='section'>Example:</h5>
049 * <p class='bjava'>
050 *    <jc>// Construct using SwaggerBuilder.</jc>
051 *    Info <jv>info</jv> = <jsm>info</jsm>(<js>"Swagger Sample App"</js>, <js>"1.0.1"</js>)
052 *       .description(<js>"This is a sample server Petstore server."</js>)
053 *       .termsOfService(<js>"http://swagger.io/terms/"</js>)
054 *       .contact(
055 *          <jsm>contact</jsm>(<js>"API Support"</js>, <js>"http://www.swagger.io/support"</js>, <js>"support@swagger.io"</js>)
056 *       )
057 *       .license(
058 *          <jsm>license</jsm>(<js>"Apache 2.0"</js>, <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>)
059 *       );
060 *
061 *    <jc>// Serialize using JsonSerializer.</jc>
062 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>info</jv>);
063 *
064 *    <jc>// Or just use toString() which does the same as above.</jc>
065 *    <jv>json</jv> = <jv>info</jv>.toString();
066 * </p>
067 * <p class='bjson'>
068 *    <jc>// Output</jc>
069 *    {
070 *       <js>"title"</js>: <js>"Swagger Sample App"</js>,
071 *       <js>"description"</js>: <js>"This is a sample server Petstore server."</js>,
072 *       <js>"termsOfService"</js>: <js>"http://swagger.io/terms/"</js>,
073 *       <js>"contact"</js>: {
074 *          <js>"name"</js>: <js>"API Support"</js>,
075 *          <js>"url"</js>: <js>"http://www.swagger.io/support"</js>,
076 *          <js>"email"</js>: <js>"support@swagger.io"</js>
077 *       },
078 *       <js>"license"</js>: {
079 *          <js>"name"</js>: <js>"Apache 2.0"</js>,
080 *          <js>"url"</js>: <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>
081 *       },
082 *       <js>"version"</js>: <js>"1.0.1"</js>
083 *    }
084 * </p>
085 *
086 * <h5 class='section'>See Also:</h5><ul>
087 *    <li class='link'><a class="doclink" href="https://swagger.io/specification/v2/#info-object">Swagger 2.0 Specification &gt; Info Object</a>
088 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/2-0/api-general-info/">Swagger API General Info</a>
089 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>
090 * </ul>
091 */
092public class Info extends SwaggerElement {
093
094   private String
095      siteName,
096      title,
097      description,
098      termsOfService,
099      version;
100   private Contact contact;
101   private License license;
102
103   /**
104    * Default constructor.
105    */
106   public Info() {}
107
108   /**
109    * Copy constructor.
110    *
111    * @param copyFrom The object to copy.
112    */
113   public Info(Info copyFrom) {
114      super(copyFrom);
115
116      this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
117      this.description = copyFrom.description;
118      this.license = copyFrom.license == null ? null : copyFrom.license.copy();
119      this.siteName = copyFrom.siteName;
120      this.termsOfService = copyFrom.termsOfService;
121      this.title = copyFrom.title;
122      this.version = copyFrom.version;
123   }
124
125   /**
126    * Make a deep copy of this object.
127    *
128    * @return A deep copy of this object.
129    */
130   public Info copy() {
131      return new Info(this);
132   }
133
134   //-----------------------------------------------------------------------------------------------------------------
135   // Properties
136   //-----------------------------------------------------------------------------------------------------------------
137
138   /**
139    * Bean property getter:  <property>contact</property>.
140    *
141    * <p>
142    * The contact information for the exposed API.
143    *
144    * @return The property value, or <jk>null</jk> if it is not set.
145    */
146   public Contact getContact() {
147      return contact;
148   }
149
150   /**
151    * Bean property setter:  <property>contact</property>.
152    *
153    * <p>
154    * The contact information for the exposed API.
155    *
156    * @param value
157    *    The new value for this property.
158    *    <br>Can be <jk>null</jk> to unset the property.
159    * @return This object.
160    */
161   public Info setContact(Contact value) {
162      contact = value;
163      return this;
164   }
165
166   /**
167    * Bean property getter:  <property>description</property>.
168    *
169    * <p>
170    * A short description of the application.
171    *
172    * @return The property value, or <jk>null</jk> if it is not set.
173    */
174   public String getDescription() {
175      return description;
176   }
177
178   /**
179    * Bean property setter:  <property>description</property>.
180    *
181    * <p>
182    * A short description of the application.
183    *
184    * @param value
185    *    The new value for this property.
186    *    <br><a class="doclink" href="https://help.github.com/articles/github-flavored-markdown">GFM syntax</a> can be used for rich text representation.
187    *    <br>Can be <jk>null</jk> to unset the property.
188    * @return This object.
189    */
190   public Info setDescription(String value) {
191      description = value;
192      return this;
193   }
194
195   /**
196    * Bean property getter:  <property>license</property>.
197    *
198    * <p>
199    * The license information for the exposed API.
200    *
201    * @return The property value, or <jk>null</jk> if it is not set.
202    */
203   public License getLicense() {
204      return license;
205   }
206
207   /**
208    * Bean property setter:  <property>license</property>.
209    *
210    * <p>
211    * The license information for the exposed API.
212    *
213    * @param value
214    *    The new value for this property.
215    *    <br>Can be <jk>null</jk> to unset the property.
216    * @return This object.
217    */
218   public Info setLicense(License value) {
219      license = value;
220      return this;
221   }
222
223   /**
224    * Bean property getter:  <property>siteName</property>.
225    *
226    * <p>
227    * The site name of the application.
228    *
229    * @return The property value, or <jk>null</jk> if it is not set.
230    */
231   public String getSiteName() {
232      return siteName;
233   }
234
235   /**
236    * Bean property setter:  <property>siteName</property>.
237    *
238    * <p>
239    * The site name of the application.
240    *
241    * @param value
242    *    The new value for this property.
243    *    <br>Can be <jk>null</jk> to unset the property.
244    * @return This object.
245    */
246   public Info setSiteName(String value) {
247      siteName = value;
248      return this;
249   }
250
251   /**
252    * Bean property getter:  <property>termsOfService</property>.
253    *
254    * <p>
255    * The Terms of Service for the API.
256    *
257    * @return The property value, or <jk>null</jk> if it is not set.
258    */
259   public String getTermsOfService() {
260      return termsOfService;
261   }
262
263   /**
264    * Bean property setter:  <property>termsOfService</property>.
265    *
266    * <p>
267    * The Terms of Service for the API.
268    *
269    * @param value
270    *    The new value for this property.
271    *    <br>Can be <jk>null</jk> to unset the property.
272    * @return This object.
273    */
274   public Info setTermsOfService(String value) {
275      termsOfService = value;
276      return this;
277   }
278
279   /**
280    * Bean property getter:  <property>title</property>.
281    *
282    * <p>
283    * The title of the application.
284    *
285    * @return The property value, or <jk>null</jk> if it is not set.
286    */
287   public String getTitle() {
288      return title;
289   }
290
291   /**
292    * Bean property setter:  <property>title</property>.
293    *
294    * <p>
295    * The title of the application.
296    *
297    * @param value
298    *    The new value for this property.
299    *    <br>Can be <jk>null</jk> to unset the property.
300    * @return This object.
301    */
302   public Info setTitle(String value) {
303      title = value;
304      return this;
305   }
306
307   /**
308    * Bean property getter:  <property>version</property>.
309    *
310    * <p>
311    * The version of the application API (not to be confused with the specification version).
312    *
313    * @return The property value, or <jk>null</jk> if it is not set.
314    */
315   public String getVersion() {
316      return version;
317   }
318
319   /**
320    * Bean property setter:  <property>version</property>.
321    *
322    * <p>
323    * The version of the application API (not to be confused with the specification version).
324    *
325    * @param value
326    *    The new value for this property.
327    *    <br>Property value is required.
328    *    <br>Can be <jk>null</jk> to unset the property.
329    * @return This object.
330    */
331   public Info setVersion(String value) {
332      version = value;
333      return this;
334   }
335
336   @Override /* Overridden from SwaggerElement */
337   public <T> T get(String property, Class<T> type) {
338      assertArgNotNull("property", property);
339      return switch (property) {
340         case "contact" -> toType(getContact(), type);
341         case "description" -> toType(getDescription(), type);
342         case "license" -> toType(getLicense(), type);
343         case "siteName" -> toType(getSiteName(), type);
344         case "termsOfService" -> toType(getTermsOfService(), type);
345         case "title" -> toType(getTitle(), type);
346         case "version" -> toType(getVersion(), type);
347         default -> super.get(property, type);
348      };
349   }
350
351   @Override /* Overridden from SwaggerElement */
352   public Info set(String property, Object value) {
353      assertArgNotNull("property", property);
354      return switch (property) {
355         case "contact" -> setContact(toType(value, Contact.class));
356         case "description" -> setDescription(Utils.s(value));
357         case "license" -> setLicense(toType(value, License.class));
358         case "siteName" -> setSiteName(Utils.s(value));
359         case "termsOfService" -> setTermsOfService(Utils.s(value));
360         case "title" -> setTitle(Utils.s(value));
361         case "version" -> setVersion(Utils.s(value));
362         default -> {
363            super.set(property, value);
364            yield this;
365         }
366      };
367   }
368
369   @Override /* Overridden from SwaggerElement */
370   public Set<String> keySet() {
371      var s = setBuilder(String.class)
372         .addIf(contact != null, "contact")
373         .addIf(description != null, "description")
374         .addIf(license != null, "license")
375         .addIf(siteName != null, "siteName")
376         .addIf(termsOfService != null, "termsOfService")
377         .addIf(title != null, "title")
378         .addIf(version != null, "version")
379         .build();
380      return new MultiSet<>(s, super.keySet());
381   }
382
383   /**
384    * Sets strict mode on this bean.
385    *
386    * @return This object.
387    */
388   @Override
389   public Info strict() {
390      super.strict();
391      return this;
392   }
393
394   /**
395    * Sets strict mode on this bean.
396    *
397    * @param value
398    *    The new value for this property.
399    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
400    *    <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>).
401    * @return This object.
402    */
403   @Override
404   public Info strict(Object value) {
405      super.strict(value);
406      return this;
407   }
408
409}