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.StringUtils.*;
020import static org.apache.juneau.common.utils.Utils.*;
021import static org.apache.juneau.internal.CollectionUtils.*;
022import static org.apache.juneau.internal.ConverterUtils.*;
023
024import java.net.*;
025import java.util.*;
026
027import org.apache.juneau.*;
028import org.apache.juneau.common.utils.*;
029import org.apache.juneau.internal.*;
030
031/**
032 * Allows referencing an external resource for extended documentation.
033 *
034 * <p>
035 * The External Documentation Object allows referencing an external resource for extended documentation. This can be 
036 * used to provide additional documentation that is not part of the main OpenAPI specification, such as detailed 
037 * guides, tutorials, or API documentation hosted elsewhere.
038 *
039 * <h5 class='section'>OpenAPI Specification:</h5>
040 * <p>
041 * The External Documentation Object is composed of the following fields:
042 * <ul class='spaced-list'>
043 *    <li><c>description</c> (string) - A short description of the target documentation (CommonMark syntax may be used)
044 *    <li><c>url</c> (string, REQUIRED) - The URL for the target documentation
045 * </ul>
046 *
047 * <h5 class='section'>Example:</h5>
048 * <p class='bjava'>
049 *    <jc>// Create external documentation reference</jc>
050 *    ExternalDocumentation <jv>docs</jv> = <jk>new</jk> ExternalDocumentation()
051 *       .setDescription(<js>"Find more info here"</js>)
052 *       .setUrl(<js>"https://example.com"</js>);
053 * </p>
054 *
055 * <h5 class='section'>See Also:</h5><ul>
056 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#external-documentation-object">OpenAPI Specification &gt; External Documentation Object</a>
057 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/external-documentation/">OpenAPI External Documentation</a>
058 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
059 * </ul>
060 */
061public class ExternalDocumentation extends OpenApiElement {
062
063   private String description;
064   private URI url;
065
066   /**
067    * Default constructor.
068    */
069   public ExternalDocumentation() {}
070
071   /**
072    * Copy constructor.
073    *
074    * @param copyFrom The object to copy.
075    */
076   public ExternalDocumentation(ExternalDocumentation copyFrom) {
077      super(copyFrom);
078
079      this.description = copyFrom.description;
080      this.url = copyFrom.url;
081   }
082
083   /**
084    * Make a deep copy of this object.
085    *
086    * @return A deep copy of this object.
087    */
088   public ExternalDocumentation copy() {
089      return new ExternalDocumentation(this);
090   }
091
092   /**
093    * Bean property getter:  <property>description</property>.
094    *
095    * <p>
096    * A short description of the target documentation.
097    *
098    * @return The property value, or <jk>null</jk> if it is not set.
099    */
100   public String getDescription() {
101      return description;
102   }
103
104   /**
105    * Bean property setter:  <property>description</property>.
106    *
107    * <p>
108    * A short description of the target documentation.
109    *
110    * @param value
111    *    The new value for this property.
112    *    <br>Can be <jk>null</jk> to unset the property.
113    * @return This object
114    */
115   public ExternalDocumentation setDescription(String value) {
116      description = value;
117      return this;
118   }
119
120   /**
121    * Bean property getter:  <property>url</property>.
122    *
123    * <p>
124    * The URL for the target documentation.
125    *
126    * @return The property value, or <jk>null</jk> if it is not set.
127    */
128   public URI getUrl() {
129      return url;
130   }
131
132   /**
133    * Bean property setter:  <property>url</property>.
134    *
135    * <p>
136    * The URL for the target documentation.
137    *
138    * @param value
139    *    The new value for this property.
140    *    <br>Property value is required.
141    *    <br>URIs defined by {@link UriResolver} can be used for values.
142    *    <br>Can be <jk>null</jk> to unset the property.
143    * @return This object
144    */
145   public ExternalDocumentation setUrl(URI value) {
146      url = value;
147      return this;
148   }
149
150   @Override /* Overridden from OpenApiElement */
151   public <T> T get(String property, Class<T> type) {
152      assertArgNotNull("property", property);
153      return switch (property) {
154         case "description" -> toType(getDescription(), type);
155         case "url" -> toType(getUrl(), type);
156         default -> super.get(property, type);
157      };
158   }
159
160   @Override /* Overridden from OpenApiElement */
161   public ExternalDocumentation set(String property, Object value) {
162      assertArgNotNull("property", property);
163      return switch (property) {
164         case "description" -> setDescription(Utils.s(value));
165         case "url" -> setUrl(toURI(value));
166         default -> {
167            super.set(property, value);
168            yield this;
169         }
170      };
171   }
172
173   @Override /* Overridden from OpenApiElement */
174   public Set<String> keySet() {
175      var s = setBuilder(String.class)
176         .addIf(description != null, "description")
177         .addIf(url != null, "url")
178         .build();
179      return new MultiSet<>(s, super.keySet());
180   }
181
182   @Override /* Overridden from OpenApiElement */
183   public ExternalDocumentation strict() {
184      super.strict();
185      return this;
186   }
187
188   @Override /* Overridden from OpenApiElement */
189   public ExternalDocumentation strict(Object value) {
190      super.strict(value);
191      return this;
192   }
193
194}