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.commons.utils.AssertionUtils.*;
020import static org.apache.juneau.commons.utils.CollectionUtils.*;
021import static org.apache.juneau.commons.utils.Utils.*;
022import static org.apache.juneau.internal.ConverterUtils.*;
023
024import java.util.*;
025
026import org.apache.juneau.commons.collections.*;
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   @Override /* Overridden from OpenApiElement */
110   public <T> T get(String property, Class<T> type) {
111      assertArgNotNull("property", property);
112      return switch (property) {
113         case "description" -> toType(getDescription(), type);
114         case "externalValue" -> toType(getExternalValue(), type);
115         case "summary" -> toType(getSummary(), type);
116         case "value" -> toType(getValue(), type);
117         default -> super.get(property, type);
118      };
119   }
120
121   /**
122    * Bean property getter:  <property>description</property>.
123    *
124    * <p>
125    * The URL pointing to the contact information.
126    *
127    * @return The property value, or <jk>null</jk> if it is not set.
128    */
129   public String getDescription() { return description; }
130
131   /**
132    * Bean property getter:  <property>externalValue</property>.
133    *
134    * <p>
135    * The email address of the contact person/organization.
136    *
137    * @return The property value, or <jk>null</jk> if it is not set.
138    */
139   public String getExternalValue() { return externalValue; }
140
141   /**
142    * Bean property getter:  <property>summary</property>.
143    *
144    * <p>
145    * The identifying name of the contact person/organization.
146    *
147    * @return The property value, or <jk>null</jk> if it is not set.
148    */
149   public String getSummary() { return summary; }
150
151   /**
152    * Bean property getter:  <property>default</property>.
153    *
154    * <p>
155    * Declares the value of the parameter that the server will use if none is provided, for example a <js>"count"</js>
156    * to control the number of results per page might default to 100 if not supplied by the client in the request.
157    *
158    * (Note: <js>"value"</js> has no meaning for required parameters.)
159    * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for this parameter.
160    *
161    * @return The property value, or <jk>null</jk> if it is not set.
162    */
163   public Object getValue() { return value; }
164
165   @Override /* Overridden from OpenApiElement */
166   public Set<String> keySet() {
167      // @formatter:off
168      var s = setb(String.class)
169         .addIf(nn(description), "description")
170         .addIf(nn(externalValue), "externalValue")
171         .addIf(nn(summary), "summary")
172         .addIf(nn(value), "value")
173         .build();
174      // @formatter:on
175      return new MultiSet<>(s, super.keySet());
176   }
177
178   @Override /* Overridden from OpenApiElement */
179   public Example set(String property, Object value) {
180      assertArgNotNull("property", property);
181      return switch (property) {
182         case "description" -> setDescription(s(value));
183         case "externalValue" -> setExternalValue(s(value));
184         case "summary" -> setSummary(s(value));
185         case "value" -> setValue(value);
186         default -> {
187            super.set(property, value);
188            yield this;
189         }
190      };
191   }
192
193   /**
194    * Bean property setter:  <property>description</property>.
195    * @param value
196    *    The new value for this property.
197    *    <br>Can be <jk>null</jk> to unset the property.
198    * @return This object
199    */
200   public Example setDescription(String value) {
201      description = value;
202      return this;
203   }
204
205   /**
206    * Bean property setter:  <property>externalValue</property>.
207    *
208    * <p>
209    * The email address of the contact person/organization.
210    *
211    * @param value
212    *    The new value for this property.
213    *    <br>MUST be in the format of an email address.
214    *    <br>Can be <jk>null</jk> to unset the property.
215    * @return This object
216    */
217   public Example setExternalValue(String value) {
218      externalValue = value;
219      return this;
220   }
221
222   /**
223    * Bean property setter:  <property>summary</property>.
224    *
225    * <p>
226    * The identifying name of the contact person/organization.
227    *
228    * @param value
229    *    The new value for this property.
230    *    <br>Can be <jk>null</jk> to unset the property.
231    * @return This object
232    */
233   public Example setSummary(String value) {
234      summary = value;
235      return this;
236   }
237
238   /**
239    * Bean property setter:  <property>value</property>.
240    *
241    * <p>
242    * Declares the value of the parameter that the server will use if none is provided, for example a <js>"count"</js>
243    * to control the number of results per page might default to 100 if not supplied by the client in the request.
244    * (Note: <js>"default"</js> has no meaning for required parameters.)
245    * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for this parameter.
246    *
247    * @param val The new value for this property.
248    *    <br>Can be <jk>null</jk> to unset the property.
249    * @return This object
250    */
251   public Example setValue(Object val) {
252      value = val;
253      return this;
254   }
255
256   @Override /* Overridden from OpenApiElement */
257   public Example strict() {
258      super.strict();
259      return this;
260   }
261
262   @Override /* Overridden from OpenApiElement */
263   public Example strict(Object value) {
264      super.strict(value);
265      return this;
266   }
267}