001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.dto.swagger;
014
015import static org.apache.juneau.internal.StringUtils.*;
016import static org.apache.juneau.internal.ConverterUtils.*;
017
018import java.net.*;
019import java.net.URI;
020import java.util.*;
021
022import org.apache.juneau.*;
023import org.apache.juneau.annotation.*;
024import org.apache.juneau.collections.*;
025import org.apache.juneau.internal.*;
026
027/**
028 * Allows referencing an external resource for extended documentation.
029 *
030 * <h5 class='section'>Example:</h5>
031 * <p class='bcode w800'>
032 *    <jc>// Construct using SwaggerBuilder.</jc>
033 *    ExternalDocumentation x = <jsm>externalDocumentation</jsm>(<js>"https://swagger.io"</js>, <js>"Find more info here"</js>);
034 *
035 *    <jc>// Serialize using JsonSerializer.</jc>
036 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
037 *
038 *    <jc>// Or just use toString() which does the same as above.</jc>
039 *    String json = x.toString();
040 * </p>
041 * <p class='bcode w800'>
042 *    <jc>// Output</jc>
043 *    {
044 *       <js>"description"</js>: <js>"Find more info here"</js>,
045 *       <js>"url"</js>: <js>"https://swagger.io"</js>
046 *    }
047 * </p>
048 *
049 * <ul class='seealso'>
050 *    <li class='link'>{@doc DtoSwagger}
051 * </ul>
052 */
053@Bean(bpi="description,url,*")
054public class ExternalDocumentation extends SwaggerElement {
055
056   private String description;
057   private URI url;
058
059   /**
060    * Default constructor.
061    */
062   public ExternalDocumentation() {}
063
064   /**
065    * Copy constructor.
066    *
067    * @param copyFrom The object to copy.
068    */
069   public ExternalDocumentation(ExternalDocumentation copyFrom) {
070      super(copyFrom);
071
072      this.description = copyFrom.description;
073      this.url = copyFrom.url;
074   }
075
076   /**
077    * Make a deep copy of this object.
078    *
079    * @return A deep copy of this object.
080    */
081   public ExternalDocumentation copy() {
082      return new ExternalDocumentation(this);
083   }
084
085   /**
086    * Bean property getter:  <property>description</property>.
087    *
088    * <p>
089    * A short description of the target documentation.
090    *
091    * @return The property value, or <jk>null</jk> if it is not set.
092    */
093   public String getDescription() {
094      return description;
095   }
096
097   /**
098    * Bean property setter:  <property>description</property>.
099    *
100    * <p>
101    * A short description of the target documentation.
102    *
103    * @param value
104    *    The new value for this property.
105    *    <br>{@doc ExtGFM} can be used for rich text representation.
106    *    <br>Can be <jk>null</jk> to unset the property.
107    * @return This object (for method chaining).
108    */
109   public ExternalDocumentation setDescription(String value) {
110      description = value;
111      return this;
112   }
113
114   /**
115    * Same as {@link #setDescription(String)}.
116    *
117    * @param value
118    *    The new value for this property.
119    *    <br>Non-String values will be converted to String using <c>toString()</c>.
120    *    <br>Can be <jk>null</jk> to unset the property.
121    * @return This object (for method chaining).
122    */
123   public ExternalDocumentation description(Object value) {
124      return setDescription(stringify(value));
125   }
126
127   /**
128    * Bean property getter:  <property>url</property>.
129    *
130    * <p>
131    * The URL for the target documentation.
132    *
133    * @return The property value, or <jk>null</jk> if it is not set.
134    */
135   public URI getUrl() {
136      return url;
137   }
138
139   /**
140    * Bean property setter:  <property>url</property>.
141    *
142    * <p>
143    * The URL for the target documentation.
144    *
145    * @param value
146    *    The new value for this property.
147    *    <br>Property value is required.
148    *    <br>URIs defined by {@link UriResolver} can be used for values.
149    * @return This object (for method chaining).
150    */
151   public ExternalDocumentation setUrl(URI value) {
152      url = value;
153      return this;
154   }
155
156   /**
157    * Same as {@link #setUrl(URI)}.
158    *
159    * @param value
160    *    The new value for this property.
161    *    <br>URIs defined by {@link UriResolver} can be used for values.
162    *    <br>Valid types:
163    *    <ul>
164    *       <li>{@link URI}
165    *       <li>{@link URL}
166    *       <li>{@link String}
167    *          <br>Converted to URI using <code><jk>new</jk> URI(value.toString())</code>.
168    *       <li>
169    *    </ul>
170    *    <br>Can be <jk>null</jk> to unset the property.
171    * @return This object (for method chaining).
172    */
173   public ExternalDocumentation url(Object value) {
174      return setUrl(StringUtils.toURI(value));
175   }
176
177   /**
178    * Returns <jk>true</jk> if the url property is not null.
179    *
180    * @return <jk>true</jk> if the url property is not null.
181    */
182   public boolean hasUrl() {
183      return url != null;
184   }
185
186   /**
187    * Returns <jk>true</jk> if the description property is not null or empty.
188    *
189    * @return <jk>true</jk> if the description property is not null or empty.
190    */
191   public boolean hasDescription() {
192      return isNotEmpty(description);
193   }
194
195   @Override /* SwaggerElement */
196   public <T> T get(String property, Class<T> type) {
197      if (property == null)
198         return null;
199      switch (property) {
200         case "description": return toType(getDescription(), type);
201         case "url": return toType(getUrl(), type);
202         default: return super.get(property, type);
203      }
204   }
205
206   @Override /* SwaggerElement */
207   public ExternalDocumentation set(String property, Object value) {
208      if (property == null)
209         return this;
210      switch (property) {
211         case "description": return description(value);
212         case "url": return url(value);
213         default:
214            super.set(property, value);
215            return this;
216      }
217   }
218
219   @Override /* SwaggerElement */
220   public Set<String> keySet() {
221      ASet<String> s = ASet.<String>of()
222         .aif(description != null, "description")
223         .aif(url != null, "url");
224      return new MultiSet<>(s, super.keySet());
225   }
226}