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