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.BeanPropertyUtils.*;
016
017import java.util.*;
018
019import org.apache.juneau.annotation.*;
020import org.apache.juneau.internal.*;
021import org.apache.juneau.utils.*;
022
023/**
024 * Allows adding meta data to a single tag that is used by the {@doc SwaggerOperationObject Operation Object}.
025 *
026 * <p>
027 * It is not mandatory to have a Tag Object per tag used there.
028 *
029 * <h5 class='section'>Example:</h5>
030 * <p class='bcode w800'>
031 *    <jc>// Construct using SwaggerBuilder.</jc>
032 *    Tag x = <jsm>tag</jsm>()
033 *       .name(<js>"pet"</js>)
034 *       .description(<js>"Pets operations"</js>)
035 *
036 *    <jc>// Serialize using JsonSerializer.</jc>
037 *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.toString(x);
038 *
039 *    <jc>// Or just use toString() which does the same as above.</jc>
040 *    String json = x.toString();
041 * </p>
042 * <p class='bcode w800'>
043 *    <jc>// Output</jc>
044 *    {
045 *       <js>"name"</js>: <js>"pet"</js>,
046 *       <js>"description"</js>: <js>"Pets operations"</js>
047 *    }
048 * </p>
049 *
050 * <h5 class='section'>See Also:</h5>
051 * <ul class='doctree'>
052 *    <li class='link'>{@doc juneau-dto.Swagger}
053 * </ul>
054 */
055@Bean(properties="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 <code>toString()</code>.
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(toStringVal(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 GFM} 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 <code>toString()</code>.
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(toStringVal(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><code>String</code> - JSON object representation of {@link ExternalDocumentation}
210    *          <h5 class='figure'>Example:</h5>
211    *          <p class='bcode w800'>
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 = new ASet<String>()
251         .appendIf(name != null, "name")
252         .appendIf(description != null, "description")
253         .appendIf(externalDocs != null, "externalDocs");
254      return new MultiSet<>(s, super.keySet());
255   }
256}