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.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.CollectionUtils.*;
021import static org.apache.juneau.commons.utils.Utils.*;
022import static org.apache.juneau.internal.ConverterUtils.*;
023
024import java.util.*;
025
026import org.apache.juneau.commons.collections.*;
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 siteName, title, description, termsOfService, version;
095   private Contact contact;
096   private License license;
097
098   /**
099    * Default constructor.
100    */
101   public Info() {}
102
103   /**
104    * Copy constructor.
105    *
106    * @param copyFrom The object to copy.
107    */
108   public Info(Info copyFrom) {
109      super(copyFrom);
110
111      this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
112      this.description = copyFrom.description;
113      this.license = copyFrom.license == null ? null : copyFrom.license.copy();
114      this.siteName = copyFrom.siteName;
115      this.termsOfService = copyFrom.termsOfService;
116      this.title = copyFrom.title;
117      this.version = copyFrom.version;
118   }
119
120   /**
121    * Make a deep copy of this object.
122    *
123    * @return A deep copy of this object.
124    */
125   public Info copy() {
126      return new Info(this);
127   }
128
129   @Override /* Overridden from SwaggerElement */
130   public <T> T get(String property, Class<T> type) {
131      assertArgNotNull("property", property);
132      return switch (property) {
133         case "contact" -> toType(getContact(), type);
134         case "description" -> toType(getDescription(), type);
135         case "license" -> toType(getLicense(), type);
136         case "siteName" -> toType(getSiteName(), type);
137         case "termsOfService" -> toType(getTermsOfService(), type);
138         case "title" -> toType(getTitle(), type);
139         case "version" -> toType(getVersion(), type);
140         default -> super.get(property, type);
141      };
142   }
143
144   /**
145    * Bean property getter:  <property>contact</property>.
146    *
147    * <p>
148    * The contact information for the exposed API.
149    *
150    * @return The property value, or <jk>null</jk> if it is not set.
151    */
152   public Contact getContact() { return contact; }
153
154   /**
155    * Bean property getter:  <property>description</property>.
156    *
157    * <p>
158    * A short description of the application.
159    *
160    * @return The property value, or <jk>null</jk> if it is not set.
161    */
162   public String getDescription() { return description; }
163
164   /**
165    * Bean property getter:  <property>license</property>.
166    *
167    * <p>
168    * The license information for the exposed API.
169    *
170    * @return The property value, or <jk>null</jk> if it is not set.
171    */
172   public License getLicense() { return license; }
173
174   /**
175    * Bean property getter:  <property>siteName</property>.
176    *
177    * <p>
178    * The site name of the application.
179    *
180    * @return The property value, or <jk>null</jk> if it is not set.
181    */
182   public String getSiteName() { return siteName; }
183
184   /**
185    * Bean property getter:  <property>termsOfService</property>.
186    *
187    * <p>
188    * The Terms of Service for the API.
189    *
190    * @return The property value, or <jk>null</jk> if it is not set.
191    */
192   public String getTermsOfService() { return termsOfService; }
193
194   /**
195    * Bean property getter:  <property>title</property>.
196    *
197    * <p>
198    * The title of the application.
199    *
200    * @return The property value, or <jk>null</jk> if it is not set.
201    */
202   public String getTitle() { return title; }
203
204   /**
205    * Bean property getter:  <property>version</property>.
206    *
207    * <p>
208    * The version of the application API (not to be confused with the specification version).
209    *
210    * @return The property value, or <jk>null</jk> if it is not set.
211    */
212   public String getVersion() { return version; }
213
214   @Override /* Overridden from SwaggerElement */
215   public Set<String> keySet() {
216      // @formatter:off
217      var s = setb(String.class)
218         .addIf(nn(contact), "contact")
219         .addIf(nn(description), "description")
220         .addIf(nn(license), "license")
221         .addIf(nn(siteName), "siteName")
222         .addIf(nn(termsOfService), "termsOfService")
223         .addIf(nn(title), "title")
224         .addIf(nn(version), "version")
225         .build();
226      // @formatter:on
227      return new MultiSet<>(s, super.keySet());
228   }
229
230   @Override /* Overridden from SwaggerElement */
231   public Info set(String property, Object value) {
232      assertArgNotNull("property", property);
233      return switch (property) {
234         case "contact" -> setContact(toType(value, Contact.class));
235         case "description" -> setDescription(s(value));
236         case "license" -> setLicense(toType(value, License.class));
237         case "siteName" -> setSiteName(s(value));
238         case "termsOfService" -> setTermsOfService(s(value));
239         case "title" -> setTitle(s(value));
240         case "version" -> setVersion(s(value));
241         default -> {
242            super.set(property, value);
243            yield this;
244         }
245      };
246   }
247
248   /**
249    * Bean property setter:  <property>contact</property>.
250    *
251    * <p>
252    * The contact information for the exposed API.
253    *
254    * @param value
255    *    The new value for this property.
256    *    <br>Can be <jk>null</jk> to unset the property.
257    * @return This object.
258    */
259   public Info setContact(Contact value) {
260      contact = value;
261      return this;
262   }
263
264   /**
265    * Bean property setter:  <property>description</property>.
266    *
267    * <p>
268    * A short description of the application.
269    *
270    * @param value
271    *    The new value for this property.
272    *    <br><a class="doclink" href="https://help.github.com/articles/github-flavored-markdown">GFM syntax</a> can be used for rich text representation.
273    *    <br>Can be <jk>null</jk> to unset the property.
274    * @return This object.
275    */
276   public Info setDescription(String value) {
277      description = value;
278      return this;
279   }
280
281   /**
282    * Bean property setter:  <property>license</property>.
283    *
284    * <p>
285    * The license information for the exposed API.
286    *
287    * @param value
288    *    The new value for this property.
289    *    <br>Can be <jk>null</jk> to unset the property.
290    * @return This object.
291    */
292   public Info setLicense(License value) {
293      license = value;
294      return this;
295   }
296
297   /**
298    * Bean property setter:  <property>siteName</property>.
299    *
300    * <p>
301    * The site name of the application.
302    *
303    * @param value
304    *    The new value for this property.
305    *    <br>Can be <jk>null</jk> to unset the property.
306    * @return This object.
307    */
308   public Info setSiteName(String value) {
309      siteName = value;
310      return this;
311   }
312
313   /**
314    * Bean property setter:  <property>termsOfService</property>.
315    *
316    * <p>
317    * The Terms of Service for the API.
318    *
319    * @param value
320    *    The new value for this property.
321    *    <br>Can be <jk>null</jk> to unset the property.
322    * @return This object.
323    */
324   public Info setTermsOfService(String value) {
325      termsOfService = value;
326      return this;
327   }
328
329   /**
330    * Bean property setter:  <property>title</property>.
331    *
332    * <p>
333    * The title of the application.
334    *
335    * @param value
336    *    The new value for this property.
337    *    <br>Can be <jk>null</jk> to unset the property.
338    * @return This object.
339    */
340   public Info setTitle(String value) {
341      title = value;
342      return this;
343   }
344
345   /**
346    * Bean property setter:  <property>version</property>.
347    *
348    * <p>
349    * The version of the application API (not to be confused with the specification version).
350    *
351    * @param value
352    *    The new value for this property.
353    *    <br>Property value is required.
354    *    <br>Can be <jk>null</jk> to unset the property.
355    * @return This object.
356    */
357   public Info setVersion(String value) {
358      version = value;
359      return this;
360   }
361
362   /**
363    * Sets strict mode on this bean.
364    *
365    * @return This object.
366    */
367   @Override
368   public Info strict() {
369      super.strict();
370      return this;
371   }
372
373   /**
374    * Sets strict mode on this bean.
375    *
376    * @param value
377    *    The new value for this property.
378    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
379    *    <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>).
380    * @return This object.
381    */
382   @Override
383   public Info strict(Object value) {
384      super.strict(value);
385      return this;
386   }
387}