View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.bean.openapi3;
18  
19  import static org.apache.juneau.commons.utils.AssertionUtils.*;
20  import static org.apache.juneau.commons.utils.CollectionUtils.*;
21  import static org.apache.juneau.commons.utils.Utils.*;
22  import static org.apache.juneau.internal.ConverterUtils.*;
23  
24  import java.util.*;
25  
26  import org.apache.juneau.commons.collections.*;
27  
28  /**
29   * Provides metadata about the API.
30   *
31   * <p>
32   * The Info Object contains required and optional metadata about the API, including the title, version, description,
33   * terms of service, contact information, and license. This metadata can be used by client tooling and is typically
34   * displayed in API documentation interfaces.
35   *
36   * <h5 class='section'>OpenAPI Specification:</h5>
37   * <p>
38   * The Info Object is composed of the following fields:
39   * <ul class='spaced-list'>
40   * 	<li><c>title</c> (string, REQUIRED) - The title of the API
41   * 	<li><c>version</c> (string, REQUIRED) - The version of the OpenAPI document (not the API itself)
42   * 	<li><c>description</c> (string) - A short description of the API (CommonMark syntax may be used)
43   * 	<li><c>termsOfService</c> (string) - A URL to the Terms of Service for the API
44   * 	<li><c>contact</c> ({@link Contact}) - Contact information for the exposed API
45   * 	<li><c>license</c> ({@link License}) - License information for the exposed API
46   * </ul>
47   *
48   * <h5 class='section'>Example:</h5>
49   * <p class='bjava'>
50   * 	<jc>// Create an Info object</jc>
51   * 	Info <jv>info</jv> = <jk>new</jk> Info()
52   * 		.setTitle(<js>"Pet Store API"</js>)
53   * 		.setVersion(<js>"1.0.0"</js>)
54   * 		.setDescription(<js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>)
55   * 		.setTermsOfService(<js>"http://example.com/terms/"</js>)
56   * 		.setContact(
57   * 			<jk>new</jk> Contact()
58   * 				.setName(<js>"API Support"</js>)
59   * 				.setUrl(URI.<jsm>create</jsm>(<js>"http://www.example.com/support"</js>))
60   * 				.setEmail(<js>"support@example.com"</js>)
61   * 		)
62   * 		.setLicense(
63   * 			<jk>new</jk> License()
64   * 				.setName(<js>"Apache 2.0"</js>)
65   * 				.setUrl(URI.<jsm>create</jsm>(<js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>))
66   * 		);
67   * </p>
68   * <p class='bjava'>
69   * 	<jc>// Serialize to JSON</jc>
70   * 	String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>info</jv>);
71   *
72   * 	<jc>// Or just use toString() which does the same as above.</jc>
73   * 	<jv>json</jv> = <jv>info</jv>.toString();
74   * </p>
75   * <p class='bcode'>
76   * 	<jc>// Output</jc>
77   * 	{
78   * 		<js>"title"</js>: <js>"Pet Store API"</js>,
79   * 		<js>"version"</js>: <js>"1.0.0"</js>,
80   * 		<js>"description"</js>: <js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>,
81   * 		<js>"termsOfService"</js>: <js>"http://example.com/terms/"</js>,
82   * 		<js>"contact"</js>: {
83   * 			<js>"name"</js>: <js>"API Support"</js>,
84   * 			<js>"url"</js>: <js>"http://www.example.com/support"</js>,
85   * 			<js>"email"</js>: <js>"support@example.com"</js>
86   * 		},
87   * 		<js>"license"</js>: {
88   * 			<js>"name"</js>: <js>"Apache 2.0"</js>,
89   * 			<js>"url"</js>: <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>
90   * 		},
91   * 		<js>"version"</js>: <js>"1.0.1"</js>
92   * 	}
93   * </p>
94   *
95   * <h5 class='section'>See Also:</h5><ul>
96   * 	<li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#info-object">OpenAPI Specification &gt; Info Object</a>
97   * 	<li class='link'><a class="doclink" href="https://swagger.io/docs/specification/api-general-info/">OpenAPI API General Info</a>
98   * 	<li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
99   * </ul>
100  */
101 public class Info extends OpenApiElement {
102 
103 	private String title, description, termsOfService, version;
104 	private Contact contact;
105 	private License license;
106 
107 	/**
108 	 * Default constructor.
109 	 */
110 	public Info() {}
111 
112 	/**
113 	 * Copy constructor.
114 	 *
115 	 * @param copyFrom The object to copy.
116 	 */
117 	public Info(Info copyFrom) {
118 		super(copyFrom);
119 
120 		this.title = copyFrom.title;
121 		this.description = copyFrom.description;
122 		this.termsOfService = copyFrom.termsOfService;
123 		this.version = copyFrom.version;
124 		this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
125 		this.license = copyFrom.license == null ? null : copyFrom.license.copy();
126 	}
127 
128 	/**
129 	 * Make a deep copy of this object.
130 	 *
131 	 * @return A deep copy of this object.
132 	 */
133 	public Info copy() {
134 		return new Info(this);
135 	}
136 
137 	@Override /* Overridden from OpenApiElement */
138 	public <T> T get(String property, Class<T> type) {
139 		assertArgNotNull("property", property);
140 		return switch (property) {
141 			case "title" -> toType(getTitle(), type);
142 			case "description" -> toType(getDescription(), type);
143 			case "termsOfService" -> toType(getTermsOfService(), type);
144 			case "contact" -> toType(getContact(), type);
145 			case "license" -> toType(getLicense(), type);
146 			case "version" -> toType(getVersion(), type);
147 			default -> super.get(property, type);
148 		};
149 	}
150 
151 	/**
152 	 * Bean property getter:  <property>contact</property>.
153 	 *
154 	 * <p>
155 	 * The contact information for the exposed API.
156 	 *
157 	 * @return The property value, or <jk>null</jk> if it is not set.
158 	 */
159 	public Contact getContact() { return contact; }
160 
161 	/**
162 	 * Bean property getter:  <property>description</property>.
163 	 *
164 	 * <p>
165 	 * A short description of the application.
166 	 *
167 	 * @return The property value, or <jk>null</jk> if it is not set.
168 	 */
169 	public String getDescription() { return description; }
170 
171 	/**
172 	 * Bean property getter:  <property>license</property>.
173 	 *
174 	 * <p>
175 	 * The license information for the exposed API.
176 	 *
177 	 * @return The property value, or <jk>null</jk> if it is not set.
178 	 */
179 	public License getLicense() { return license; }
180 
181 	/**
182 	 * Bean property getter:  <property>termsOfService</property>.
183 	 *
184 	 * <p>
185 	 * The Terms of Service for the API.
186 	 *
187 	 * @return The property value, or <jk>null</jk> if it is not set.
188 	 */
189 	public String getTermsOfService() { return termsOfService; }
190 
191 	/**
192 	 * Bean property getter:  <property>title</property>.
193 	 *
194 	 * <p>
195 	 * The title of the application.
196 	 *
197 	 * @return The property value, or <jk>null</jk> if it is not set.
198 	 */
199 	public String getTitle() { return title; }
200 
201 	/**
202 	 * Bean property getter:  <property>version</property>.
203 	 *
204 	 * <p>
205 	 * Provides the version of the application API (not to be confused with the specification version).
206 	 *
207 	 * @return The property value, or <jk>null</jk> if it is not set.
208 	 */
209 	public String getVersion() { return version; }
210 
211 	@Override /* Overridden from OpenApiElement */
212 	public Set<String> keySet() {
213 		// @formatter:off
214 		var s = setb(String.class)
215 			.addIf(nn(contact), "contact")
216 			.addIf(nn(description), "description")
217 			.addIf(nn(license), "license")
218 			.addIf(nn(termsOfService), "termsOfService")
219 			.addIf(nn(title), "title")
220 			.addIf(nn(version), "version")
221 			.build();
222 		// @formatter:on
223 		return new MultiSet<>(s, super.keySet());
224 	}
225 
226 	@Override /* Overridden from OpenApiElement */
227 	public Info set(String property, Object value) {
228 		assertArgNotNull("property", property);
229 		return switch (property) {
230 			case "contact" -> setContact(toType(value, Contact.class));
231 			case "description" -> setDescription(s(value));
232 			case "license" -> setLicense(toType(value, License.class));
233 			case "termsOfService" -> setTermsOfService(s(value));
234 			case "title" -> setTitle(s(value));
235 			case "version" -> setVersion(s(value));
236 			default -> {
237 				super.set(property, value);
238 				yield this;
239 			}
240 		};
241 	}
242 
243 	/**
244 	 * Bean property setter:  <property>contact</property>.
245 	 *
246 	 * <p>
247 	 * The contact information for the exposed API.
248 	 *
249 	 * @param value
250 	 * 	The new value for this property.
251 	 * 	<br>Can be <jk>null</jk> to unset the property.
252 	 * @return This object
253 	 */
254 	public Info setContact(Contact value) {
255 		contact = value;
256 		return this;
257 	}
258 
259 	/**
260 	 * Bean property setter:  <property>description</property>.
261 	 *
262 	 * <p>
263 	 * A short description of the application.
264 	 *
265 	 * @param value
266 	 * 	The new value for this property.
267 	 * 	<br>Can be <jk>null</jk> to unset the property.
268 	 * @return This object
269 	 */
270 	public Info setDescription(String value) {
271 		description = value;
272 		return this;
273 	}
274 
275 	/**
276 	 * Bean property setter:  <property>license</property>.
277 	 *
278 	 * <p>
279 	 * The license information for the exposed API.
280 	 *
281 	 * @param value
282 	 * 	The new value for this property.
283 	 * 	<br>Can be <jk>null</jk> to unset the property.
284 	 * @return This object
285 	 */
286 	public Info setLicense(License value) {
287 		license = value;
288 		return this;
289 	}
290 
291 	/**
292 	 * Bean property setter:  <property>termsOfService</property>.
293 	 *
294 	 * <p>
295 	 * The Terms of Service for the API.
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 setTermsOfService(String value) {
303 		termsOfService = value;
304 		return this;
305 	}
306 
307 	/**
308 	 * Bean property setter:  <property>title</property>.
309 	 *
310 	 * <p>
311 	 * The title of the application.
312 	 *
313 	 * @param value
314 	 * 	The new value for this property.
315 	 * 	<br>Property value is required.
316 	 * 	<br>Can be <jk>null</jk> to unset the property.
317 	 * @return This object
318 	 */
319 	public Info setTitle(String value) {
320 		title = value;
321 		return this;
322 	}
323 
324 	/**
325 	 * Bean property setter:  <property>version</property>.
326 	 *
327 	 * <p>
328 	 * Provides the version of the application API (not to be confused with the specification version).
329 	 *
330 	 * @param value
331 	 * 	The new value for this property.
332 	 * 	<br>Property value is required.
333 	 * 	<br>Can be <jk>null</jk> to unset the property.
334 	 * @return This object
335 	 */
336 	public Info setVersion(String value) {
337 		version = value;
338 		return this;
339 	}
340 
341 	@Override /* Overridden from OpenApiElement */
342 	public Info strict() {
343 		super.strict();
344 		return this;
345 	}
346 
347 	@Override /* Overridden from OpenApiElement */
348 	public Info strict(Object value) {
349 		super.strict(value);
350 		return this;
351 	}
352 }