001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.xml; 014 015import org.apache.juneau.*; 016import org.apache.juneau.json.*; 017import org.apache.juneau.serializer.*; 018import org.apache.juneau.xmlschema.*; 019 020/** 021 * Serializes POJO models to XML. 022 * 023 * <h5 class='topic'>Media types</h5> 024 * 025 * Handles <code>Accept</code> types: <code><b>text/xml</b></code> 026 * <p> 027 * Produces <code>Content-Type</code> types: <code><b>text/xml</b></code> 028 * 029 * <h5 class='topic'>Description</h5> 030 * 031 * See the {@link JsonSerializer} class for details on how Java models map to JSON. 032 * 033 * <p> 034 * For example, the following JSON... 035 * <p class='bcode w800'> 036 * { 037 * name:<js>'John Smith'</js>, 038 * address: { 039 * streetAddress: <js>'21 2nd Street'</js>, 040 * city: <js>'New York'</js>, 041 * state: <js>'NY'</js>, 042 * postalCode: <js>10021</js> 043 * }, 044 * phoneNumbers: [ 045 * <js>'212 555-1111'</js>, 046 * <js>'212 555-2222'</js> 047 * ], 048 * additionalInfo: <jk>null</jk>, 049 * remote: <jk>false</jk>, 050 * height: <js>62.4</js>, 051 * <js>'fico score'</js>: <js>' > 640'</js> 052 * } 053 * <p> 054 * ...maps to the following XML using the default serializer... 055 * <p class='bcode w800'> 056 * <xt><object></xt> 057 * <xt><name></xt>John Smith<xt></name></xt> 058 * <xt><address></xt> 059 * <xt><streetAddress></xt>21 2nd Street<xt></streetAddress></xt> 060 * <xt><city></xt>New York<xt></city></xt> 061 * <xt><state></xt>NY<xt></state></xt> 062 * <xt><postalCode></xt>10021<xt></postalCode></xt> 063 * <xt></address></xt> 064 * <xt><phoneNumbers></xt> 065 * <xt><string></xt>212 555-1111<xt></string></xt> 066 * <xt><string></xt>212 555-2222<xt></string></xt> 067 * <xt></phoneNumbers></xt> 068 * <xt><additionalInfo</xt> <xa>_type</xa>=<xs>'null'</xs><xt>></additionalInfo></xt> 069 * <xt><remote></xt>false<xt></remote></xt> 070 * <xt><height></xt>62.4<xt></height></xt> 071 * <xt><fico_x0020_score></xt> &gt; 640<xt></fico_x0020_score></xt> 072 * <xt></object></xt> 073 * 074 * <p> 075 * An additional "add-json-properties" mode is also provided to prevent loss of JSON data types... 076 * <p class='bcode w800'> 077 * <xt><name</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>John Smith<xt></name></xt> 078 * <xt><address</xt> <xa>_type</xa>=<xs>'object'</xs><xt>></xt> 079 * <xt><streetAddress</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>21 2nd Street<xt></streetAddress></xt> 080 * <xt><city</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>New York<xt></city></xt> 081 * <xt><state</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>NY<xt></state></xt> 082 * <xt><postalCode</xt> <xa>_type</xa>=<xs>'number'</xs><xt>></xt>10021<xt></postalCode></xt> 083 * <xt></address></xt> 084 * <xt><phoneNumbers</xt> <xa>_type</xa>=<xs>'array'</xs><xt>></xt> 085 * <xt><string></xt>212 555-1111<xt></string></xt> 086 * <xt><string></xt>212 555-2222<xt></string></xt> 087 * <xt></phoneNumbers></xt> 088 * <xt><additionalInfo</xt> <xa>_type</xa>=<xs>'null'</xs><xt>></additionalInfo></xt> 089 * <xt><remote</xt> <xa>_type</xa>=<xs>'boolean'</xs><xt>></xt>false<xt></remote></xt> 090 * <xt><height</xt> <xa>_type</xa>=<xs>'number'</xs><xt>></xt>62.4<xt></height></xt> 091 * <xt><fico_x0020_score</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt> &gt; 640<xt></fico_x0020_score></xt> 092 * <xt></object></xt> 093 * </p> 094 * 095 * <p> 096 * This serializer provides several serialization options. 097 * Typically, one of the predefined <jsf>DEFAULT</jsf> serializers will be sufficient. 098 * However, custom serializers can be constructed to fine-tune behavior. 099 * 100 * <p> 101 * If an attribute name contains any non-valid XML element characters, they will be escaped using standard 102 * {@code _x####_} notation. 103 * 104 * <h5 class='topic'>Behavior-specific subclasses</h5> 105 * 106 * The following direct subclasses are provided for convenience: 107 * <ul> 108 * <li>{@link Sq} - Default serializer, single quotes. 109 * <li>{@link SqReadable} - Default serializer, single quotes, whitespace added. 110 * </ul> 111 */ 112public class XmlSerializer extends WriterSerializer { 113 114 //------------------------------------------------------------------------------------------------------------------- 115 // Configurable properties 116 //------------------------------------------------------------------------------------------------------------------- 117 118 private static final String PREFIX = "XmlSerializer."; 119 120 /** 121 * Configuration property: Add <js>"_type"</js> properties when needed. 122 * 123 * <h5 class='section'>Property:</h5> 124 * <ul> 125 * <li><b>Name:</b> <js>"XmlSerializer.addBeanTypes.b"</js> 126 * <li><b>Data type:</b> <code>Boolean</code> 127 * <li><b>Default:</b> <jk>false</jk> 128 * <li><b>Session property:</b> <jk>false</jk> 129 * <li><b>Methods:</b> 130 * <ul> 131 * <li class='jm'>{@link XmlSerializerBuilder#addBeanTypes(boolean)} 132 * </ul> 133 * </ul> 134 * 135 * <h5 class='section'>Description:</h5> 136 * <p> 137 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 138 * through reflection. 139 * 140 * <p> 141 * When present, this value overrides the {@link #SERIALIZER_addBeanTypes} setting and is 142 * provided to customize the behavior of specific serializers in a {@link SerializerGroup}. 143 */ 144 public static final String XML_addBeanTypes = PREFIX + "addBeanTypes.b"; 145 146 /** 147 * Configuration property: Add namespace URLs to the root element. 148 * 149 * <h5 class='section'>Property:</h5> 150 * <ul> 151 * <li><b>Name:</b> <js>"XmlSerializer.addNamespaceUrisToRoot.b"</js> 152 * <li><b>Data type:</b> <code>Boolean</code> 153 * <li><b>Default:</b> <jk>false</jk> 154 * <li><b>Session property:</b> <jk>false</jk> 155 * <li><b>Methods:</b> 156 * <ul> 157 * <li class='jm'>{@link XmlSerializerBuilder#addNamespaceUrisToRoot(boolean)} 158 * <li class='jm'>{@link XmlSerializerBuilder#addNamespaceUrisToRoot()} 159 * </ul> 160 * </ul> 161 * 162 * <h5 class='section'>Description:</h5> 163 * <p> 164 * Use this setting to add {@code xmlns:x} attributes to the root element for the default and all mapped namespaces. 165 * 166 * <p> 167 * This setting is ignored if {@link #XML_enableNamespaces} is not enabled. 168 * 169 * <h5 class='section'>See Also:</h5> 170 * <ul> 171 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 172 * </ul> 173 */ 174 public static final String XML_addNamespaceUrisToRoot = PREFIX + "addNamespaceUrisToRoot.b"; 175 176 /** 177 * Configuration property: Auto-detect namespace usage. 178 * 179 * <h5 class='section'>Property:</h5> 180 * <ul> 181 * <li><b>Name:</b> <js>"XmlSerializer.autoDetectNamespaces.b"</js> 182 * <li><b>Data type:</b> <code>Boolean</code> 183 * <li><b>Default:</b> <jk>true</jk> 184 * <li><b>Session property:</b> <jk>false</jk> 185 * <li><b>Methods:</b> 186 * <ul> 187 * <li class='jm'>{@link XmlSerializerBuilder#autoDetectNamespaces(boolean)} 188 * </ul> 189 * </ul> 190 * 191 * <h5 class='section'>Description:</h5> 192 * <p> 193 * Detect namespace usage before serialization. 194 * 195 * <p> 196 * Used in conjunction with {@link #XML_addNamespaceUrisToRoot} to reduce the list of namespace URLs appended to the 197 * root element to only those that will be used in the resulting document. 198 * 199 * <p> 200 * If enabled, then the data structure will first be crawled looking for namespaces that will be encountered before 201 * the root element is serialized. 202 * 203 * <p> 204 * This setting is ignored if {@link #XML_enableNamespaces} is not enabled. 205 * 206 * <h5 class='section'>Notes:</h5> 207 * <ul class='spaced-list'> 208 * <li> 209 * Auto-detection of namespaces can be costly performance-wise. 210 * <br>In high-performance environments, it's recommended that namespace detection be 211 * disabled, and that namespaces be manually defined through the {@link #XML_namespaces} property. 212 * </ul> 213 * 214 * <h5 class='section'>See Also:</h5> 215 * <ul> 216 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 217 * </ul> 218 */ 219 public static final String XML_autoDetectNamespaces = PREFIX + "autoDetectNamespaces.b"; 220 221 /** 222 * Configuration property: Default namespace. 223 * 224 * <h5 class='section'>Property:</h5> 225 * <ul> 226 * <li><b>Name:</b> <js>"XmlSerializer.defaultNamespace.s"</js> 227 * <li><b>Data type:</b> <code>String</code> ({@link Namespace}) 228 * <li><b>Default:</b> <js>"juneau: http://www.apache.org/2013/Juneau"</js> 229 * <li><b>Session property:</b> <jk>false</jk> 230 * <li><b>Methods:</b> 231 * <ul> 232 * <li class='jm'>{@link XmlSerializerBuilder#defaultNamespace(String)} 233 * </ul> 234 * </ul> 235 * 236 * <h5 class='section'>Description:</h5> 237 * <p> 238 * Specifies the default namespace URI for this document. 239 * 240 * <h5 class='section'>See Also:</h5> 241 * <ul> 242 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 243 * </ul> 244 */ 245 public static final String XML_defaultNamespace = PREFIX + "defaultNamespace.s"; 246 247 /** 248 * Configuration property: Enable support for XML namespaces. 249 * 250 * <h5 class='section'>Property:</h5> 251 * <ul> 252 * <li><b>Name:</b> <js>"XmlSerializer.enableNamespaces.b"</js> 253 * <li><b>Data type:</b> <code>Boolean</code> 254 * <li><b>Default:</b> <jk>false</jk> 255 * <li><b>Session property:</b> <jk>false</jk> 256 * <li><b>Methods:</b> 257 * <ul> 258 * <li class='jm'>{@link XmlSerializerBuilder#enableNamespaces(boolean)} 259 * </ul> 260 * </ul> 261 * 262 * <h5 class='section'>Description:</h5> 263 * <p> 264 * If not enabled, XML output will not contain any namespaces regardless of any other settings. 265 * 266 * <h5 class='section'>See Also:</h5> 267 * <ul> 268 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 269 * </ul> 270 */ 271 public static final String XML_enableNamespaces = PREFIX + "enableNamespaces.b"; 272 273 /** 274 * Configuration property: Default namespaces. 275 * 276 * <h5 class='section'>Property:</h5> 277 * <ul> 278 * <li><b>Name:</b> <js>"XmlSerializer.namespaces.ls"</js> 279 * <li><b>Data type:</b> <code>Set<String></code> ({@link Namespace}) 280 * <li><b>Default:</b> empty set 281 * <li><b>Session property:</b> <jk>false</jk> 282 * <li><b>Methods:</b> 283 * <ul> 284 * <li class='jm'>{@link XmlSerializerBuilder#defaultNamespace(String)} 285 * </ul> 286 * </ul> 287 * 288 * <h5 class='section'>Description:</h5> 289 * <p> 290 * The default list of namespaces associated with this serializer. 291 * 292 * <h5 class='section'>See Also:</h5> 293 * <ul> 294 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 295 * </ul> 296 */ 297 public static final String XML_namespaces = PREFIX + "namespaces.ls"; 298 299 /** 300 * Configuration property: XMLSchema namespace. 301 * 302 * <h5 class='section'>Property:</h5> 303 * <ul> 304 * <li><b>Name:</b> <js>"XmlSerializer.xsNamespace.s"</js> 305 * <li><b>Data type:</b> <code>String</code> ({@link Namespace}) 306 * <li><b>Default:</b> <js>"xs: http://www.w3.org/2001/XMLSchema"</js> 307 * <li><b>Session property:</b> <jk>false</jk> 308 * <li><b>Methods:</b> 309 * <ul> 310 * <li class='jm'>{@link XmlSerializerBuilder#xsNamespace(Namespace)} 311 * </ul> 312 * </ul> 313 * 314 * <h5 class='section'>Description:</h5> 315 * <p> 316 * Specifies the namespace for the <code>XMLSchema</code> namespace, used by the schema generated by the 317 * {@link XmlSchemaSerializer} class. 318 * 319 * <h5 class='section'>See Also:</h5> 320 * <ul> 321 * <li class='link'>{@doc juneau-marshall.XmlDetails.Namespaces} 322 * </ul> 323 */ 324 public static final String XML_xsNamespace = PREFIX + "xsNamespace.s"; 325 326 327 //------------------------------------------------------------------------------------------------------------------- 328 // Predefined instances 329 //------------------------------------------------------------------------------------------------------------------- 330 331 /** Default serializer without namespaces. */ 332 public static final XmlSerializer DEFAULT = new XmlSerializer(PropertyStore.DEFAULT); 333 334 /** Default serializer without namespaces, with single quotes. */ 335 public static final XmlSerializer DEFAULT_SQ = new Sq(PropertyStore.DEFAULT); 336 337 /** Default serializer without namespaces, with single quotes, whitespace added. */ 338 public static final XmlSerializer DEFAULT_SQ_READABLE = new SqReadable(PropertyStore.DEFAULT); 339 340 /** Default serializer, all default settings. */ 341 public static final XmlSerializer DEFAULT_NS = new Ns(PropertyStore.DEFAULT); 342 343 /** Default serializer, single quotes. */ 344 public static final XmlSerializer DEFAULT_NS_SQ = new NsSq(PropertyStore.DEFAULT); 345 346 /** Default serializer, single quotes, whitespace added. */ 347 public static final XmlSerializer DEFAULT_NS_SQ_READABLE = new NsSqReadable(PropertyStore.DEFAULT); 348 349 350 //------------------------------------------------------------------------------------------------------------------- 351 // Predefined subclasses 352 //------------------------------------------------------------------------------------------------------------------- 353 354 /** Default serializer, single quotes. */ 355 public static class Sq extends XmlSerializer { 356 357 /** 358 * Constructor. 359 * 360 * @param ps The property store containing all the settings for this object. 361 */ 362 public Sq(PropertyStore ps) { 363 super( 364 ps.builder() 365 .set(WSERIALIZER_quoteChar, '\'') 366 .build() 367 ); 368 } 369 } 370 371 /** Default serializer, single quotes, whitespace added. */ 372 public static class SqReadable extends XmlSerializer { 373 374 /** 375 * Constructor. 376 * 377 * @param ps The property store containing all the settings for this object. 378 */ 379 public SqReadable(PropertyStore ps) { 380 super( 381 ps.builder() 382 .set(WSERIALIZER_quoteChar, '\'') 383 .set(SERIALIZER_useWhitespace, true) 384 .build() 385 ); 386 } 387 } 388 389 /** Default serializer without namespaces. */ 390 public static class Ns extends XmlSerializer { 391 392 /** 393 * Constructor. 394 * 395 * @param ps The property store containing all the settings for this object. 396 */ 397 public Ns(PropertyStore ps) { 398 super( 399 ps.builder() 400 .set(XML_enableNamespaces, true) 401 .build(), 402 "text/xml", 403 "text/xml+simple" 404 ); 405 } 406 } 407 408 /** Default serializer without namespaces, single quotes. */ 409 public static class NsSq extends XmlSerializer { 410 411 /** 412 * Constructor. 413 * 414 * @param ps The property store containing all the settings for this object. 415 */ 416 public NsSq(PropertyStore ps) { 417 super( 418 ps.builder() 419 .set(XML_enableNamespaces, true) 420 .set(WSERIALIZER_quoteChar, '\'') 421 .build() 422 ); 423 } 424 } 425 426 /** Default serializer without namespaces, single quotes, with whitespace. */ 427 public static class NsSqReadable extends XmlSerializer { 428 429 /** 430 * Constructor. 431 * 432 * @param ps The property store containing all the settings for this object. 433 */ 434 public NsSqReadable(PropertyStore ps) { 435 super( 436 ps.builder() 437 .set(XML_enableNamespaces, true) 438 .set(WSERIALIZER_quoteChar, '\'') 439 .set(SERIALIZER_useWhitespace, true) 440 .build() 441 ); 442 } 443 } 444 445 @SuppressWarnings("javadoc") 446 protected static final Namespace 447 DEFAULT_JUNEAU_NAMESPACE = Namespace.create("juneau", "http://www.apache.org/2013/Juneau"), 448 DEFAULT_XS_NAMESPACE = Namespace.create("xs", "http://www.w3.org/2001/XMLSchema"); 449 450 //------------------------------------------------------------------------------------------------------------------- 451 // Instance 452 //------------------------------------------------------------------------------------------------------------------- 453 454 private final boolean 455 autoDetectNamespaces, 456 enableNamespaces, 457 addNamespaceUrlsToRoot, 458 addBeanTypes; 459 private final Namespace defaultNamespace; 460 private final Namespace 461 xsNamespace; 462 private final Namespace[] namespaces; 463 464 private volatile XmlSchemaSerializer schemaSerializer; 465 466 /** 467 * Constructor. 468 * 469 * @param ps 470 * The property store containing all the settings for this object. 471 */ 472 public XmlSerializer(PropertyStore ps) { 473 this(ps, "text/xml", null); 474 } 475 476 /** 477 * Constructor. 478 * 479 * @param ps 480 * The property store containing all the settings for this object. 481 * @param produces 482 * The media type that this serializer produces. 483 * @param accept 484 * The accept media types that the serializer can handle. 485 * <p> 486 * Can contain meta-characters per the <code>media-type</code> specification of {@doc RFC2616.section14.1} 487 * <p> 488 * If empty, then assumes the only media type supported is <code>produces</code>. 489 * <p> 490 * For example, if this serializer produces <js>"application/json"</js> but should handle media types of 491 * <js>"application/json"</js> and <js>"text/json"</js>, then the arguments should be: 492 * <p class='bcode w800'> 493 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"application/json,text/json"</js>); 494 * </p> 495 * <br>...or... 496 * <p class='bcode w800'> 497 * <jk>super</jk>(ps, <js>"application/json"</js>, <js>"*​/json"</js>); 498 * </p> 499 * <p> 500 * The accept value can also contain q-values. 501 */ 502 public XmlSerializer(PropertyStore ps, String produces, String accept) { 503 super(ps, produces, accept); 504 autoDetectNamespaces = getBooleanProperty(XML_autoDetectNamespaces, true); 505 enableNamespaces = getBooleanProperty(XML_enableNamespaces, false); 506 addNamespaceUrlsToRoot = getBooleanProperty(XML_addNamespaceUrisToRoot, false); 507 defaultNamespace = getInstanceProperty(XML_defaultNamespace, Namespace.class, DEFAULT_JUNEAU_NAMESPACE); 508 addBeanTypes = getBooleanProperty(XML_addBeanTypes, getBooleanProperty(SERIALIZER_addBeanTypes, false)); 509 xsNamespace = getInstanceProperty(XML_xsNamespace, Namespace.class, DEFAULT_XS_NAMESPACE); 510 namespaces = getInstanceArrayProperty(XML_namespaces, Namespace.class, new Namespace[0]); 511 } 512 513 @Override /* Context */ 514 public XmlSerializerBuilder builder() { 515 return new XmlSerializerBuilder(getPropertyStore()); 516 } 517 518 /** 519 * Instantiates a new clean-slate {@link XmlSerializerBuilder} object. 520 * 521 * <p> 522 * This is equivalent to simply calling <code><jk>new</jk> XmlSerializerBuilder()</code>. 523 * 524 * <p> 525 * Note that this method creates a builder initialized to all default settings, whereas {@link #builder()} copies 526 * the settings of the object called on. 527 * 528 * @return A new {@link XmlSerializerBuilder} object. 529 */ 530 public static XmlSerializerBuilder create() { 531 return new XmlSerializerBuilder(); 532 } 533 534 /** 535 * Returns the schema serializer based on the settings of this serializer. 536 * @return The schema serializer. 537 */ 538 public XmlSerializer getSchemaSerializer() { 539 if (schemaSerializer == null) 540 schemaSerializer = builder().build(XmlSchemaSerializer.class); 541 return schemaSerializer; 542 } 543 544 @Override /* Serializer */ 545 public WriterSerializerSession createSession(SerializerSessionArgs args) { 546 return new XmlSerializerSession(this, args); 547 } 548 549 //----------------------------------------------------------------------------------------------------------------- 550 // Properties 551 //----------------------------------------------------------------------------------------------------------------- 552 553 /** 554 * Configuration property: Auto-detect namespace usage. 555 * 556 * @see #XML_autoDetectNamespaces 557 * @return 558 * <jk>true</jk> if namespace usage is detected before serialization. 559 */ 560 protected final boolean isAutoDetectNamespaces() { 561 return autoDetectNamespaces; 562 } 563 564 /** 565 * Configuration property: Enable support for XML namespaces. 566 * 567 * @see #XML_enableNamespaces 568 * @return 569 * <jk>false</jk> if XML output will not contain any namespaces regardless of any other settings. 570 */ 571 protected final boolean isEnableNamespaces() { 572 return enableNamespaces; 573 } 574 575 /** 576 * Configuration property: Add namespace URLs to the root element. 577 * 578 * @see #XML_addNamespaceUrisToRoot 579 * @return 580 * <jk>true</jk> if {@code xmlns:x} attributes are added to the root element for the default and all mapped namespaces. 581 */ 582 protected final boolean isAddNamespaceUrlsToRoot() { 583 return addNamespaceUrlsToRoot; 584 } 585 586 /** 587 * Configuration property: Add <js>"_type"</js> properties when needed. 588 * 589 * @see #XML_addBeanTypes 590 * @return 591 * <jk>true</jk> if<js>"_type"</js> properties will be added to beans if their type cannot be inferred 592 * through reflection. 593 */ 594 @Override 595 protected boolean isAddBeanTypes() { 596 return addBeanTypes; 597 } 598 599 /** 600 * Configuration property: Default namespace. 601 * 602 * @see #XML_defaultNamespace 603 * @return 604 * The default namespace URI for this document. 605 */ 606 protected final Namespace getDefaultNamespace() { 607 return defaultNamespace; 608 } 609 610 /** 611 * Configuration property: XMLSchema namespace. 612 * 613 * @see #XML_xsNamespace 614 * @return 615 * The namespace for the <code>XMLSchema</code> namespace, used by the schema generated by the 616 * {@link XmlSchemaSerializer} class. 617 */ 618 protected final Namespace getXsNamespace() { 619 return xsNamespace; 620 } 621 622 /** 623 * Configuration property: Default namespaces. 624 * 625 * @see #XML_namespaces 626 * @return 627 * The default list of namespaces associated with this serializer. 628 */ 629 protected final Namespace[] getNamespaces() { 630 return namespaces; 631 } 632 633 @Override /* Context */ 634 public ObjectMap asMap() { 635 return super.asMap() 636 .append("XmlSerializer", new ObjectMap() 637 .append("autoDetectNamespaces", autoDetectNamespaces) 638 .append("enableNamespaces", enableNamespaces) 639 .append("addNamespaceUrlsToRoot", addNamespaceUrlsToRoot) 640 .append("defaultNamespace", defaultNamespace) 641 .append("xsNamespace", xsNamespace) 642 .append("namespaces", namespaces) 643 .append("addBeanTypes", addBeanTypes) 644 ); 645 } 646}