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.util.*;
019
020import org.apache.juneau.annotation.*;
021import org.apache.juneau.collections.*;
022import org.apache.juneau.internal.*;
023
024/**
025 * Allows adding meta data to a single tag that is used by the {@doc ExtSwaggerOperationObject Operation Object}.
026 *
027 * <p>
028 * It is not mandatory to have a Tag Object per tag used there.
029 *
030 * <h5 class='section'>Example:</h5>
031 * <p class='bcode w800'>
032 *    <jc>// Construct using SwaggerBuilder.</jc>
033 *    Tag x = <jsm>tag</jsm>()
034 *       .name(<js>"pet"</js>)
035 *       .description(<js>"Pets operations"</js>)
036 *
037 *    <jc>// Serialize using JsonSerializer.</jc>
038 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
039 *
040 *    <jc>// Or just use toString() which does the same as above.</jc>
041 *    String json = x.toString();
042 * </p>
043 * <p class='bcode w800'>
044 *    <jc>// Output</jc>
045 *    {
046 *       <js>"name"</js>: <js>"pet"</js>,
047 *       <js>"description"</js>: <js>"Pets operations"</js>
048 *    }
049 * </p>
050 *
051 * <ul class='seealso'>
052 *    <li class='link'>{@doc DtoSwagger}
053 * </ul>
054 */
055@Bean(bpi="name,description,externalDocs,*")
056public class Tag extends SwaggerElement {
057
058   private String
059      name,
060      description;
061   private ExternalDocumentation externalDocs;
062
063   /**
064    * Default constructor.
065    */
066   public Tag() {}
067
068   /**
069    * Copy constructor.
070    *
071    * @param copyFrom The object to copy.
072    */
073   public Tag(Tag copyFrom) {
074      super(copyFrom);
075
076      this.name = copyFrom.name;
077      this.description = copyFrom.description;
078      this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
079   }
080
081   /**
082    * Make a deep copy of this object.
083    *
084    * @return A deep copy of this object.
085    */
086   public Tag copy() {
087      return new Tag(this);
088   }
089
090   /**
091    * Bean property getter:  <property>name</property>.
092    *
093    * <p>
094    * The name of the tag.
095    *
096    * @return The property value, or <jk>null</jk> if it is not set.
097    */
098   public String getName() {
099      return name;
100   }
101
102   /**
103    * Bean property setter:  <property>name</property>.
104    *
105    * <p>
106    * The name of the tag.
107    *
108    * @param value
109    *    The new value for this property.
110    *    <br>Property value is required.
111    * @return This object (for method chaining).
112    */
113   public Tag setName(String value) {
114      name = value;
115      return this;
116   }
117
118   /**
119    * Same as {@link #setName(String)}.
120    *
121    * @param value
122    *    The new value for this property.
123    *    <br>Non-String values will be converted to String using <c>toString()</c>.
124    *    <br>Can be <jk>null</jk> to unset the property.
125    * @return This object (for method chaining).
126    */
127   public Tag name(Object value) {
128      return setName(stringify(value));
129   }
130
131   /**
132    * Bean property getter:  <property>description</property>.
133    *
134    * <p>
135    * A short description for the tag.
136    *
137    * @return The property value, or <jk>null</jk> if it is not set.
138    */
139   public String getDescription() {
140      return description;
141   }
142
143   /**
144    * Bean property setter:  <property>description</property>.
145    *
146    * <p>
147    * A short description for the tag.
148    *
149    * @param value
150    *    The new value for this property.
151    *    <br>{@doc ExtGFM} can be used for rich text representation.
152    *    <br>Can be <jk>null</jk> to unset the property.
153    * @return This object (for method chaining).
154    */
155   public Tag setDescription(String value) {
156      description = value;
157      return this;
158   }
159
160   /**
161    * Same as {@link #setDescription(String)}.
162    *
163    * @param value
164    *    The new value for this property.
165    *    <br>Non-String values will be converted to String using <c>toString()</c>.
166    *    <br>Can be <jk>null</jk> to unset the property.
167    * @return This object (for method chaining).
168    */
169   public Tag description(Object value) {
170      return setDescription(stringify(value));
171   }
172
173   /**
174    * Bean property getter:  <property>externalDocs</property>.
175    *
176    * <p>
177    * Additional external documentation for this tag.
178    *
179    * @return The property value, or <jk>null</jk> if it is not set.
180    */
181   public ExternalDocumentation getExternalDocs() {
182      return externalDocs;
183   }
184
185   /**
186    * Bean property setter:  <property>externalDocs</property>.
187    *
188    * <p>
189    * Additional external documentation for this tag.
190    *
191    * @param value
192    *    The new value for this property.
193    *    <br>Can be <jk>null</jk> to unset the property.
194    * @return This object (for method chaining).
195    */
196   public Tag setExternalDocs(ExternalDocumentation value) {
197      externalDocs = value;
198      return this;
199   }
200
201   /**
202    * Same as {@link #setExternalDocs(ExternalDocumentation)}.
203    *
204    * @param value
205    *    The new value for this property.
206    *    <br>Valid types:
207    *    <ul>
208    *       <li>{@link ExternalDocumentation}
209    *       <li><c>String</c> - JSON object representation of {@link ExternalDocumentation}
210    *          <p class='bcode w800'>
211    *    <jc>// Example </jc>
212    *    externalDocs(<js>"{description:'description',url:'url'}"</js>);
213    *          </p>
214    *    </ul>
215    *    <br>Can be <jk>null</jk> to unset the property.
216    * @return This object (for method chaining).
217    */
218   public Tag externalDocs(Object value) {
219      return setExternalDocs(toType(value, ExternalDocumentation.class));
220   }
221
222   @Override /* SwaggerElement */
223   public <T> T get(String property, Class<T> type) {
224      if (property == null)
225         return null;
226      switch (property) {
227         case "name": return toType(getName(), type);
228         case "description": return toType(getDescription(), type);
229         case "externalDocs": return toType(getExternalDocs(), type);
230         default: return super.get(property, type);
231      }
232   }
233
234   @Override /* SwaggerElement */
235   public Tag set(String property, Object value) {
236      if (property == null)
237         return this;
238      switch (property) {
239         case "name": return name(value);
240         case "description": return description(value);
241         case "externalDocs": return externalDocs(value);
242         default:
243            super.set(property, value);
244            return this;
245      }
246   }
247
248   @Override /* SwaggerElement */
249   public Set<String> keySet() {
250      ASet<String> s = ASet.<String>of()
251         .aif(name != null, "name")
252         .aif(description != null, "description")
253         .aif(externalDocs != null, "externalDocs");
254      return new MultiSet<>(s, super.keySet());
255   }
256}