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.openapi3;
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.util.*;
024
025import org.apache.juneau.common.utils.*;
026import org.apache.juneau.internal.*;
027
028/**
029 * information for Examples object.
030 *
031 * <p>
032 * The Example Object provides an example of a media type. The example object is mutually exclusive of the examples 
033 * object. Furthermore, if referencing a schema which contains an example, the example value shall override the example 
034 * provided by the schema.
035 *
036 * <h5 class='section'>OpenAPI Specification:</h5>
037 * <p>
038 * The Example Object is composed of the following fields:
039 * <ul class='spaced-list'>
040 *    <li><c>summary</c> (string) - Short description for the example
041 *    <li><c>description</c> (string) - Long description for the example. CommonMark syntax MAY be used for rich text representation
042 *    <li><c>value</c> (any) - Embedded literal example. The value field and externalValue field are mutually exclusive
043 *    <li><c>externalValue</c> (string) - A URI that points to the literal example. This provides the capability to reference 
044 *       examples that cannot easily be included in JSON or YAML documents. The value field and externalValue field are mutually exclusive
045 * </ul>
046 *
047 * <h5 class='section'>Example:</h5>
048 * <p class='bcode'>
049 *    <jc>// Construct using SwaggerBuilder.</jc>
050 *    Example <jv>x</jv> = <jsm>example</jsm>()
051 *       .setSummary(<js>"User example"</js>)
052 *       .setValue(<js>"John Doe"</js>);
053 *
054 *    <jc>// Serialize using JsonSerializer.</jc>
055 *    String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
056 *
057 *    <jc>// Or just use toString() which does the same as above.</jc>
058 *    <jv>json</jv> = <jv>x</jv>.toString();
059 * </p>
060 * <p class='bcode'>
061 *    <jc>// Output</jc>
062 *    {
063 *       <js>"summary"</js>: <js>"User example"</js>,
064 *       <js>"value"</js>: <js>"John Doe"</js>
065 *    }
066 * </p>
067 *
068 * <h5 class='section'>See Also:</h5><ul>
069 *    <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#example-object">OpenAPI Specification &gt; Example Object</a>
070 *    <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/adding-examples/">OpenAPI Adding Examples</a>
071 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
072 * </ul>
073 */
074public class Example extends OpenApiElement {
075
076   private String summary;
077   private String description;
078   private String externalValue;
079   private Object value;
080
081   /**
082    * Default constructor.
083    */
084   public Example() {}
085
086   /**
087    * Copy constructor.
088    *
089    * @param copyFrom The object to copy.
090    */
091   public Example(Example copyFrom) {
092      super(copyFrom);
093
094      this.summary = copyFrom.summary;
095      this.description = copyFrom.description;
096      this.externalValue = copyFrom.externalValue;
097      this.value = copyFrom.value;
098   }
099
100   /**
101    * Make a deep copy of this object.
102    *
103    * @return A deep copy of this object.
104    */
105   public Example copy() {
106      return new Example(this);
107   }
108
109   /**
110    * Bean property getter:  <property>summary</property>.
111    *
112    * <p>
113    * The identifying name of the contact person/organization.
114    *
115    * @return The property value, or <jk>null</jk> if it is not set.
116    */
117   public String getSummary() {
118      return summary;
119   }
120
121   /**
122    * Bean property setter:  <property>summary</property>.
123    *
124    * <p>
125    * The identifying name of the contact person/organization.
126    *
127    * @param value
128    *    The new value for this property.
129    *    <br>Can be <jk>null</jk> to unset the property.
130    * @return This object
131    */
132   public Example setSummary(String value) {
133      summary = value;
134      return this;
135   }
136
137   /**
138    * Bean property getter:  <property>description</property>.
139    *
140    * <p>
141    * The URL pointing to the contact information.
142    *
143    * @return The property value, or <jk>null</jk> if it is not set.
144    */
145   public String getDescription() {
146      return description;
147   }
148
149   /**
150    * Bean property setter:  <property>description</property>.
151    * @param value
152    *    The new value for this property.
153    *    <br>Can be <jk>null</jk> to unset the property.
154    * @return This object
155    */
156   public Example setDescription(String value) {
157      description = value;
158      return this;
159   }
160
161   /**
162    * Bean property getter:  <property>externalValue</property>.
163    *
164    * <p>
165    * The email address of the contact person/organization.
166    *
167    * @return The property value, or <jk>null</jk> if it is not set.
168    */
169   public String getExternalValue() {
170      return externalValue;
171   }
172
173   /**
174    * Bean property setter:  <property>externalValue</property>.
175    *
176    * <p>
177    * The email address of the contact person/organization.
178    *
179    * @param value
180    *    The new value for this property.
181    *    <br>MUST be in the format of an email address.
182    *    <br>Can be <jk>null</jk> to unset the property.
183    * @return This object
184    */
185   public Example setExternalValue(String value) {
186      externalValue = value;
187      return this;
188   }
189
190   /**
191    * Bean property getter:  <property>default</property>.
192    *
193    * <p>
194    * Declares the value of the parameter that the server will use if none is provided, for example a <js>"count"</js>
195    * to control the number of results per page might default to 100 if not supplied by the client in the request.
196    *
197    * (Note: <js>"value"</js> has no meaning for required parameters.)
198    * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for this parameter.
199    *
200    * @return The property value, or <jk>null</jk> if it is not set.
201    */
202   public Object getValue() {
203      return value;
204   }
205
206   /**
207    * Bean property setter:  <property>value</property>.
208    *
209    * <p>
210    * Declares the value of the parameter that the server will use if none is provided, for example a <js>"count"</js>
211    * to control the number of results per page might default to 100 if not supplied by the client in the request.
212    * (Note: <js>"default"</js> has no meaning for required parameters.)
213    * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for this parameter.
214    *
215    * @param val The new value for this property.
216    *    <br>Can be <jk>null</jk> to unset the property.
217    * @return This object
218    */
219   public Example setValue(Object val) {
220      value = val;
221      return this;
222   }
223
224   @Override /* Overridden from OpenApiElement */
225   public <T> T get(String property, Class<T> type) {
226      assertArgNotNull("property", property);
227      return switch (property) {
228         case "description" -> toType(getDescription(), type);
229         case "externalValue" -> toType(getExternalValue(), type);
230         case "summary" -> toType(getSummary(), type);
231         case "value" -> toType(getValue(), type);
232         default -> super.get(property, type);
233      };
234   }
235
236   @Override /* Overridden from OpenApiElement */
237   public Example set(String property, Object value) {
238      assertArgNotNull("property", property);
239      return switch (property) {
240         case "description" -> setDescription(Utils.s(value));
241         case "externalValue" -> setExternalValue(Utils.s(value));
242         case "summary" -> setSummary(Utils.s(value));
243         case "value" -> setValue(value);
244         default -> {
245            super.set(property, value);
246            yield this;
247         }
248      };
249   }
250
251   @Override /* Overridden from OpenApiElement */
252   public Set<String> keySet() {
253      var s = setBuilder(String.class)
254         .addIf(description != null, "description")
255         .addIf(externalValue != null, "externalValue")
256         .addIf(summary != null, "summary")
257         .addIf(value != null, "value")
258         .build();
259      return new MultiSet<>(s, super.keySet());
260   }
261
262   @Override /* Overridden from OpenApiElement */
263   public Example strict() {
264      super.strict();
265      return this;
266   }
267
268   @Override /* Overridden from OpenApiElement */
269   public Example strict(Object value) {
270      super.strict(value);
271      return this;
272   }
273
274}