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.common.utils.Utils.*;
020import static org.apache.juneau.internal.CollectionUtils.*;
021import static org.apache.juneau.internal.ConverterUtils.*;
022
023import java.net.*;
024import java.util.*;
025
026import org.apache.juneau.*;
027import org.apache.juneau.common.utils.*;
028import org.apache.juneau.internal.*;
029
030/**
031 * Allows referencing an external resource for extended documentation.
032 *
033 * <p>
034 * The External Documentation Object allows referencing an external resource for extended documentation in Swagger 2.0. 
035 * This can be used to provide additional documentation that is not part of the main Swagger specification, such as 
036 * detailed guides, tutorials, or API documentation hosted elsewhere.
037 *
038 * <h5 class='section'>Swagger Specification:</h5>
039 * <p>
040 * The External Documentation Object is composed of the following fields:
041 * <ul class='spaced-list'>
042 *    <li><c>description</c> (string) - A short description of the target documentation
043 *    <li><c>url</c> (string, REQUIRED) - The URL for the target documentation
044 * </ul>
045 *
046 * <h5 class='section'>Example:</h5>
047 * <p class='bjava'>
048 *    <jc>// Construct using SwaggerBuilder.</jc>
049 *    ExternalDocumentation <jv>extDoc</jv> = <jsm>externalDocumentation</jsm>(<js>"https://swagger.io"</js>, <js>"Find more info here"</js>);
050 *
051 *    <jc>// Serialize using JsonSerializer.</jc>
052 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>extDoc</jv>);
053 *
054 *    <jc>// Or just use toString() which does the same as above.</jc>
055 *    <jv>json</jv> = <jv>extDoc</jv>.toString();
056 * </p>
057 * <p class='bjson'>
058 *    <jc>// Output</jc>
059 *    {
060 *       <js>"description"</js>: <js>"Find more info here"</js>,
061 *       <js>"url"</js>: <js>"https://swagger.io"</js>
062 *    }
063 * </p>
064 *
065 * <h5 class='section'>See Also:</h5><ul>
066 *    <li class='link'><a class="doclink" href="https://swagger.io/specification/v2/#external-documentation-object">Swagger 2.0 Specification &gt; External Documentation Object</a>
067 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/2-0/external-documentation/">Swagger External Documentation</a>
068 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a>
069 * </ul>
070 */
071public class ExternalDocumentation extends SwaggerElement {
072
073   private String description;
074   private URI url;
075
076   /**
077    * Default constructor.
078    */
079   public ExternalDocumentation() {}
080
081   /**
082    * Copy constructor.
083    *
084    * @param copyFrom The object to copy.
085    */
086   public ExternalDocumentation(ExternalDocumentation copyFrom) {
087      super(copyFrom);
088
089      this.description = copyFrom.description;
090      this.url = copyFrom.url;
091   }
092
093   /**
094    * Make a deep copy of this object.
095    *
096    * @return A deep copy of this object.
097    */
098   public ExternalDocumentation copy() {
099      return new ExternalDocumentation(this);
100   }
101
102   //-----------------------------------------------------------------------------------------------------------------
103   // Properties
104   //-----------------------------------------------------------------------------------------------------------------
105
106   /**
107    * Bean property getter:  <property>description</property>.
108    *
109    * <p>
110    * A short description of the target documentation.
111    *
112    * @return The property value, or <jk>null</jk> if it is not set.
113    */
114   public String getDescription() {
115      return description;
116   }
117
118   /**
119    * Bean property setter:  <property>description</property>.
120    *
121    * <p>
122    * A short description of the target documentation.
123    *
124    * @param value
125    *    The new value for this property.
126    *    <br><a class="doclink" href="https://help.github.com/articles/github-flavored-markdown">GFM syntax</a> can be used for rich text representation.
127    *    <br>Can be <jk>null</jk> to unset the property.
128    * @return This object.
129    */
130   public ExternalDocumentation setDescription(String value) {
131      description = value;
132      return this;
133   }
134
135   /**
136    * Bean property getter:  <property>url</property>.
137    *
138    * <p>
139    * The URL for the target documentation.
140    *
141    * @return The property value, or <jk>null</jk> if it is not set.
142    */
143   public URI getUrl() {
144      return url;
145   }
146
147   /**
148    * Bean property setter:  <property>url</property>.
149    *
150    * <p>
151    * The URL for the target documentation.
152    *
153    * @param value
154    *    The new value for this property.
155    *    <br>Property value is required.
156    *    <br>URIs defined by {@link UriResolver} can be used for values.
157    *    <br>Can be <jk>null</jk> to unset the property.
158    * @return This object.
159    */
160   public ExternalDocumentation setUrl(URI value) {
161      url = value;
162      return this;
163   }
164
165   @Override /* Overridden from SwaggerElement */
166   public <T> T get(String property, Class<T> type) {
167      assertArgNotNull("property", property);
168      return switch (property) {
169         case "description" -> toType(getDescription(), type);
170         case "url" -> toType(getUrl(), type);
171         default -> super.get(property, type);
172      };
173   }
174
175   @Override /* Overridden from SwaggerElement */
176   public ExternalDocumentation set(String property, Object value) {
177      assertArgNotNull("property", property);
178      return switch (property) {
179         case "description" -> setDescription(Utils.s(value));
180         case "url" -> setUrl(StringUtils.toURI(value));
181         default -> {
182            super.set(property, value);
183            yield this;
184         }
185      };
186   }
187
188   @Override /* Overridden from SwaggerElement */
189   public Set<String> keySet() {
190      var s = setBuilder(String.class)
191         .addIf(description != null, "description")
192         .addIf(url != null, "url")
193         .build();
194      return new MultiSet<>(s, super.keySet());
195   }
196
197   /**
198    * Sets strict mode on this bean.
199    *
200    * @return This object.
201    */
202   @Override
203   public ExternalDocumentation strict() {
204      super.strict();
205      return this;
206   }
207
208   /**
209    * Sets strict mode on this bean.
210    *
211    * @param value
212    *    The new value for this property.
213    *    <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>.
214    *    <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>).
215    * @return This object.
216    */
217   @Override
218   public ExternalDocumentation strict(Object value) {
219      super.strict(value);
220      return this;
221   }
222
223}