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