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.CollectionUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021import static org.apache.juneau.marshall.internal.ConverterUtils.*; 022 023import java.util.*; 024 025import org.apache.juneau.commons.collections.*; 026 027/** 028 * The ServerVariable Object represents a server variable for server URL template substitution. Server variables can be 029 * used to define different server environments (e.g., development, staging, production) with different base URLs, 030 * ports, or other variable parts of the server URL. 031 * 032 * <h5 class='section'>OpenAPI Specification:</h5> 033 * <p> 034 * The ServerVariable Object is composed of the following fields: 035 * <ul class='spaced-list'> 036 * <li><c>enum</c> (array of any) - An enumeration of string values to be used if the substitution options are from a limited set 037 * <li><c>default</c> (string, REQUIRED) - The default value to use for substitution, which SHALL be sent if an alternate value is not supplied 038 * <li><c>description</c> (string) - An optional description for the server variable. CommonMark syntax MAY be used for rich text representation 039 * </ul> 040 * 041 * <h5 class='section'>Example:</h5> 042 * <p class='bcode'> 043 * <jc>// Construct using SwaggerBuilder.</jc> 044 * ServerVariable <jv>x</jv> = <jsm>serverVariable</jsm>() 045 * .setDefault(<js>"api"</js>) 046 * .setEnum(<js>"api"</js>, <js>"staging"</js>, <js>"dev"</js>) 047 * .setDescription(<js>"Environment to use"</js>); 048 * 049 * <jc>// Serialize using JsonSerializer.</jc> 050 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>x</jv>); 051 * 052 * <jc>// Or just use toString() which does the same as above.</jc> 053 * <jv>json</jv> = <jv>x</jv>.toString(); 054 * </p> 055 * <p class='bcode'> 056 * <jc>// Output</jc> 057 * { 058 * <js>"default"</js>: <js>"api"</js>, 059 * <js>"enum"</js>: [<js>"api"</js>, <js>"staging"</js>, <js>"dev"</js>], 060 * <js>"description"</js>: <js>"Environment to use"</js> 061 * } 062 * </p> 063 * 064 * <h5 class='section'>See Also:</h5><ul> 065 * <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#server-variable-object">OpenAPI Specification > Server Variable Object</a> 066 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/api-host-and-base-path/">OpenAPI API Host and Base Path</a> 067 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a> 068 * </ul> 069 */ 070@SuppressWarnings({ 071 "java:S116", // Field name uses trailing underscore (default_) to avoid Java keyword conflict 072 "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants 073}) 074public class ServerVariable extends OpenApiElement { 075 076 private final List<Object> enum_ = list(); 077 private String default_; 078 private String description; 079 080 /** 081 * Default constructor. 082 */ 083 public ServerVariable() {} 084 085 /** 086 * Copy constructor. 087 * 088 * @param copyFrom The object to copy. 089 */ 090 public ServerVariable(ServerVariable copyFrom) { 091 super(copyFrom); 092 093 this.enum_.addAll(cp(copyFrom.enum_)); 094 this.default_ = copyFrom.default_; 095 this.description = copyFrom.description; 096 } 097 098 /** 099 * Adds one or more values to the <property>enum</property> property. 100 * 101 * @param values 102 * The values to add to this property. 103 * <br>Valid types: 104 * <ul> 105 * <li><code>Object</code> 106 * <li><code>Collection<Object></code> 107 * <li><code>String</code> - JSON array representation of <code>Collection<Object></code> 108 * <h5 class='figure'>Example:</h5> 109 * <p class='bcode'> 110 * enum_(<js>"['foo','bar']"</js>); 111 * </p> 112 * <li><code>String</code> - Individual values 113 * <h5 class='figure'>Example:</h5> 114 * <p class='bcode'> 115 * enum_(<js>"foo"</js>, <js>"bar"</js>); 116 * </p> 117 * </ul> 118 * <br>Ignored if <jk>null</jk>. 119 * @return This object 120 */ 121 public ServerVariable addEnum(Object...values) { 122 addAllNn(enum_, values); 123 return this; 124 } 125 126 /** 127 * Make a deep copy of this object. 128 * @return A deep copy of this object. 129 */ 130 public ServerVariable copy() { 131 return new ServerVariable(this); 132 } 133 134 @Override /* Overridden from OpenApiElement */ 135 public <T> T get(String property, Class<T> type) { 136 reqnn("property", property); 137 return switch (property) { 138 case "enum" -> toType(getEnum(), type); 139 case "default" -> toType(getDefault(), type); 140 case "description" -> toType(getDescription(), type); 141 default -> super.get(property, type); 142 }; 143 } 144 145 /** 146 * Bean property getter: <property>default</property>. 147 * 148 * <p> 149 * Declares the value of the item that the server will use if none is provided. 150 * 151 * <h5 class='section'>Notes:</h5> 152 * <ul class='spaced-list'> 153 * <li> 154 * <js>"default"</js> has no meaning for required items. 155 * <li> 156 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type. 157 * </ul> 158 * 159 * @return The property value, or <jk>null</jk> if it is not set. 160 */ 161 public String getDefault() { return default_; } 162 163 /** 164 * Bean property getter: <property>description</property>. 165 * 166 * <p> 167 * An optional description for the server variable. 168 * 169 * @return The property value, or <jk>null</jk> if it is not set. 170 */ 171 public String getDescription() { return description; } 172 173 /** 174 * Bean property getter: <property>enum</property>. 175 * 176 * @return The property value, or <jk>null</jk> if it is not set. 177 */ 178 public List<Object> getEnum() { return nie(enum_); } 179 180 @Override /* Overridden from OpenApiElement */ 181 public Set<String> keySet() { 182 // @formatter:off 183 var s = stb(String.class) 184 .addIf(nn(default_), "default") 185 .addIf(nn(description), "description") 186 .addIf(ine(enum_), "enum") 187 .build(); 188 // @formatter:on 189 return new MultiSet<>(s, super.keySet()); 190 } 191 192 @Override /* Overridden from OpenApiElement */ 193 public ServerVariable set(String property, Object value) { 194 reqnn("property", property); 195 return switch (property) { 196 case "default" -> setDefault(s(value)); 197 case "description" -> setDescription(s(value)); 198 case "enum" -> setEnum(lb(Object.class).addAny(value).sparse().build()); 199 default -> { 200 super.set(property, value); 201 yield this; 202 } 203 }; 204 } 205 206 /** 207 * Bean property setter: <property>default</property>. 208 * 209 * <p> 210 * Declares the value of the item that the server will use if none is provided. 211 * 212 * <h5 class='section'>Notes:</h5> 213 * <ul class='spaced-list'> 214 * <li> 215 * <js>"default"</js> has no meaning for required items. 216 * <li> 217 * Unlike JSON Schema this value MUST conform to the defined <code>type</code> for the data type. 218 * </ul> 219 * 220 * @param value 221 * The new value for this property. 222 * <br>Can be <jk>null</jk> to unset the property. 223 * @return This object 224 */ 225 public ServerVariable setDefault(String value) { 226 default_ = value; 227 return this; 228 } 229 230 /** 231 * Bean property setter: <property>description</property>. 232 * 233 * <p> 234 * An optional description for the server variable. 235 * 236 * @param value 237 * The new value for this property. 238 * <br>Can be <jk>null</jk> to unset the property. 239 * @return This object 240 */ 241 public ServerVariable setDescription(String value) { 242 description = value; 243 return this; 244 } 245 246 /** 247 * Bean property setter: <property>enum</property>. 248 * 249 * @param value 250 * The new value for this property. 251 * <br>Can be <jk>null</jk> to unset the property. 252 * @return This object 253 */ 254 public ServerVariable setEnum(Collection<Object> value) { 255 enum_.clear(); 256 if (nn(value)) 257 enum_.addAll(value); 258 return this; 259 } 260 261 @Override /* Overridden from OpenApiElement */ 262 public ServerVariable strict(Object value) { 263 super.strict(value); 264 return this; 265 } 266 267 @Override /* Overridden from OpenApiElement */ 268 protected ServerVariable strict() { 269 super.strict(); 270 return this; 271 } 272}