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.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 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 104 title, 105 description, 106 termsOfService, 107 version; 108 private Contact contact; 109 private License license; 110 111 /** 112 * Default constructor. 113 */ 114 public Info() {} 115 116 /** 117 * Copy constructor. 118 * 119 * @param copyFrom The object to copy. 120 */ 121 public Info(Info copyFrom) { 122 super(copyFrom); 123 124 this.title = copyFrom.title; 125 this.description = copyFrom.description; 126 this.termsOfService = copyFrom.termsOfService; 127 this.version = copyFrom.version; 128 this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy(); 129 this.license = copyFrom.license == null ? null : copyFrom.license.copy(); 130 } 131 132 /** 133 * Make a deep copy of this object. 134 * 135 * @return A deep copy of this object. 136 */ 137 public Info copy() { 138 return new Info(this); 139 } 140 141 /** 142 * Bean property getter: <property>title</property>. 143 * 144 * <p> 145 * The title of the application. 146 * 147 * @return The property value, or <jk>null</jk> if it is not set. 148 */ 149 public String getTitle() { 150 return title; 151 } 152 153 /** 154 * Bean property setter: <property>title</property>. 155 * 156 * <p> 157 * The title of the application. 158 * 159 * @param value 160 * The new value for this property. 161 * <br>Property value is required. 162 * <br>Can be <jk>null</jk> to unset the property. 163 * @return This object 164 */ 165 public Info setTitle(String value) { 166 title = value; 167 return this; 168 } 169 170 /** 171 * Bean property getter: <property>description</property>. 172 * 173 * <p> 174 * A short description of the application. 175 * 176 * @return The property value, or <jk>null</jk> if it is not set. 177 */ 178 public String getDescription() { 179 return description; 180 } 181 182 /** 183 * Bean property setter: <property>description</property>. 184 * 185 * <p> 186 * A short description of the application. 187 * 188 * @param value 189 * The new value for this property. 190 * <br>Can be <jk>null</jk> to unset the property. 191 * @return This object 192 */ 193 public Info setDescription(String value) { 194 description = value; 195 return this; 196 } 197 198 /** 199 * Bean property getter: <property>termsOfService</property>. 200 * 201 * <p> 202 * The Terms of Service for the API. 203 * 204 * @return The property value, or <jk>null</jk> if it is not set. 205 */ 206 public String getTermsOfService() { 207 return termsOfService; 208 } 209 210 /** 211 * Bean property setter: <property>termsOfService</property>. 212 * 213 * <p> 214 * The Terms of Service for the API. 215 * 216 * @param value 217 * The new value for this property. 218 * <br>Can be <jk>null</jk> to unset the property. 219 * @return This object 220 */ 221 public Info setTermsOfService(String value) { 222 termsOfService = value; 223 return this; 224 } 225 226 /** 227 * Bean property getter: <property>contact</property>. 228 * 229 * <p> 230 * The contact information for the exposed API. 231 * 232 * @return The property value, or <jk>null</jk> if it is not set. 233 */ 234 public Contact getContact() { 235 return contact; 236 } 237 238 /** 239 * Bean property setter: <property>contact</property>. 240 * 241 * <p> 242 * The contact information for the exposed API. 243 * 244 * @param value 245 * The new value for this property. 246 * <br>Can be <jk>null</jk> to unset the property. 247 * @return This object 248 */ 249 public Info setContact(Contact value) { 250 contact = value; 251 return this; 252 } 253 254 /** 255 * Bean property getter: <property>license</property>. 256 * 257 * <p> 258 * The license information for the exposed API. 259 * 260 * @return The property value, or <jk>null</jk> if it is not set. 261 */ 262 public License getLicense() { 263 return license; 264 } 265 266 /** 267 * Bean property setter: <property>license</property>. 268 * 269 * <p> 270 * The license information for the exposed API. 271 * 272 * @param value 273 * The new value for this property. 274 * <br>Can be <jk>null</jk> to unset the property. 275 * @return This object 276 */ 277 public Info setLicense(License value) { 278 license = value; 279 return this; 280 } 281 282 /** 283 * Bean property getter: <property>version</property>. 284 * 285 * <p> 286 * Provides the version of the application API (not to be confused with the specification version). 287 * 288 * @return The property value, or <jk>null</jk> if it is not set. 289 */ 290 public String getVersion() { 291 return version; 292 } 293 294 /** 295 * Bean property setter: <property>version</property>. 296 * 297 * <p> 298 * Provides the version of the application API (not to be confused with the specification version). 299 * 300 * @param value 301 * The new value for this property. 302 * <br>Property value is required. 303 * <br>Can be <jk>null</jk> to unset the property. 304 * @return This object 305 */ 306 public Info setVersion(String value) { 307 version = value; 308 return this; 309 } 310 311 @Override /* Overridden from OpenApiElement */ 312 public <T> T get(String property, Class<T> type) { 313 assertArgNotNull("property", property); 314 return switch (property) { 315 case "title" -> toType(getTitle(), type); 316 case "description" -> toType(getDescription(), type); 317 case "termsOfService" -> toType(getTermsOfService(), type); 318 case "contact" -> toType(getContact(), type); 319 case "license" -> toType(getLicense(), type); 320 case "version" -> toType(getVersion(), type); 321 default -> super.get(property, type); 322 }; 323 } 324 325 @Override /* Overridden from OpenApiElement */ 326 public Info set(String property, Object value) { 327 assertArgNotNull("property", property); 328 return switch (property) { 329 case "contact" -> setContact(toType(value, Contact.class)); 330 case "description" -> setDescription(Utils.s(value)); 331 case "license" -> setLicense(toType(value, License.class)); 332 case "termsOfService" -> setTermsOfService(Utils.s(value)); 333 case "title" -> setTitle(Utils.s(value)); 334 case "version" -> setVersion(Utils.s(value)); 335 default -> { 336 super.set(property, value); 337 yield this; 338 } 339 }; 340 } 341 342 @Override /* Overridden from OpenApiElement */ 343 public Set<String> keySet() { 344 var s = setBuilder(String.class) 345 .addIf(contact != null, "contact") 346 .addIf(description != null, "description") 347 .addIf(license != null, "license") 348 .addIf(termsOfService != null, "termsOfService") 349 .addIf(title != null, "title") 350 .addIf(version != null, "version") 351 .build(); 352 return new MultiSet<>(s, super.keySet()); 353 } 354 355 @Override /* Overridden from OpenApiElement */ 356 public Info strict() { 357 super.strict(); 358 return this; 359 } 360 361 @Override /* Overridden from OpenApiElement */ 362 public Info strict(Object value) { 363 super.strict(value); 364 return this; 365 } 366 367}