1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.juneau.bean.openapi3;
18
19 import static org.apache.juneau.commons.utils.AssertionUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.commons.utils.Utils.*;
22 import static org.apache.juneau.internal.ConverterUtils.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.commons.collections.*;
27
28 /**
29 * TODO
30 *
31 * <p>
32 * The ServerVariable Object represents a server variable for server URL template substitution. Server variables can be
33 * used to define different server environments (e.g., development, staging, production) with different base URLs,
34 * ports, or other variable parts of the server URL.
35 *
36 * <h5 class='section'>OpenAPI Specification:</h5>
37 * <p>
38 * The ServerVariable Object is composed of the following fields:
39 * <ul class='spaced-list'>
40 * <li><c>enum</c> (array of any) - An enumeration of string values to be used if the substitution options are from a limited set
41 * <li><c>default</c> (string, REQUIRED) - The default value to use for substitution, which SHALL be sent if an alternate value is not supplied
42 * <li><c>description</c> (string) - An optional description for the server variable. CommonMark syntax MAY be used for rich text representation
43 * </ul>
44 *
45 * <h5 class='section'>Example:</h5>
46 * <p class='bcode'>
47 * <jc>// Construct using SwaggerBuilder.</jc>
48 * ServerVariable <jv>x</jv> = <jsm>serverVariable</jsm>()
49 * .setDefault(<js>"api"</js>)
50 * .setEnum(<js>"api"</js>, <js>"staging"</js>, <js>"dev"</js>)
51 * .setDescription(<js>"Environment to use"</js>);
52 *
53 * <jc>// Serialize using JsonSerializer.</jc>
54 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>);
55 *
56 * <jc>// Or just use toString() which does the same as above.</jc>
57 * <jv>json</jv> = <jv>x</jv>.toString();
58 * </p>
59 * <p class='bcode'>
60 * <jc>// Output</jc>
61 * {
62 * <js>"default"</js>: <js>"api"</js>,
63 * <js>"enum"</js>: [<js>"api"</js>, <js>"staging"</js>, <js>"dev"</js>],
64 * <js>"description"</js>: <js>"Environment to use"</js>
65 * }
66 * </p>
67 *
68 * <h5 class='section'>See Also:</h5><ul>
69 * <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#server-variable-object">OpenAPI Specification > Server Variable Object</a>
70 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/api-host-and-base-path/">OpenAPI API Host and Base Path</a>
71 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
72 * </ul>
73 */
74 public class ServerVariable extends OpenApiElement {
75
76 private List<Object> enum_ = list();
77 private String default_;
78 private String description;
79
80 /**
81 * Default constructor.
82 */
83 public ServerVariable() {}
84
85 /**
86 * Copy constructor.
87 *
88 * @param copyFrom The object to copy.
89 */
90 public ServerVariable(ServerVariable copyFrom) {
91 super(copyFrom);
92
93 if (nn(copyFrom.enum_))
94 this.enum_.addAll(copyOf(copyFrom.enum_));
95 this.default_ = copyFrom.default_;
96 this.description = copyFrom.description;
97 }
98
99 /**
100 * Adds one or more values to the <property>enum</property> property.
101 *
102 * @param values
103 * The values to add to this property.
104 * <br>Valid types:
105 * <ul>
106 * <li><code>Object</code>
107 * <li><code>Collection<Object></code>
108 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code>
109 * <h5 class='figure'>Example:</h5>
110 * <p class='bcode'>
111 * enum_(<js>"['foo','bar']"</js>);
112 * </p>
113 * <li><code>String</code> - Individual values
114 * <h5 class='figure'>Example:</h5>
115 * <p class='bcode'>
116 * enum_(<js>"foo"</js>, <js>"bar"</js>);
117 * </p>
118 * </ul>
119 * <br>Ignored if <jk>null</jk>.
120 * @return This object
121 */
122 public ServerVariable addEnum(Object...values) {
123 if (nn(values))
124 for (var v : values)
125 if (nn(v))
126 enum_.add(v);
127 return this;
128 }
129
130 /**
131 * Make a deep copy of this object.
132 * @return A deep copy of this object.
133 */
134 public ServerVariable copy() {
135 return new ServerVariable(this);
136 }
137
138 @Override /* Overridden from OpenApiElement */
139 public <T> T get(String property, Class<T> type) {
140 assertArgNotNull("property", property);
141 return switch (property) {
142 case "enum" -> toType(getEnum(), type);
143 case "default" -> toType(getDefault(), type);
144 case "description" -> toType(getDescription(), type);
145 default -> super.get(property, type);
146 };
147 }
148
149 /**
150 * Bean property getter: <property>default</property>.
151 *
152 * <p>
153 * Declares the value of the item that the server will use if none is provided.
154 *
155 * <h5 class='section'>Notes:</h5>
156 * <ul class='spaced-list'>
157 * <li>
158 * <js>"default"</js> has no meaning for required items.
159 * <li>
160 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type.
161 * </ul>
162 *
163 * @return The property value, or <jk>null</jk> if it is not set.
164 */
165 public String getDefault() { return default_; }
166
167 /**
168 * Bean property getter: <property>description</property>.
169 *
170 * <p>
171 * Declares the value of the item that the server will use if none is provided.
172 *
173 * <h5 class='section'>Notes:</h5>
174 * <ul class='spaced-list'>
175 * <li>
176 * <js>"description"</js> has no meaning for required items.
177 * <li>
178 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type.
179 * </ul>
180 *
181 * @return The property value, or <jk>null</jk> if it is not set.
182 */
183 public String getDescription() { return description; }
184
185 /**
186 * Bean property getter: <property>enum</property>.
187 *
188 * @return The property value, or <jk>null</jk> if it is not set.
189 */
190 public List<Object> getEnum() { return nullIfEmpty(enum_); }
191
192 @Override /* Overridden from OpenApiElement */
193 public Set<String> keySet() {
194 // @formatter:off
195 var s = setb(String.class)
196 .addIf(nn(default_),"default" )
197 .addIf(nn(description), "description")
198 .addIf(ne(enum_), "enum")
199 .build();
200 // @formatter:on
201 return new MultiSet<>(s, super.keySet());
202 }
203
204 @Override /* Overridden from OpenApiElement */
205 public ServerVariable set(String property, Object value) {
206 assertArgNotNull("property", property);
207 return switch (property) {
208 case "default" -> setDefault(s(value));
209 case "description" -> setDescription(s(value));
210 case "enum" -> setEnum(listb(Object.class).addAny(value).sparse().build());
211 default -> {
212 super.set(property, value);
213 yield this;
214 }
215 };
216 }
217
218 /**
219 * Bean property setter: <property>default</property>.
220 *
221 * <p>
222 * Declares the value of the item that the server will use if none is provided.
223 *
224 * <h5 class='section'>Notes:</h5>
225 * <ul class='spaced-list'>
226 * <li>
227 * <js>"default"</js> has no meaning for required items.
228 * <li>
229 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type.
230 * </ul>
231 *
232 * @param value
233 * The new value for this property.
234 * <br>Can be <jk>null</jk> to unset the property.
235 * @return This object
236 */
237 public ServerVariable setDefault(String value) {
238 default_ = value;
239 return this;
240 }
241
242 /**
243 * Bean property setter: <property>description</property>.
244 *
245 * <p>
246 * Declares the value of the item that the server will use if none is provided.
247 *
248 * <h5 class='section'>Notes:</h5>
249 * <ul class='spaced-list'>
250 * <li>
251 * <js>"description"</js> has no meaning for required items.
252 * <li>
253 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type.
254 * </ul>
255 *
256 * @param value
257 * The new value for this property.
258 * <br>Can be <jk>null</jk> to unset the property.
259 * @return This object
260 */
261 public ServerVariable setDescription(String value) {
262 description = value;
263 return this;
264 }
265
266 /**
267 * Bean property setter: <property>enum</property>.
268 *
269 * @param value
270 * The new value for this property.
271 * <br>Can be <jk>null</jk> to unset the property.
272 * @return This object
273 */
274 public ServerVariable setEnum(Collection<Object> value) {
275 enum_.clear();
276 if (nn(value))
277 enum_.addAll(value);
278 return this;
279 }
280
281 @Override /* Overridden from OpenApiElement */
282 public ServerVariable strict(Object value) {
283 super.strict(value);
284 return this;
285 }
286
287 @Override /* Overridden from OpenApiElement */
288 protected ServerVariable strict() {
289 super.strict();
290 return this;
291 }
292 }