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.swagger; 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 * A metadata object that allows for more fine-tuned XML model definitions. 030 * 031 * <p> 032 * The Xml Object is a metadata object that allows for more fine-tuned XML model definitions in Swagger 2.0. When using 033 * arrays, XML element names are not inferred (for singular/plural forms) and the name property should be used to add 034 * that information. This object is used to control how schema properties are serialized to XML. 035 * 036 * <h5 class='section'>Swagger Specification:</h5> 037 * <p> 038 * The Xml Object is composed of the following fields: 039 * <ul class='spaced-list'> 040 * <li><c>name</c> (string) - Replaces the name of the element/attribute used for the described schema property 041 * <li><c>namespace</c> (string) - The URI of the namespace definition 042 * <li><c>prefix</c> (string) - The prefix to be used for the name 043 * <li><c>attribute</c> (boolean) - Declares whether the property definition translates to an attribute instead of an element 044 * <li><c>wrapped</c> (boolean) - May be used only for an array definition. Signifies whether the array is wrapped 045 * </ul> 046 * 047 * <h5 class='section'>Example:</h5> 048 * <p class='bjava'> 049 * <jc>// Construct using SwaggerBuilder.</jc> 050 * Xml <jv>xml</jv> = <jsm>xml</jsm>() 051 * .name(<js>"foo"</js>) 052 * .namespace(<js>"http://foo"</js>) 053 * 054 * <jc>// Serialize using JsonSerializer.</jc> 055 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>xml</jv>); 056 * 057 * <jc>// Or just use toString() which does the same as above.</jc> 058 * <jv>json</jv> = <jv>xml</jv>.toString(); 059 * </p> 060 * <p class='bjson'> 061 * <jc>// Output</jc> 062 * { 063 * <js>"name"</js>: <js>"foo"</js>, 064 * <js>"namespace"</js>: <js>"http://foo"</js> 065 * } 066 * </p> 067 * 068 * <h5 class='section'>See Also:</h5><ul> 069 * <li class='link'><a class="doclink" href="https://swagger.io/specification/v2/#xml-object">Swagger 2.0 Specification > XML Object</a> 070 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/2-0/describing-models/">Swagger Describing Models</a> 071 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanSwagger2">juneau-bean-swagger-v2</a> 072 * </ul> 073 */ 074public class Xml extends SwaggerElement { 075 076 private String 077 name, 078 namespace, 079 prefix; 080 private Boolean 081 attribute, 082 wrapped; 083 084 /** 085 * Default constructor. 086 */ 087 public Xml() {} 088 089 /** 090 * Copy constructor. 091 * 092 * @param copyFrom The object to copy. 093 */ 094 public Xml(Xml copyFrom) { 095 super(copyFrom); 096 097 this.attribute = copyFrom.attribute; 098 this.name = copyFrom.name; 099 this.namespace = copyFrom.namespace; 100 this.prefix = copyFrom.prefix; 101 this.wrapped = copyFrom.wrapped; 102 } 103 104 /** 105 * Make a deep copy of this object. 106 * 107 * @return A deep copy of this object. 108 */ 109 public Xml copy() { 110 return new Xml(this); 111 } 112 113 //----------------------------------------------------------------------------------------------------------------- 114 // Properties 115 //----------------------------------------------------------------------------------------------------------------- 116 117 /** 118 * Bean property getter: <property>attribute</property>. 119 * 120 * <p> 121 * Declares whether the property definition translates to an attribute instead of an element. 122 * 123 * @return The property value, or <jk>null</jk> if it is not set. 124 */ 125 public Boolean getAttribute() { 126 return attribute; 127 } 128 129 /** 130 * Bean property setter: <property>attribute</property>. 131 * 132 * <p> 133 * Declares whether the property definition translates to an attribute instead of an element. 134 * 135 * @param value 136 * The new value for this property. 137 * <br>Default value is <jk>false</jk>. 138 * <br>Can be <jk>null</jk> to unset the property. 139 * @return This object. 140 */ 141 public Xml setAttribute(Boolean value) { 142 attribute = value; 143 return this; 144 } 145 146 /** 147 * Bean property getter: <property>name</property>. 148 * 149 * <p> 150 * The name of the element/attribute used for the described schema property. 151 * 152 * @return The property value, or <jk>null</jk> if it is not set. 153 */ 154 public String getName() { 155 return name; 156 } 157 158 /** 159 * Bean property setter: <property>name</property>. 160 * 161 * <p> 162 * The name of the element/attribute used for the described schema property. 163 * 164 * @param value 165 * The new value for this property. 166 * <br>Can be <jk>null</jk> to unset the property. 167 * @return This object. 168 */ 169 public Xml setName(String value) { 170 name = value; 171 return this; 172 } 173 174 /** 175 * Bean property getter: <property>namespace</property>. 176 * 177 * <p> 178 * The URL of the namespace definition. 179 * 180 * @return The property value, or <jk>null</jk> if it is not set. 181 */ 182 public String getNamespace() { 183 return namespace; 184 } 185 186 /** 187 * Bean property setter: <property>namespace</property>. 188 * 189 * <p> 190 * The URL of the namespace definition. 191 * 192 * @param value 193 * The new value for this property. 194 * <br>Can be <jk>null</jk> to unset the property. 195 * @return This object. 196 */ 197 public Xml setNamespace(String value) { 198 namespace = value; 199 return this; 200 } 201 202 /** 203 * Bean property getter: <property>prefix</property>. 204 * 205 * <p> 206 * The prefix to be used for the name. 207 * 208 * @return The property value, or <jk>null</jk> if it is not set. 209 */ 210 public String getPrefix() { 211 return prefix; 212 } 213 214 /** 215 * Bean property setter: <property>prefix</property>. 216 * 217 * <p> 218 * The prefix to be used for the name. 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 Xml setPrefix(String value) { 226 prefix = value; 227 return this; 228 } 229 230 /** 231 * Bean property getter: <property>wrapped</property>. 232 * 233 * <p> 234 * Signifies whether the array is wrapped (for example, 235 * <c><books><book/><book/><books></c>) or unwrapped 236 * (<c><book/><book/></c>). 237 * <br>The definition takes effect only when defined alongside <c>type</c> being <c>array</c> 238 * (outside the <c>items</c>). 239 * 240 * @return The property value, or <jk>null</jk> if it is not set. 241 */ 242 public Boolean getWrapped() { 243 return wrapped; 244 } 245 246 /** 247 * Bean property setter: <property>wrapped</property>. 248 * 249 * 250 * <p> 251 * Signifies whether the array is wrapped (for example, 252 * <c><books><book/><book/><books></c>) or unwrapped 253 * (<c><book/><book/></c>). 254 * <br>The definition takes effect only when defined alongside <c>type</c> being <c>array</c> 255 * (outside the <c>items</c>). 256 * 257 * @param value 258 * The new value for this property. 259 * <br>Can be <jk>null</jk> to unset the property. 260 * @return This object. 261 */ 262 public Xml setWrapped(Boolean value) { 263 this.wrapped = value; 264 return this; 265 } 266 267 @Override /* Overridden from SwaggerElement */ 268 public <T> T get(String property, Class<T> type) { 269 assertArgNotNull("property", property); 270 return switch (property) { 271 case "attribute" -> toType(getAttribute(), type); 272 case "name" -> toType(getName(), type); 273 case "namespace" -> toType(getNamespace(), type); 274 case "prefix" -> toType(getPrefix(), type); 275 case "wrapped" -> toType(getWrapped(), type); 276 default -> super.get(property, type); 277 }; 278 } 279 280 @Override /* Overridden from SwaggerElement */ 281 public Xml set(String property, Object value) { 282 assertArgNotNull("property", property); 283 return switch (property) { 284 case "attribute" -> setAttribute(toBoolean(value)); 285 case "name" -> setName(Utils.s(value)); 286 case "namespace" -> setNamespace(Utils.s(value)); 287 case "prefix" -> setPrefix(Utils.s(value)); 288 case "wrapped" -> setWrapped(toBoolean(value)); 289 default -> { 290 super.set(property, value); 291 yield this; 292 } 293 }; 294 } 295 296 @Override /* Overridden from SwaggerElement */ 297 public Set<String> keySet() { 298 var s = setBuilder(String.class) 299 .addIf(attribute != null, "attribute") 300 .addIf(name != null, "name") 301 .addIf(namespace != null, "namespace") 302 .addIf(prefix != null, "prefix") 303 .addIf(wrapped != null, "wrapped") 304 .build(); 305 return new MultiSet<>(s, super.keySet()); 306 } 307 308 /** 309 * Sets strict mode on this bean. 310 * 311 * @return This object. 312 */ 313 @Override 314 public Xml strict() { 315 super.strict(); 316 return this; 317 } 318 319 /** 320 * Sets strict mode on this bean. 321 * 322 * @param value 323 * The new value for this property. 324 * <br>Non-boolean values will be converted to boolean using <code>Boolean.<jsm>valueOf</jsm>(value.toString())</code>. 325 * <br>Can be <jk>null</jk> (interpreted as <jk>false</jk>). 326 * @return This object. 327 */ 328 @Override 329 public Xml strict(Object value) { 330 super.strict(value); 331 return this; 332 } 333 334}