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 static org.apache.juneau.collections.JsonMap.*; 016import static org.apache.juneau.internal.CollectionUtils.*; 017 018import java.lang.annotation.*; 019import java.lang.reflect.*; 020import java.nio.charset.*; 021import java.util.*; 022import java.util.concurrent.*; 023 024import org.apache.juneau.*; 025import org.apache.juneau.collections.*; 026import org.apache.juneau.internal.*; 027import org.apache.juneau.json.*; 028import org.apache.juneau.serializer.*; 029import org.apache.juneau.utils.*; 030 031/** 032 * Serializes POJO models to XML. 033 * 034 * <h5 class='topic'>Media types</h5> 035 * <p> 036 * Handles <c>Accept</c> types: <bc>text/xml</bc> 037 * <p> 038 * Produces <c>Content-Type</c> types: <bc>text/xml</bc> 039 * 040 * <h5 class='topic'>Description</h5> 041 * <p> 042 * See the {@link JsonSerializer} class for details on how Java models map to JSON. 043 * 044 * <p> 045 * For example, the following JSON... 046 * <p class='bjson'> 047 * { 048 * name:<js>'John Smith'</js>, 049 * address: { 050 * streetAddress: <js>'21 2nd Street'</js>, 051 * city: <js>'New York'</js>, 052 * state: <js>'NY'</js>, 053 * postalCode: <js>10021</js> 054 * }, 055 * phoneNumbers: [ 056 * <js>'212 555-1111'</js>, 057 * <js>'212 555-2222'</js> 058 * ], 059 * additionalInfo: <jk>null</jk>, 060 * remote: <jk>false</jk>, 061 * height: <js>62.4</js>, 062 * <js>'fico score'</js>: <js>' > 640'</js> 063 * } 064 * <p> 065 * ...maps to the following XML using the default serializer... 066 * <p class='bxml'> 067 * <xt><object></xt> 068 * <xt><name></xt>John Smith<xt></name></xt> 069 * <xt><address></xt> 070 * <xt><streetAddress></xt>21 2nd Street<xt></streetAddress></xt> 071 * <xt><city></xt>New York<xt></city></xt> 072 * <xt><state></xt>NY<xt></state></xt> 073 * <xt><postalCode></xt>10021<xt></postalCode></xt> 074 * <xt></address></xt> 075 * <xt><phoneNumbers></xt> 076 * <xt><string></xt>212 555-1111<xt></string></xt> 077 * <xt><string></xt>212 555-2222<xt></string></xt> 078 * <xt></phoneNumbers></xt> 079 * <xt><additionalInfo</xt> <xa>_type</xa>=<xs>'null'</xs><xt>></additionalInfo></xt> 080 * <xt><remote></xt>false<xt></remote></xt> 081 * <xt><height></xt>62.4<xt></height></xt> 082 * <xt><fico_x0020_score></xt> &gt; 640<xt></fico_x0020_score></xt> 083 * <xt></object></xt> 084 * 085 * <p> 086 * An additional "add-json-properties" mode is also provided to prevent loss of JSON data types... 087 * <p class='bxml'> 088 * <xt><object></xt> 089 * <xt><name</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>John Smith<xt></name></xt> 090 * <xt><address</xt> <xa>_type</xa>=<xs>'object'</xs><xt>></xt> 091 * <xt><streetAddress</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>21 2nd Street<xt></streetAddress></xt> 092 * <xt><city</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>New York<xt></city></xt> 093 * <xt><state</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt>NY<xt></state></xt> 094 * <xt><postalCode</xt> <xa>_type</xa>=<xs>'number'</xs><xt>></xt>10021<xt></postalCode></xt> 095 * <xt></address></xt> 096 * <xt><phoneNumbers</xt> <xa>_type</xa>=<xs>'array'</xs><xt>></xt> 097 * <xt><string></xt>212 555-1111<xt></string></xt> 098 * <xt><string></xt>212 555-2222<xt></string></xt> 099 * <xt></phoneNumbers></xt> 100 * <xt><additionalInfo</xt> <xa>_type</xa>=<xs>'null'</xs><xt>></additionalInfo></xt> 101 * <xt><remote</xt> <xa>_type</xa>=<xs>'boolean'</xs><xt>></xt>false<xt></remote></xt> 102 * <xt><height</xt> <xa>_type</xa>=<xs>'number'</xs><xt>></xt>62.4<xt></height></xt> 103 * <xt><fico_x0020_score</xt> <xa>_type</xa>=<xs>'string'</xs><xt>></xt> &gt; 640<xt></fico_x0020_score></xt> 104 * <xt></object></xt> 105 * </p> 106 * 107 * <p> 108 * This serializer provides several serialization options. 109 * Typically, one of the predefined <jsf>DEFAULT</jsf> serializers will be sufficient. 110 * However, custom serializers can be constructed to fine-tune behavior. 111 * 112 * <p> 113 * If an attribute name contains any non-valid XML element characters, they will be escaped using standard 114 * {@code _x####_} notation. 115 * 116 * <h5 class='topic'>Behavior-specific subclasses</h5> 117 * <p> 118 * The following direct subclasses are provided for convenience: 119 * <ul> 120 * <li>{@link Sq} - Default serializer, single quotes. 121 * <li>{@link SqReadable} - Default serializer, single quotes, whitespace added. 122 * </ul> 123 * 124 * <h5 class='section'>Notes:</h5><ul> 125 * <li class='note'>This class is thread safe and reusable. 126 * </ul> 127 * 128 * <h5 class='section'>See Also:</h5><ul> 129 * <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlDetails">XML Details</a> 130 131 * </ul> 132 */ 133public class XmlSerializer extends WriterSerializer implements XmlMetaProvider { 134 135 //------------------------------------------------------------------------------------------------------------------- 136 // Static 137 //------------------------------------------------------------------------------------------------------------------- 138 139 private static final Namespace[] EMPTY_NAMESPACE_ARRAY = {}; 140 141 /** Default serializer without namespaces. */ 142 public static final XmlSerializer DEFAULT = new XmlSerializer(create()); 143 144 /** Default serializer without namespaces, with single quotes. */ 145 public static final XmlSerializer DEFAULT_SQ = new Sq(create()); 146 147 /** Default serializer without namespaces, with single quotes, whitespace added. */ 148 public static final XmlSerializer DEFAULT_SQ_READABLE = new SqReadable(create()); 149 150 /** Default serializer, all default settings. */ 151 public static final XmlSerializer DEFAULT_NS = new Ns(create()); 152 153 /** Default serializer, single quotes. */ 154 public static final XmlSerializer DEFAULT_NS_SQ = new NsSq(create()); 155 156 /** Default serializer, single quotes, whitespace added. */ 157 public static final XmlSerializer DEFAULT_NS_SQ_READABLE = new NsSqReadable(create()); 158 159 /** 160 * Creates a new builder for this object. 161 * 162 * @return A new builder. 163 */ 164 public static Builder create() { 165 return new Builder(); 166 } 167 168 //------------------------------------------------------------------------------------------------------------------- 169 // Static subclasses 170 //------------------------------------------------------------------------------------------------------------------- 171 172 /** Default serializer, single quotes. */ 173 public static class Sq extends XmlSerializer { 174 175 /** 176 * Constructor. 177 * 178 * @param builder The builder for this object. 179 */ 180 public Sq(Builder builder) { 181 super(builder.quoteChar('\'')); 182 } 183 } 184 185 /** Default serializer, single quotes, whitespace added. */ 186 public static class SqReadable extends XmlSerializer { 187 188 /** 189 * Constructor. 190 * 191 * @param builder The builder for this object. 192 */ 193 public SqReadable(Builder builder) { 194 super(builder.quoteChar('\'').useWhitespace()); 195 } 196 } 197 198 /** Default serializer without namespaces. */ 199 public static class Ns extends XmlSerializer { 200 201 /** 202 * Constructor. 203 * 204 * @param builder The builder for this object. 205 */ 206 public Ns(Builder builder) { 207 super(builder.enableNamespaces()); 208 } 209 } 210 211 /** Default serializer without namespaces, single quotes. */ 212 public static class NsSq extends XmlSerializer { 213 214 /** 215 * Constructor. 216 * 217 * @param builder The builder for this object. 218 */ 219 public NsSq(Builder builder) { 220 super(builder.enableNamespaces().quoteChar('\'')); 221 } 222 } 223 224 /** Default serializer without namespaces, single quotes, with whitespace. */ 225 public static class NsSqReadable extends XmlSerializer { 226 227 /** 228 * Constructor. 229 * 230 * @param builder The builder for this object. 231 */ 232 public NsSqReadable(Builder builder) { 233 super(builder.enableNamespaces().quoteChar('\'').useWhitespace()); 234 } 235 } 236 237 @SuppressWarnings("javadoc") 238 protected static final Namespace 239 DEFAULT_JUNEAU_NAMESPACE = Namespace.of("juneau", "http://www.apache.org/2013/Juneau"), 240 DEFAULT_XS_NAMESPACE = Namespace.of("xs", "http://www.w3.org/2001/XMLSchema"); 241 242 //------------------------------------------------------------------------------------------------------------------- 243 // Builder 244 //------------------------------------------------------------------------------------------------------------------- 245 246 /** 247 * Builder class. 248 */ 249 @FluentSetters 250 public static class Builder extends WriterSerializer.Builder { 251 252 private static final Cache<HashKey,XmlSerializer> CACHE = Cache.of(HashKey.class, XmlSerializer.class).build(); 253 254 boolean addBeanTypesXml, addNamespaceUrisToRoot, disableAutoDetectNamespaces, enableNamespaces; 255 Namespace defaultNamespace; 256 List<Namespace> namespaces; 257 258 /** 259 * Constructor, default settings. 260 */ 261 protected Builder() { 262 produces("text/xml"); 263 addBeanTypesXml = env("XmlSerializer.addBeanTypes", false); 264 addNamespaceUrisToRoot = env("XmlSerializer.addNamespaceUrisToRoot", false); 265 disableAutoDetectNamespaces = env("XmlSerializer.disableAutoDetectNamespaces", false); 266 enableNamespaces = env("XmlSerializer.enableNamespaces", false); 267 defaultNamespace = null; 268 namespaces = null; 269 270 } 271 272 /** 273 * Copy constructor. 274 * 275 * @param copyFrom The bean to copy from. 276 */ 277 protected Builder(XmlSerializer copyFrom) { 278 super(copyFrom); 279 addBeanTypesXml = copyFrom.addBeanTypesXml; 280 addNamespaceUrisToRoot = copyFrom.addNamespaceUrlsToRoot; 281 disableAutoDetectNamespaces = ! copyFrom.autoDetectNamespaces; 282 enableNamespaces = copyFrom.enableNamespaces; 283 defaultNamespace = copyFrom.defaultNamespace; 284 namespaces = copyFrom.namespaces.length == 0 ? null : list(copyFrom.namespaces); 285 } 286 287 /** 288 * Copy constructor. 289 * 290 * @param copyFrom The builder to copy from. 291 */ 292 protected Builder(Builder copyFrom) { 293 super(copyFrom); 294 addBeanTypesXml = copyFrom.addBeanTypesXml; 295 addNamespaceUrisToRoot = copyFrom.addNamespaceUrisToRoot; 296 disableAutoDetectNamespaces = copyFrom.disableAutoDetectNamespaces; 297 enableNamespaces = copyFrom.enableNamespaces; 298 defaultNamespace = copyFrom.defaultNamespace; 299 namespaces = copyOf(copyFrom.namespaces); 300 } 301 302 @Override /* Context.Builder */ 303 public Builder copy() { 304 return new Builder(this); 305 } 306 307 @Override /* Context.Builder */ 308 public XmlSerializer build() { 309 return cache(CACHE).build(XmlSerializer.class); 310 } 311 312 @Override /* Context.Builder */ 313 public HashKey hashKey() { 314 return HashKey.of( 315 super.hashKey(), 316 addBeanTypesXml, 317 addNamespaceUrisToRoot, 318 disableAutoDetectNamespaces, 319 enableNamespaces, 320 defaultNamespace, 321 namespaces 322 ); 323 } 324 325 //----------------------------------------------------------------------------------------------------------------- 326 // Properties 327 //----------------------------------------------------------------------------------------------------------------- 328 329 /** 330 * Add <js>"_type"</js> properties when needed. 331 * 332 * <p> 333 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 334 * through reflection. 335 * 336 * <p> 337 * When present, this value overrides the {@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()} setting and is 338 * provided to customize the behavior of specific serializers in a {@link SerializerSet}. 339 * 340 * @return This object. 341 */ 342 @FluentSetter 343 public Builder addBeanTypesXml() { 344 return addBeanTypesXml(true); 345 } 346 347 /** 348 * Same as {@link #addBeanTypesXml()} but allows you to explicitly specify the value. 349 * 350 * @param value The value for this setting. 351 * @return This object. 352 */ 353 @FluentSetter 354 public Builder addBeanTypesXml(boolean value) { 355 addBeanTypesXml = value; 356 return this; 357 } 358 359 /** 360 * Add namespace URLs to the root element. 361 * 362 * <p> 363 * Use this setting to add {@code xmlns:x} attributes to the root element for the default and all mapped namespaces. 364 * 365 * <p> 366 * This setting is ignored if {@link #enableNamespaces()} is not enabled. 367 * 368 * <h5 class='section'>See Also:</h5><ul> 369 * <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlNamespaces">Namespaces</a> 370 * </ul> 371 * 372 * @return This object. 373 */ 374 @FluentSetter 375 public Builder addNamespaceUrisToRoot() { 376 return addNamespaceUrisToRoot(true); 377 } 378 379 /** 380 * Same as {@link #addNamespaceUrisToRoot()} but allows you to explicitly specify the value. 381 * 382 * @param value The value for this setting. 383 * @return This object. 384 */ 385 @FluentSetter 386 public Builder addNamespaceUrisToRoot(boolean value) { 387 addNamespaceUrisToRoot = value; 388 return this; 389 } 390 391 /** 392 * Don't auto-detect namespace usage. 393 * 394 * <p> 395 * Don't detect namespace usage before serialization. 396 * 397 * <p> 398 * Used in conjunction with {@link Builder#addNamespaceUrisToRoot()} to reduce the list of namespace URLs appended to the 399 * root element to only those that will be used in the resulting document. 400 * 401 * <p> 402 * If disabled, then the data structure will first be crawled looking for namespaces that will be encountered before 403 * the root element is serialized. 404 * 405 * <p> 406 * This setting is ignored if {@link Builder#enableNamespaces()} is not enabled. 407 * 408 * <h5 class='section'>Notes:</h5><ul> 409 * <li class='note'> 410 * Auto-detection of namespaces can be costly performance-wise. 411 * <br>In high-performance environments, it's recommended that namespace detection be 412 * disabled, and that namespaces be manually defined through the {@link Builder#namespaces(Namespace...)} property. 413 * </ul> 414 * 415 * <h5 class='section'>See Also:</h5><ul> 416 * <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlNamespaces">Namespaces</a> 417 * </ul> 418 * 419 * @return This object. 420 */ 421 @FluentSetter 422 public Builder disableAutoDetectNamespaces() { 423 return disableAutoDetectNamespaces(true); 424 } 425 426 /** 427 * Same as {@link #disableAutoDetectNamespaces()} but allows you to explicitly specify the value. 428 * 429 * @param value The value for this setting. 430 * @return This object. 431 */ 432 @FluentSetter 433 public Builder disableAutoDetectNamespaces(boolean value) { 434 disableAutoDetectNamespaces = value; 435 return this; 436 } 437 438 /** 439 * Default namespace. 440 * 441 * <p> 442 * Specifies the default namespace URI for this document. 443 * 444 * <h5 class='section'>See Also:</h5><ul> 445 * <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlNamespaces">Namespaces</a> 446 * </ul> 447 * 448 * @param value 449 * The new value for this property. 450 * <br>The default is <js>"juneau: http://www.apache.org/2013/Juneau"</js>. 451 * @return This object. 452 */ 453 @FluentSetter 454 public Builder defaultNamespace(Namespace value) { 455 defaultNamespace = value; 456 return this; 457 } 458 459 /** 460 * Enable support for XML namespaces. 461 * 462 * <p> 463 * If not enabled, XML output will not contain any namespaces regardless of any other settings. 464 * 465 * <h5 class='section'>See Also:</h5><ul> 466 * <li class='link'><a class="doclink" href="../../../../index.html#jm.XmlNamespaces">Namespaces</a> 467 * </ul> 468 * 469 * @return This object. 470 */ 471 @FluentSetter 472 public Builder enableNamespaces() { 473 return enableNamespaces(true); 474 } 475 476 /** 477 * Same as {@link #enableNamespaces()} but allows you to explicitly specify the value. 478 * 479 * @param value The value for this setting. 480 * @return This object. 481 */ 482 @FluentSetter 483 public Builder enableNamespaces(boolean value) { 484 enableNamespaces = value; 485 return this; 486 } 487 488 /** 489 * Enable support for XML namespaces. 490 * 491 * <p> 492 * Shortcut for calling <code>enableNamespaces(<jk>true</jk>)</code>. 493 * 494 * @return This object. 495 */ 496 @FluentSetter 497 public Builder ns() { 498 return enableNamespaces(); 499 } 500 501 /** 502 * Default namespaces. 503 * 504 * <p> 505 * The default list of namespaces associated with this serializer. 506 * 507 * @param values The new value for this property. 508 * @return This object. 509 */ 510 @FluentSetter 511 public Builder namespaces(Namespace...values) { 512 namespaces = addAll(namespaces, values); 513 return this; 514 } 515 516 // <FluentSetters> 517 518 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 519 public Builder annotations(Annotation...values) { 520 super.annotations(values); 521 return this; 522 } 523 524 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 525 public Builder apply(AnnotationWorkList work) { 526 super.apply(work); 527 return this; 528 } 529 530 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 531 public Builder applyAnnotations(java.lang.Class<?>...fromClasses) { 532 super.applyAnnotations(fromClasses); 533 return this; 534 } 535 536 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 537 public Builder applyAnnotations(Method...fromMethods) { 538 super.applyAnnotations(fromMethods); 539 return this; 540 } 541 542 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 543 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 544 super.cache(value); 545 return this; 546 } 547 548 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 549 public Builder debug() { 550 super.debug(); 551 return this; 552 } 553 554 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 555 public Builder debug(boolean value) { 556 super.debug(value); 557 return this; 558 } 559 560 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 561 public Builder impl(Context value) { 562 super.impl(value); 563 return this; 564 } 565 566 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 567 public Builder type(Class<? extends org.apache.juneau.Context> value) { 568 super.type(value); 569 return this; 570 } 571 572 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 573 public Builder beanClassVisibility(Visibility value) { 574 super.beanClassVisibility(value); 575 return this; 576 } 577 578 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 579 public Builder beanConstructorVisibility(Visibility value) { 580 super.beanConstructorVisibility(value); 581 return this; 582 } 583 584 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 585 public Builder beanContext(BeanContext value) { 586 super.beanContext(value); 587 return this; 588 } 589 590 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 591 public Builder beanContext(BeanContext.Builder value) { 592 super.beanContext(value); 593 return this; 594 } 595 596 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 597 public Builder beanDictionary(java.lang.Class<?>...values) { 598 super.beanDictionary(values); 599 return this; 600 } 601 602 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 603 public Builder beanFieldVisibility(Visibility value) { 604 super.beanFieldVisibility(value); 605 return this; 606 } 607 608 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 609 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 610 super.beanInterceptor(on, value); 611 return this; 612 } 613 614 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 615 public Builder beanMapPutReturnsOldValue() { 616 super.beanMapPutReturnsOldValue(); 617 return this; 618 } 619 620 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 621 public Builder beanMethodVisibility(Visibility value) { 622 super.beanMethodVisibility(value); 623 return this; 624 } 625 626 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 627 public Builder beanProperties(Map<String,Object> values) { 628 super.beanProperties(values); 629 return this; 630 } 631 632 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 633 public Builder beanProperties(Class<?> beanClass, String properties) { 634 super.beanProperties(beanClass, properties); 635 return this; 636 } 637 638 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 639 public Builder beanProperties(String beanClassName, String properties) { 640 super.beanProperties(beanClassName, properties); 641 return this; 642 } 643 644 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 645 public Builder beanPropertiesExcludes(Map<String,Object> values) { 646 super.beanPropertiesExcludes(values); 647 return this; 648 } 649 650 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 651 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 652 super.beanPropertiesExcludes(beanClass, properties); 653 return this; 654 } 655 656 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 657 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 658 super.beanPropertiesExcludes(beanClassName, properties); 659 return this; 660 } 661 662 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 663 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 664 super.beanPropertiesReadOnly(values); 665 return this; 666 } 667 668 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 669 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 670 super.beanPropertiesReadOnly(beanClass, properties); 671 return this; 672 } 673 674 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 675 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 676 super.beanPropertiesReadOnly(beanClassName, properties); 677 return this; 678 } 679 680 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 681 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 682 super.beanPropertiesWriteOnly(values); 683 return this; 684 } 685 686 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 687 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 688 super.beanPropertiesWriteOnly(beanClass, properties); 689 return this; 690 } 691 692 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 693 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 694 super.beanPropertiesWriteOnly(beanClassName, properties); 695 return this; 696 } 697 698 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 699 public Builder beansRequireDefaultConstructor() { 700 super.beansRequireDefaultConstructor(); 701 return this; 702 } 703 704 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 705 public Builder beansRequireSerializable() { 706 super.beansRequireSerializable(); 707 return this; 708 } 709 710 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 711 public Builder beansRequireSettersForGetters() { 712 super.beansRequireSettersForGetters(); 713 return this; 714 } 715 716 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 717 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 718 super.dictionaryOn(on, values); 719 return this; 720 } 721 722 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 723 public Builder disableBeansRequireSomeProperties() { 724 super.disableBeansRequireSomeProperties(); 725 return this; 726 } 727 728 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 729 public Builder disableIgnoreMissingSetters() { 730 super.disableIgnoreMissingSetters(); 731 return this; 732 } 733 734 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 735 public Builder disableIgnoreTransientFields() { 736 super.disableIgnoreTransientFields(); 737 return this; 738 } 739 740 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 741 public Builder disableIgnoreUnknownNullBeanProperties() { 742 super.disableIgnoreUnknownNullBeanProperties(); 743 return this; 744 } 745 746 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 747 public Builder disableInterfaceProxies() { 748 super.disableInterfaceProxies(); 749 return this; 750 } 751 752 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 753 public <T> Builder example(Class<T> pojoClass, T o) { 754 super.example(pojoClass, o); 755 return this; 756 } 757 758 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 759 public <T> Builder example(Class<T> pojoClass, String json) { 760 super.example(pojoClass, json); 761 return this; 762 } 763 764 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 765 public Builder findFluentSetters() { 766 super.findFluentSetters(); 767 return this; 768 } 769 770 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 771 public Builder findFluentSetters(Class<?> on) { 772 super.findFluentSetters(on); 773 return this; 774 } 775 776 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 777 public Builder ignoreInvocationExceptionsOnGetters() { 778 super.ignoreInvocationExceptionsOnGetters(); 779 return this; 780 } 781 782 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 783 public Builder ignoreInvocationExceptionsOnSetters() { 784 super.ignoreInvocationExceptionsOnSetters(); 785 return this; 786 } 787 788 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 789 public Builder ignoreUnknownBeanProperties() { 790 super.ignoreUnknownBeanProperties(); 791 return this; 792 } 793 794 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 795 public Builder ignoreUnknownEnumValues() { 796 super.ignoreUnknownEnumValues(); 797 return this; 798 } 799 800 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 801 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 802 super.implClass(interfaceClass, implClass); 803 return this; 804 } 805 806 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 807 public Builder implClasses(Map<Class<?>,Class<?>> values) { 808 super.implClasses(values); 809 return this; 810 } 811 812 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 813 public Builder interfaceClass(Class<?> on, Class<?> value) { 814 super.interfaceClass(on, value); 815 return this; 816 } 817 818 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 819 public Builder interfaces(java.lang.Class<?>...value) { 820 super.interfaces(value); 821 return this; 822 } 823 824 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 825 public Builder locale(Locale value) { 826 super.locale(value); 827 return this; 828 } 829 830 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 831 public Builder mediaType(MediaType value) { 832 super.mediaType(value); 833 return this; 834 } 835 836 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 837 public Builder notBeanClasses(java.lang.Class<?>...values) { 838 super.notBeanClasses(values); 839 return this; 840 } 841 842 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 843 public Builder notBeanPackages(String...values) { 844 super.notBeanPackages(values); 845 return this; 846 } 847 848 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 849 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 850 super.propertyNamer(value); 851 return this; 852 } 853 854 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 855 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 856 super.propertyNamer(on, value); 857 return this; 858 } 859 860 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 861 public Builder sortProperties() { 862 super.sortProperties(); 863 return this; 864 } 865 866 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 867 public Builder sortProperties(java.lang.Class<?>...on) { 868 super.sortProperties(on); 869 return this; 870 } 871 872 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 873 public Builder stopClass(Class<?> on, Class<?> value) { 874 super.stopClass(on, value); 875 return this; 876 } 877 878 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 879 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 880 super.swap(normalClass, swappedClass, swapFunction); 881 return this; 882 } 883 884 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 885 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 886 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 887 return this; 888 } 889 890 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 891 public Builder swaps(java.lang.Class<?>...values) { 892 super.swaps(values); 893 return this; 894 } 895 896 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 897 public Builder timeZone(TimeZone value) { 898 super.timeZone(value); 899 return this; 900 } 901 902 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 903 public Builder typeName(Class<?> on, String value) { 904 super.typeName(on, value); 905 return this; 906 } 907 908 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 909 public Builder typePropertyName(String value) { 910 super.typePropertyName(value); 911 return this; 912 } 913 914 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 915 public Builder typePropertyName(Class<?> on, String value) { 916 super.typePropertyName(on, value); 917 return this; 918 } 919 920 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 921 public Builder useEnumNames() { 922 super.useEnumNames(); 923 return this; 924 } 925 926 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 927 public Builder useJavaBeanIntrospector() { 928 super.useJavaBeanIntrospector(); 929 return this; 930 } 931 932 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 933 public Builder detectRecursions() { 934 super.detectRecursions(); 935 return this; 936 } 937 938 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 939 public Builder detectRecursions(boolean value) { 940 super.detectRecursions(value); 941 return this; 942 } 943 944 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 945 public Builder ignoreRecursions() { 946 super.ignoreRecursions(); 947 return this; 948 } 949 950 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 951 public Builder ignoreRecursions(boolean value) { 952 super.ignoreRecursions(value); 953 return this; 954 } 955 956 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 957 public Builder initialDepth(int value) { 958 super.initialDepth(value); 959 return this; 960 } 961 962 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 963 public Builder maxDepth(int value) { 964 super.maxDepth(value); 965 return this; 966 } 967 968 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 969 public Builder accept(String value) { 970 super.accept(value); 971 return this; 972 } 973 974 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 975 public Builder addBeanTypes() { 976 super.addBeanTypes(); 977 return this; 978 } 979 980 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 981 public Builder addBeanTypes(boolean value) { 982 super.addBeanTypes(value); 983 return this; 984 } 985 986 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 987 public Builder addRootType() { 988 super.addRootType(); 989 return this; 990 } 991 992 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 993 public Builder addRootType(boolean value) { 994 super.addRootType(value); 995 return this; 996 } 997 998 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 999 public Builder keepNullProperties() { 1000 super.keepNullProperties(); 1001 return this; 1002 } 1003 1004 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1005 public Builder keepNullProperties(boolean value) { 1006 super.keepNullProperties(value); 1007 return this; 1008 } 1009 1010 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1011 public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) { 1012 super.listener(value); 1013 return this; 1014 } 1015 1016 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1017 public Builder produces(String value) { 1018 super.produces(value); 1019 return this; 1020 } 1021 1022 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1023 public Builder sortCollections() { 1024 super.sortCollections(); 1025 return this; 1026 } 1027 1028 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1029 public Builder sortCollections(boolean value) { 1030 super.sortCollections(value); 1031 return this; 1032 } 1033 1034 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1035 public Builder sortMaps() { 1036 super.sortMaps(); 1037 return this; 1038 } 1039 1040 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1041 public Builder sortMaps(boolean value) { 1042 super.sortMaps(value); 1043 return this; 1044 } 1045 1046 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1047 public Builder trimEmptyCollections() { 1048 super.trimEmptyCollections(); 1049 return this; 1050 } 1051 1052 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1053 public Builder trimEmptyCollections(boolean value) { 1054 super.trimEmptyCollections(value); 1055 return this; 1056 } 1057 1058 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1059 public Builder trimEmptyMaps() { 1060 super.trimEmptyMaps(); 1061 return this; 1062 } 1063 1064 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1065 public Builder trimEmptyMaps(boolean value) { 1066 super.trimEmptyMaps(value); 1067 return this; 1068 } 1069 1070 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1071 public Builder trimStrings() { 1072 super.trimStrings(); 1073 return this; 1074 } 1075 1076 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1077 public Builder trimStrings(boolean value) { 1078 super.trimStrings(value); 1079 return this; 1080 } 1081 1082 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1083 public Builder uriContext(UriContext value) { 1084 super.uriContext(value); 1085 return this; 1086 } 1087 1088 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1089 public Builder uriRelativity(UriRelativity value) { 1090 super.uriRelativity(value); 1091 return this; 1092 } 1093 1094 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1095 public Builder uriResolution(UriResolution value) { 1096 super.uriResolution(value); 1097 return this; 1098 } 1099 1100 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1101 public Builder fileCharset(Charset value) { 1102 super.fileCharset(value); 1103 return this; 1104 } 1105 1106 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1107 public Builder maxIndent(int value) { 1108 super.maxIndent(value); 1109 return this; 1110 } 1111 1112 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1113 public Builder quoteChar(char value) { 1114 super.quoteChar(value); 1115 return this; 1116 } 1117 1118 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1119 public Builder quoteCharOverride(char value) { 1120 super.quoteCharOverride(value); 1121 return this; 1122 } 1123 1124 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1125 public Builder sq() { 1126 super.sq(); 1127 return this; 1128 } 1129 1130 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1131 public Builder streamCharset(Charset value) { 1132 super.streamCharset(value); 1133 return this; 1134 } 1135 1136 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1137 public Builder useWhitespace() { 1138 super.useWhitespace(); 1139 return this; 1140 } 1141 1142 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1143 public Builder useWhitespace(boolean value) { 1144 super.useWhitespace(value); 1145 return this; 1146 } 1147 1148 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1149 public Builder ws() { 1150 super.ws(); 1151 return this; 1152 } 1153 1154 // </FluentSetters> 1155 } 1156 1157 //------------------------------------------------------------------------------------------------------------------- 1158 // Instance 1159 //------------------------------------------------------------------------------------------------------------------- 1160 1161 final boolean 1162 autoDetectNamespaces, 1163 enableNamespaces, 1164 addNamespaceUrlsToRoot, 1165 addBeanTypesXml; 1166 1167 final Namespace defaultNamespace; 1168 final Namespace[] namespaces; 1169 1170 private final boolean addBeanTypes; 1171 private final Map<ClassMeta<?>,XmlClassMeta> xmlClassMetas = new ConcurrentHashMap<>(); 1172 private final Map<BeanMeta<?>,XmlBeanMeta> xmlBeanMetas = new ConcurrentHashMap<>(); 1173 private final Map<BeanPropertyMeta,XmlBeanPropertyMeta> xmlBeanPropertyMetas = new ConcurrentHashMap<>(); 1174 1175 /** 1176 * Constructor. 1177 * 1178 * @param builder 1179 * The builder for this object. 1180 */ 1181 public XmlSerializer(Builder builder) { 1182 super(builder); 1183 autoDetectNamespaces = ! builder.disableAutoDetectNamespaces; 1184 enableNamespaces = builder.enableNamespaces; 1185 addNamespaceUrlsToRoot = builder.addNamespaceUrisToRoot; 1186 addBeanTypesXml = builder.addBeanTypesXml; 1187 defaultNamespace = builder.defaultNamespace != null ? builder.defaultNamespace : DEFAULT_JUNEAU_NAMESPACE; 1188 namespaces = builder.namespaces != null ? builder.namespaces.toArray(EMPTY_NAMESPACE_ARRAY) : EMPTY_NAMESPACE_ARRAY; 1189 addBeanTypes = addBeanTypesXml || super.isAddBeanTypes(); 1190 } 1191 1192 @Override /* Context */ 1193 public Builder copy() { 1194 return new Builder(this); 1195 } 1196 1197 @Override /* Context */ 1198 public XmlSerializerSession.Builder createSession() { 1199 return XmlSerializerSession.create(this); 1200 } 1201 1202 @Override /* Context */ 1203 public XmlSerializerSession getSession() { 1204 return createSession().build(); 1205 } 1206 1207 //----------------------------------------------------------------------------------------------------------------- 1208 // Extended metadata 1209 //----------------------------------------------------------------------------------------------------------------- 1210 1211 @Override /* XmlMetaProvider */ 1212 public XmlClassMeta getXmlClassMeta(ClassMeta<?> cm) { 1213 XmlClassMeta m = xmlClassMetas.get(cm); 1214 if (m == null) { 1215 m = new XmlClassMeta(cm, this); 1216 xmlClassMetas.put(cm, m); 1217 } 1218 return m; 1219 } 1220 1221 @Override /* XmlMetaProvider */ 1222 public XmlBeanMeta getXmlBeanMeta(BeanMeta<?> bm) { 1223 XmlBeanMeta m = xmlBeanMetas.get(bm); 1224 if (m == null) { 1225 m = new XmlBeanMeta(bm, this); 1226 xmlBeanMetas.put(bm, m); 1227 } 1228 return m; 1229 } 1230 1231 @Override /* XmlMetaProvider */ 1232 public XmlBeanPropertyMeta getXmlBeanPropertyMeta(BeanPropertyMeta bpm) { 1233 XmlBeanPropertyMeta m = xmlBeanPropertyMetas.get(bpm); 1234 if (m == null) { 1235 m = new XmlBeanPropertyMeta(bpm.getDelegateFor(), this); 1236 xmlBeanPropertyMetas.put(bpm, m); 1237 } 1238 return m; 1239 } 1240 1241 //----------------------------------------------------------------------------------------------------------------- 1242 // Properties 1243 //----------------------------------------------------------------------------------------------------------------- 1244 1245 /** 1246 * Add <js>"_type"</js> properties when needed. 1247 * 1248 * @see Builder#addBeanTypesXml() 1249 * @return 1250 * <jk>true</jk> if<js>"_type"</js> properties will be added to beans if their type cannot be inferred 1251 * through reflection. 1252 */ 1253 @Override 1254 protected boolean isAddBeanTypes() { 1255 return addBeanTypes; 1256 } 1257 1258 /** 1259 * Add namespace URLs to the root element. 1260 * 1261 * @see Builder#addNamespaceUrisToRoot() 1262 * @return 1263 * <jk>true</jk> if {@code xmlns:x} attributes are added to the root element for the default and all mapped namespaces. 1264 */ 1265 protected final boolean isAddNamespaceUrlsToRoot() { 1266 return addNamespaceUrlsToRoot; 1267 } 1268 1269 /** 1270 * Auto-detect namespace usage. 1271 * 1272 * @see Builder#disableAutoDetectNamespaces() 1273 * @return 1274 * <jk>true</jk> if namespace usage is detected before serialization. 1275 */ 1276 protected final boolean isAutoDetectNamespaces() { 1277 return autoDetectNamespaces; 1278 } 1279 1280 /** 1281 * Default namespace. 1282 * 1283 * @see Builder#defaultNamespace(Namespace) 1284 * @return 1285 * The default namespace URI for this document. 1286 */ 1287 protected final Namespace getDefaultNamespace() { 1288 return defaultNamespace; 1289 } 1290 1291 /** 1292 * Enable support for XML namespaces. 1293 * 1294 * @see Builder#enableNamespaces() 1295 * @return 1296 * <jk>false</jk> if XML output will not contain any namespaces regardless of any other settings. 1297 */ 1298 protected final boolean isEnableNamespaces() { 1299 return enableNamespaces; 1300 } 1301 1302 /** 1303 * Default namespaces. 1304 * 1305 * @see Builder#namespaces(Namespace...) 1306 * @return 1307 * The default list of namespaces associated with this serializer. 1308 */ 1309 protected final Namespace[] getNamespaces() { 1310 return namespaces; 1311 } 1312 1313 //----------------------------------------------------------------------------------------------------------------- 1314 // Other methods 1315 //----------------------------------------------------------------------------------------------------------------- 1316 1317 @Override /* Context */ 1318 protected JsonMap properties() { 1319 return filteredMap() 1320 .append("autoDetectNamespaces", autoDetectNamespaces) 1321 .append("enableNamespaces", enableNamespaces) 1322 .append("addNamespaceUrlsToRoot", addNamespaceUrlsToRoot) 1323 .append("defaultNamespace", defaultNamespace) 1324 .append("namespaces", namespaces) 1325 .append("addBeanTypes", addBeanTypes); 1326 } 1327}