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.openapi3; 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 contains required and optional metadata about the API, including the title, version, description, 033 * terms of service, contact information, and license. This metadata can be used by client tooling and is typically 034 * displayed in API documentation interfaces. 035 * 036 * <h5 class='section'>OpenAPI 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 (CommonMark syntax may be used) 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>// Create an Info object</jc> 051 * Info <jv>info</jv> = <jk>new</jk> Info() 052 * .setTitle(<js>"Pet Store API"</js>) 053 * .setVersion(<js>"1.0.0"</js>) 054 * .setDescription(<js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>) 055 * .setTermsOfService(<js>"http://example.com/terms/"</js>) 056 * .setContact( 057 * <jk>new</jk> Contact() 058 * .setName(<js>"API Support"</js>) 059 * .setUrl(URI.<jsm>create</jsm>(<js>"http://www.example.com/support"</js>)) 060 * .setEmail(<js>"support@example.com"</js>) 061 * ) 062 * .setLicense( 063 * <jk>new</jk> License() 064 * .setName(<js>"Apache 2.0"</js>) 065 * .setUrl(URI.<jsm>create</jsm>(<js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>)) 066 * ); 067 * </p> 068 * <p class='bjava'> 069 * <jc>// Serialize to JSON</jc> 070 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>info</jv>); 071 * 072 * <jc>// Or just use toString() which does the same as above.</jc> 073 * <jv>json</jv> = <jv>info</jv>.toString(); 074 * </p> 075 * <p class='bcode'> 076 * <jc>// Output</jc> 077 * { 078 * <js>"title"</js>: <js>"Pet Store API"</js>, 079 * <js>"version"</js>: <js>"1.0.0"</js>, 080 * <js>"description"</js>: <js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>, 081 * <js>"termsOfService"</js>: <js>"http://example.com/terms/"</js>, 082 * <js>"contact"</js>: { 083 * <js>"name"</js>: <js>"API Support"</js>, 084 * <js>"url"</js>: <js>"http://www.example.com/support"</js>, 085 * <js>"email"</js>: <js>"support@example.com"</js> 086 * }, 087 * <js>"license"</js>: { 088 * <js>"name"</js>: <js>"Apache 2.0"</js>, 089 * <js>"url"</js>: <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js> 090 * }, 091 * <js>"version"</js>: <js>"1.0.1"</js> 092 * } 093 * </p> 094 * 095 * <h5 class='section'>See Also:</h5><ul> 096 * <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#info-object">OpenAPI Specification > Info Object</a> 097 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/api-general-info/">OpenAPI API General Info</a> 098 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a> 099 * </ul> 100 */ 101public 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}