Copybara import of the project: - 5ee21af6b81107bd2d5f5213046627797f12cf80 Initial contribution by Tomas Kraus <tomas.kraus@oracle.com> - 3b66378f37960c9dfed066fde37ee28b7ceb8e8d Version update for master branch by Tomas Kraus <tomas.kraus@oracle.com> - 83a246608d159fda33aa60e51d7d4e4a8209cec9 Project "groupId" changed to jakarta.xml.bind. (#66) by Roman Grigoriadi <bravehorsie@gmail.com> - fca5b11fa40c37fe17e817900cc18ae8e7a55cd5 Added --pinentry-mode loopback to GPG configurartion. (#69) by Tomáš Kraus <tomas.kraus@oracle.com> - d9a4a7ccc5378d8e25e4bab04a2b0baf069936d3 Parent updated to 1.0.2. Removed redundant release profil... by Tomáš Kraus <tomas.kraus@oracle.com> - 2526fdf59d9574fb8b9655efd8df047974da9778 Merge pull request #73 from Tomas-Kraus/master by Lukas Jungmann <lukas.jungmann@oracle.com> - b1e8395d79fcf53b86fbaf7b22e03499331fd319 Fix artifactId. (#76) by Tomáš Kraus <tomas.kraus@oracle.com> - 08638fd1b85422b0a4403843719d51cd15e4ed90 Fixes #79: bundle symbolic name should match artifactId (... by Lukas Jungmann <lukas.jungmann@oracle.com> - 539c2e8439c8505f1f24e4a1752e2ac1023e14b5 add missing files to src jar, cleanup pom, update to pare... by Lukas Jungmann <lukas.jungmann@oracle.com> - 1e4719ddbed10037ac00b1aca9ba86d7805efb05 Added dummy javadoc for tests to satisfy nexus rules. (#85) by Tomáš Kraus <tomas.kraus@oracle.com> - 0d1f39de245ccf7fd72a8643b3db869a60ff7d5b Non Java SE default context factory for JDK's > 8 by Roman Grigoriadi <roman.grigoriadi@oracle.com> - dbeb96d1c895effe5be68f645cb81f2cacb6701d Prevent Java Compiler inlining of default ModuleUtil.DEFA... by Vladimir Konkov <vkonkov@citc.ru> - a7c3179a46f6c212d40ab047e1fe0ccb3812f305 #95: Change project name to Jakarta XML Binding by Lukas Jungmann <lukas.jungmann@oracle.com> - a7dddb8368041e67a9fde0679bc70b36d2090e0d #101: boilerplate spec (#103) by Lukas Jungmann <lukas.jungmann@oracle.com> - f58628dd0b4fd82b3e625410abdcaf9b099be58d #101: minimal changes in javadocs (#104) by Lukas Jungmann <lukas.jungmann@oracle.com> - acf35b58d4c0b5a6787f4475a38b5c2ce6175540 Release job for JAXB Spec and API (#105) by Tomáš Kraus <tomas.kraus@oracle.com> - b2fe3eb4040c322c81e2f5349df74f8210e22606 various fixes (#106) by Lukas Jungmann <lukas.jungmann@oracle.com> - db43e8894f56697bda9daddd1afd8f81829ac438 Updated jobs after project refactoring. (#107) by Tomáš Kraus <tomas.kraus@oracle.com> - 47ae033160abab02fde481cd4562ba7558afae8c tweak javadoc by Lukas Jungmann <lukas.jungmann@oracle.com> - 34ae0644f5a7196c58f0d74291356137e230d2af fix revmark by Lukas Jungmann <lukas.jungmann@oracle.com> - f133cb381dd9ccc0495973119d5a3d5e13c4f44f Modified spec build arguments. by Tomas Kraus <Tomas.Kraus@oracle.com> - 55180e9082f0172019341dd5f8c44eabe42555cc fix cp holder (#112) by Lukas Jungmann <lukas.jungmann@oracle.com> - 34f041a9f1e3d198b0ea797c9771c0022e19b8cb Removed specification artifacts from release job. by Tomas Kraus <Tomas.Kraus@oracle.com> - 3e1d9c1f39d370861c627f4a532eff551a4bee2b Fix typo by Per Lundberg <perlun@gmail.com> - 78eb485fd71a00c1794b05a20c2288411d8b5ee4 bump min bin level to 8, update copyrights by Lukas Jungmann <lukas.jungmann@oracle.com> - 9632c0b764d7c38a9a0c5d5cd883acacfff4a432 Update bontinuous and release scripts. by Tomas Kraus <Tomas.Kraus@oracle.com> - cf9e355dcdd7d5fe8527c26bfa9af18c8af5958b Integrate activation 1.2.2 by Lukas Jungmann <lukas.jungmann@oracle.com> - c5b2f2c2e6c924f61732094439bb053a70e2323c increase impl version by Lukas Jungmann <lukas.jungmann@oracle.com> - 797f8c8564df1dee944a0ca3ea3622d518e1ba71 JIPP migration by Maxim Nesen <maxim.nesen@oracle.com> - 1632b900053521dba70b1fa5ad3501cdeb1da37b update parent, plugins, remove timestamp by Lukas Jungmann <lukas.jungmann@oracle.com> - 36fed0350b988bb53166a51fc59a66b954f7e081 give javadoc SE 8 look by Lukas Jungmann <lukas.jungmann@oracle.com> - 497b08575fec0b9306c3c25197c3d9420821ca5d fix the spec name by Lukas Jungmann <lukas.jungmann@oracle.com> - 10e0f06900fc78a7a5ca5ea7126e46975ccd871a Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 033714d9e98e7f1e1749e05b76ba2a3a05ed585a Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 53e61ae75809c71f4766d1b47523e4cbbaf8b68b bump new version to 3.0.0-SNAPSHOT by Lukas Jungmann <lukas.jungmann@oracle.com> - 09a4e905f718a26eb176e3fc93ccf2fd63e54ece Rename package from javax to jakarta (#125) by Thibault Vallin <thibault.vallin@oracle.com> - 617c97823b006933ed5d6bb299b4215f284a194c bump spec version, JAF 2.0.0, fixup module name by Lukas Jungmann <lukas.jungmann@oracle.com> - 09a9282f9e6b3affd33666f7de9f9ef92f64b7c1 Original specification document by Lukas Jungmann <lukas.jungmann@oracle.com> - f0c47cef080a399f33f74b26682e8bce8b981eff Ignore Eclipse/VSCode artifacts by Andy McCright <j.andrew.mccright@gmail.com> - 03548accd5f296831563e9fabdb2660495774d15 [#126] Move `javax.*` to `jakarta.*` by Andy McCright <j.andrew.mccright@gmail.com> - 9f905914354fecfb18d5eefb26440fa2f626727b remove direct dependency on java.desktop from the API by Lukas Jungmann <lukas.jungmann@oracle.com> - 3e1a3da7463f21e7a42d255165f65241ad365e7a Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 7a6c60c0c8eaea06d51d7a6855ef0054a4139979 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - aa8289577f779c63e76d9e7f639c4e02af7541cc integrate jakarta.activation 2.0.0-RC2 by Lukas Jungmann <lukas.jungmann@oracle.com> - aa1960effa1010736211b4a9c478fe65c72fb058 update build plugins by Lukas Jungmann <lukas.jungmann@oracle.com> - b95949b6a1bf236bb16f7de4f2476e53b7cd347e add travis by Lukas Jungmann <lukas.jungmann@oracle.com> - c69923130c3b3edbc00df7f9e2a10a8358a75621 switch to modularized javadoc format by Lukas Jungmann <lukas.jungmann@oracle.com> - 256dd7827a7a33b7b9155c167bd20ffa576c4f5d Update javadoc for JDK 14 by Lukas Jungmann <lukas.jungmann@oracle.com> - d4a96d8242722ab5abbf7fbfe1b30d8e36047f18 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 6b3e4a83253be194790b7ef77f6298039abe0d95 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 849feebc66baf6b786bb3fd1eb93b025729d90c9 integrate activation 2.0.0-RC3 (#144) by Lukas Jungmann <lukas.jungmann@oracle.com> - 54a025d48a2f791ca32737632c84ce468aa539dd add schemas (#143) by Lukas Jungmann <lukas.jungmann@oracle.com> - dd8c00738e656e3dee1e1aacc9aa1d43ae0a33c4 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - ebf39a9f7ba7a9fd25d4eed73d41a28ea4927e05 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 1fccbaba0a1152baa59027ff520ec3b41fc4cd02 Added MacOSX related file types by Thodoris Bais <thodoris.bais@gmail.com> - 700582cf61ce396647a4874f8f0b0b7acf710201 Move spec files from javax.* to jakarta.* packages for Ja... by Thodoris Bais <thodoris.bais@gmail.com> - 6fb5cf45a9719230e8c94b977b9c0ec0c4498a0e fix travis build by Lukas Jungmann <lukas.jungmann@oracle.com> - 0ff046e6bd485fdbb30360d3d2b00a0a7368d3fd allow spec build on jdk 12+ by Lukas Jungmann <lukas.jungmann@oracle.com> - a511e2bae28a04932f83e028d9cca583aacf379b #150: Update CONTRIBUTING.md for Specification Project's... by Lukas Jungmann <lukas.jungmann@oracle.com> - c8371199132f85f253884e5896e243a6245a42a8 split the spec, fix chapters 1-5, 6.1, 6.2 and 9 (#154) by Lukas Jungmann <lukas.jungmann@oracle.com> - c945f826028c8b147fa64c473315bfb1483ce3f0 Integrate activation 2.0.0 by Lukas Jungmann <lukas.jungmann@oracle.com> - d8eca6df86665bc771a2c2057ad74b0164dc33d1 fix release job according to eclipse requirements by Maxim Nesen <maxim.nesen@oracle.com> - 0ab2bc278a33b73f3479049801f72cce426f11f5 update spec, chapter 6 by Lukas Jungmann <lukas.jungmann@oracle.com> - ad8e03364387b0a6187b0b65983789258044b0ba Update chapter 7 (#159) by Thibault Vallin <thibault.vallin@oracle.com> - fd5a4f6ced95b084ac5f1525097d665b102b7645 update chapter 8 by Thibault Vallin <thibault.vallin@oracle.com> - 22dbf26a8c41198efd0671f7e87ac47774000d09 fix cp year, spec file name by Lukas Jungmann <lukas.jungmann@oracle.com> - 572cc863711563ed47395fff65d6a039c65d6607 Complete chapter 7 by Lukas Jungmann <lukas.jungmann@oracle.com> - 73d59bcfac3c285756493e53467f93945384db76 the spec version is 3.0 by Lukas Jungmann <lukas.jungmann@oracle.com> - aa2d536cc41181b212d6123045539ab301a7e63c update references by Lukas Jungmann <lukas.jungmann@oracle.com> - 8574e54c7c13a2e6c81cdc78a4c2c9ca4cfacf2d update appendix C by Lukas Jungmann <lukas.jungmann@oracle.com> - 5fba1dd30f52d5af921c8d793cdb5651cca15814 update appendix E by Lukas Jungmann <lukas.jungmann@oracle.com> - 32a4663c9b0d71c0f53e931281dd768e72e0dedb use updated namespace by Lukas Jungmann <lukas.jungmann@oracle.com> - a4a14b3589edbeb39f745719c83b994b3bd9021e update chapter 8 by Lukas Jungmann <lukas.jungmann@oracle.com> - c21cb8f7eeade382d5f3bd8dfba56ce2240a3a62 Update appendix B by Lukas Jungmann <lukas.jungmann@oracle.com> - 9fb5fbcfeadeb9cbd17b125d978b81a92c9fb215 Update appendix D by Lukas Jungmann <lukas.jungmann@oracle.com> - 6bb35824836b51f02b6076410a9fccd6db017586 Update appendix F by Lukas Jungmann <lukas.jungmann@oracle.com> - b7580fd88a827455115426f9dccd72e8cfdafe2d Update appendix G by Lukas Jungmann <lukas.jungmann@oracle.com> - be694e8a0c23f6d9fdddb25b69f6f35c28655881 Update appendix H by Lukas Jungmann <lukas.jungmann@oracle.com> - 06b54fb15e234d87ef4fdc86516ca66d93cac2cb replace jaxws and jaxrpc acronyms by Lukas Jungmann <lukas.jungmann@oracle.com> - 230b687777b01fd72c5a77cdddffb619906ab586 final spec changes by Lukas Jungmann <lukas.jungmann@oracle.com> - e63c086653f0357619053dc8446507cc4cac0348 fix JAXB acronym usage, use correct module name by Lukas Jungmann <lukas.jungmann@oracle.com> - 97662506d5859720839a725c66cb89f2ed15b64b Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - 652f8adb8f7f1e93c58a77b615ff4b7abf0ff297 Update API version of jakarta.xml.bind:jakarta.xml.bind-a... by Eclipse JAXB Bot <jaxb-bot@eclipse.org> - b717e34080470d12dfdd2daf74c3100dddae7c2b Bump junit from 4.12 to 4.13.1 in /jaxb-api-test by dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> - e9ca8e7df7e0ec9961618c96e38a9aa8acbca9f6 Integrate activation 2.0.1, by Lukas Jungmann <lukas.jungmann@oracle.com> - a0cc226bd150afc632fd4021b01d43f1e3b35d50 #172: default factory class name by Lukas Jungmann <lukas.jungmann@oracle.com> - 7fe4d2e710e52e0049ce9357b60eee35af29e0d7 #121: ContextFinder falls back to context classloader res... by Lukas Jungmann <lukas.jungmann@oracle.com> - 616100a586cab5d42ef888b82974ec4f5051eaf3 Be defensive when working with passed in classes by Lukas Jungmann <lukas.jungmann@oracle.com> - 6cda2dcd5c62880b4c3164f265815e2bbb4279f2 use class classloader if it has not been loaded by system... by Lukas Jungmann <lukas.jungmann@oracle.com> - dcbf68afdb558a74f53103ba52bf3dfc712f2925 Merge pull request #184 from eclipse-ee4j/3.0.1-RELEASE by Lukas Jungmann <lukas.jungmann@oracle.com> - 857da4991e6d7c3ea9e365b59344799cf8285a33 JDK17 support by Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com> - 2523e0d87735d07cae96f4b904be8cbcb0f91054 fix broken links in xmlb spec by Lukas Jungmann <lukas.jungmann@oracle.com> - c232aef6e35273e4d83a9e11f80239b3534b82c6 update cpright in the spec by Lukas Jungmann <lukas.jungmann@oracle.com> - a5b7b8164d8bf4151baa77c67449ab6a3c1f6674 spec version by Lukas Jungmann <lukas.jungmann@oracle.com> - f2897d746171943f97854e751975ea4b5388f353 bump project version to 4.0.0-SNAPSHOT by Lukas Jungmann <lukas.jungmann@oracle.com> - 7b78b7f96fc6b6ba8b411a04d0d95a13e9636356 #188: Remove deprecated jakarta.xml.bind.Validator by Lukas Jungmann <lukas.jungmann@oracle.com> - 43d1d2d4645fd2ba3150e5f40d93fabd84d4e714 #:185: add https to the required to be removed list of sc... by Lukas Jungmann <lukas.jungmann@oracle.com> - a4206810e4c7e1cb8a99ecbca822f785f9d55d20 #134: Remove dependency on java.desktop from the specific... by Lukas Jungmann <lukas.jungmann@oracle.com> - 734832bfe7fd9653d81fbad6a0285b5100605d4a Fix compiler warnings (#193) by Lukas Jungmann <lukas.jungmann@oracle.com> - 2fc2446980711533cf11c31ca535f3f677c389b6 #194: Simplify implementation lookup by Lukas Jungmann <lukas.jungmann@oracle.com> (And 60 more changes) GitOrigin-RevId: ca43d8b962e2ef8170616741ca5dd3312ee2316b Change-Id: I8adfbabeb6b88f2d1be707e9b49652a8c38ac0b1
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..fe69ce5 --- /dev/null +++ b/.github/workflows/maven.yml
@@ -0,0 +1,38 @@ +# +# Copyright (c) 2021, 2024 Contributors to the Eclipse Foundation +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Public License v. 2.0 which is available at +# http://www.eclipse.org/legal/epl-2.0, +# or the Eclipse Distribution License v. 1.0 which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause +# + +name: XML Binding API + +on: + pull_request: + push: + +jobs: + build: + name: Test on JDK ${{ matrix.java_version }} + runs-on: ubuntu-latest + + strategy: + matrix: + java_version: [ 21 ] + + steps: + - name: Checkout for build + uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: ${{ matrix.java_version }} + cache: maven + - name: Verify + run: mvn -B -V -U -C -Poss-release -Pstaging clean verify -Dgpg.skip=true org.glassfish.copyright:glassfish-copyright-maven-plugin:check -Dcopyright.ignoreyear=true
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f85ce9 --- /dev/null +++ b/.gitignore
@@ -0,0 +1,11 @@ +target/ +**/.classpath +**/.project +.settings/ + +# IntelliJ # +.idea/ +*.iml + + # OS Files # +.DS_Store \ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..36c57ea --- /dev/null +++ b/CONTRIBUTING.md
@@ -0,0 +1,73 @@ +[//]: # " Copyright (c) 2018, 2024 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " +[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " +[//]: # " " +[//]: # " SPDX-License-Identifier: BSD-3-Clause " + +# Contributing to Jakarta XML Binding + +Thanks for your interest in this project. + +## Project description + +Jakarta XML Binding™ defines an API and tools that automate the mapping +between XML documents and Java objects. + +* https://projects.eclipse.org/projects/ee4j.jaxb + +## Terms of Use + +This repository is subject to the Terms of Use of the Eclipse Foundation + +* https://www.eclipse.org/legal/termsofuse.php + +## Developer resources + +Information regarding source code management, builds, coding standards, and +more. + +* https://projects.eclipse.org/projects/ee4j.jaxb/developer + +The project maintains the following source code repositories + +* https://github.com/jakartaee/jaxb-api +* https://github.com/jakartaee/jaxb-tck + +## Eclipse Development Process + +This Eclipse Foundation open project is governed by the Eclipse Foundation +Development Process and operates under the terms of the Eclipse IP Policy. + +The Jakarta EE Specification Committee has adopted the Jakarta EE Specification +Process (JESP) in accordance with the Eclipse Foundation Specification Process +v1.2 (EFSP) to ensure that the specification process is complied with by all +Jakarta EE specification projects. + +* https://eclipse.org/projects/dev_process +* https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf +* https://jakarta.ee/about/jesp/ +* https://www.eclipse.org/legal/efsp_non_assert.php + +## Eclipse Contributor Agreement + +In order to be able to contribute to Eclipse Foundation projects you must +electronically sign the Eclipse Contributor Agreement (ECA). + +* https://www.eclipse.org/legal/ECA.php + +The ECA provides the Eclipse Foundation with a permanent record that you agree +that each of your contributions will comply with the commitments documented in +the Developer Certificate of Origin (DCO). Having an ECA on file associated with +the email address matching the "Author" field of your contribution's Git commits +fulfills the DCO's requirement that you sign-off on your contributions. + +For more information, please see the Eclipse Committer Handbook: +https://www.eclipse.org/projects/handbook/#resources-commit + +## Contact + +Contact the project developers via the project's "dev" list. + +* https://accounts.eclipse.org/mailing-list/jaxb-dev
diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..6fb337c --- /dev/null +++ b/LICENSE.md
@@ -0,0 +1,29 @@ + + Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + - Neither the name of the Eclipse Foundation, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..417ebab --- /dev/null +++ b/NOTICE.md
@@ -0,0 +1,47 @@ +[//]: # " Copyright (c) 2018, 2024 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " +[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " +[//]: # " " +[//]: # " SPDX-License-Identifier: BSD-3-Clause " + +# Notices for Jakarta XML Binding + +This content is produced and maintained by the Jakarta XML Binding project. + +* Project home: https://projects.eclipse.org/projects/ee4j.jaxb + +## Trademarks + +Jakarta XML Binding™ is a trademark of the Eclipse Foundation. + +## Copyright + +All content is the property of the respective authors or their employers. For +more information regarding authorship of content, please consult the listed +source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Distribution License v1.0 which is available at +https://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: BSD-3-Clause + +## Source Code + +The project maintains the following source code repositories: + +* https://github.com/jakartaee/jaxb-api +* https://github.com/jakartaee/jaxb-tck + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted.
diff --git a/README.md b/README.md new file mode 100644 index 0000000..354b955 --- /dev/null +++ b/README.md
@@ -0,0 +1,40 @@ +[//]: # " Copyright (c) 2018, 2022 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " +[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " +[//]: # " " +[//]: # " SPDX-License-Identifier: BSD-3-Clause " + +# Jakarta XML Binding project + +[](https://github.com/jakartaee/jaxb-api/actions/workflows/maven.yml?branch=master) +[](https://jakarta.oss.sonatype.org/content/repositories/staging/jakarta/xml/bind/jakarta.xml.bind-api/) + +The Jakarta XML Binding provides an API and tools that automate the mapping +between XML documents and Java objects. + +## License + +* Most of the Jakarta XML Binding project source code is licensed +under the [Eclipse Distribution License (EDL) v1.0.](https://www.eclipse.org/org/documents/edl-v10.php); +see the license information at the top of each source file. +* The source code for the Jakarta XML Binding Specification project +is licensed under the [Eclipse Public License (EPL) v2.0](https://www.eclipse.org/legal/epl-2.0/) +and [GNU General Public License (GPL) v2 with Classpath Exception](https://www.gnu.org/software/classpath/license.html); +again, the license is in each source file. +* The binary jar files published to the Maven repository are licensed +under the same licenses as the corresponding source code; +see the file `META-INF/LICENSE.txt` in each jar file. + +You’ll find the text of the licenses in the workspace in various `LICENSE.txt` or `LICENSE.md` files. +Don’t let the presence of these license files in the workspace confuse you into thinking +that they apply to all files in the workspace. + +You should always read the license file included with every download, and read +the license text included in every source file. + +## Contributing + +We use [contribution policy](CONTRIBUTING.md), which means we can only accept contributions under +the terms of [Eclipse Contributor Agreement](http://www.eclipse.org/legal/ECA.php).
diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..cf652e6 --- /dev/null +++ b/SECURITY.md
@@ -0,0 +1,29 @@ +[//]: # " Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. " +[//]: # " " +[//]: # " This program and the accompanying materials are made available under the " +[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at " +[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. " +[//]: # " " +[//]: # " SPDX-License-Identifier: BSD-3-Clause " + +# Security Policy + +This project implements the Eclipse Foundation Security Policy + +* https://www.eclipse.org/security + +## Supported Versions + +These versions of Jakarta XML Binding are currently being supported with +security updates. + +| Version | Released | Supported | +| ------- | ---------- | --------- | +| 4.0 | 2022-03-30 | Yes | +| 3.0.1 | 2021-03-26 | Yes | +| < 3.0 | 2020-11-04 | No | + +## Reporting a Vulnerability + +Please report vulnerabilities to the Eclipse Foundation Security Team at +security@eclipse.org
diff --git a/api/pom.xml b/api/pom.xml new file mode 100644 index 0000000..22eb1ce --- /dev/null +++ b/api/pom.xml
@@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright (c) 2018, 2023 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>jakarta.xml.bind-api-parent</artifactId> + <groupId>jakarta.xml.bind</groupId> + <version>4.0.2</version> + <relativePath>../pom.xml</relativePath> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>jakarta.xml.bind-api</artifactId> + <packaging>jar</packaging> + <name>Jakarta XML Binding API</name> + + <properties> + <config.dir>${project.basedir}/../etc/config</config.dir> + <legal.doc.source>${project.basedir}/..</legal.doc.source> + <spotbugs.exclude>${project.basedir}/../etc/spotbugs-exclude.xml</spotbugs.exclude> + </properties> + + <dependencies> + <dependency> + <groupId>jakarta.activation</groupId> + <artifactId>jakarta.activation-api</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + + <pluginManagement> + <plugins> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <configuration> + <rules> + <requireJavaVersion> + <version>[11,)</version> + </requireJavaVersion> + <requireMavenVersion> + <version>[3.6.0,)</version> + </requireMavenVersion> + <DependencyConvergence /> + </rules> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>buildnumber-maven-plugin</artifactId> + <configuration> + <getRevisionOnlyOnce>true</getRevisionOnlyOnce> + <shortRevisionLength>7</shortRevisionLength> + <revisionOnScmFailure>false</revisionOnScmFailure> + </configuration> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <failOnWarnings>true</failOnWarnings> + <doclint>all,-missing</doclint> + <quiet>true</quiet> + <nodeprecated>false</nodeprecated> + <notimestamp>true</notimestamp> + <nosince>true</nosince> + <use>false</use> + <author>true</author> + <version>true</version> + <description>Jakarta XML Binding API documentation</description> + <doctitle>Jakarta XML Binding API documentation</doctitle> + <windowtitle>Jakarta XML Binding API documentation</windowtitle> + <header><![CDATA[Jakarta XML Binding<br>v${project.version}]]> + </header> + <bottom> + <![CDATA[ +Comments to : <a href="mailto:${release.spec.feedback}">${release.spec.feedback}</a>.<br> +Copyright © 2019, ${current.year} Eclipse Foundation. All rights reserved.<br> +Use is subject to <a href="{@docRoot}/doc-files/speclicense.html" target="_top">license terms</a>.]]> + </bottom> + <detectJavaApiLink>false</detectJavaApiLink> + <docfilessubdirs>true</docfilessubdirs> + <groups> + <group> + <title>Jakarta XML Binding API Packages</title> + <packages>jakarta.xml.bind*</packages> + </group> + </groups> + <tags> + <tag> + <name>apiNote</name> + <!-- todo tag for all places --> + <placement>a</placement> + <head>API Note:</head> + </tag> + <tag> + <name>implSpec</name> + <!-- todo tag for all places --> + <placement>a</placement> + <head>Implementation Requirements:</head> + </tag> + <tag> + <name>implNote</name> + <!-- todo tag for all places --> + <placement>a</placement> + <head>Implementation Note:</head> + </tag> + </tags> + </configuration> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>currentyear-property</id> + <goals> + <goal>timestamp-property</goal> + </goals> + <phase>validate</phase> + <configuration> + <name>current.year</name> + <locale>en,US</locale> + <pattern>yyyy</pattern> + </configuration> + </execution> + <execution> + <id>add-legal-resource</id> + <phase>generate-resources</phase> + <goals> + <goal>add-resource</goal> + </goals> + <configuration> + <resources> + <resource> + <directory>${legal.doc.source}</directory> + <includes> + <include>NOTICE.md</include> + <include>LICENSE.md</include> + </includes> + <targetPath>META-INF</targetPath> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <executions> + <execution> + <id>enforce-versions</id> + <goals> + <goal>enforce</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>buildnumber-maven-plugin</artifactId> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <goals> + <goal>create</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <compilerArgs> + <arg>-Xlint:all</arg> + <arg>-Xdoclint:all,-missing</arg> + </compilerArgs> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <executions> + <execution> + <id>bundle-manifest</id> + <phase>process-classes</phase> + <goals> + <goal>manifest</goal> + </goals> + <configuration> + <archive> + <manifest> + <addDefaultEntries>false</addDefaultEntries> + </manifest> + </archive> + <niceManifest>true</niceManifest> + <instructions> + <Bundle-Version>${project.version}</Bundle-Version> <!-- 2.2.99.bnull --> + <Bundle-Description> + Jakarta XML Binding API ${spec.version} Design Specification + </Bundle-Description> + <Extension-Name>${extension.name}</Extension-Name> + <Implementation-Version>${project.version}</Implementation-Version> + <Specification-Version>${spec.version}</Specification-Version> + <Import-Package> + !org.glassfish.hk2.osgiresourcelocator, + * + </Import-Package> + <Bundle-SymbolicName>${extension.name}-api</Bundle-SymbolicName> + <DynamicImport-Package>org.glassfish.hk2.osgiresourcelocator</DynamicImport-Package> + <Specification-Vendor>${vendor.name}</Specification-Vendor> + <Implementation-Build-Id>${buildNumber}</Implementation-Build-Id> + <_noextraheaders>true</_noextraheaders> + <!-- optional to allow usage with hk2 resource locator as a fallback --> + <Require-Capability><![CDATA[ + osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.processor) + (version>=1.0.0)(!(version>=2.0.0)))";resolution:=optional, + osgi.serviceloader; + filter:="(osgi.serviceloader=jakarta.xml.bind.JAXBContextFactory)"; + osgi.serviceloader="jakarta.xml.bind.JAXBContextFactory"; + cardinality:=multiple;resolution:=optional + ]]> + </Require-Capability> + </instructions> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultEntries>false</addDefaultEntries> + </manifest> + <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> + </archive> + </configuration> + </plugin> + <plugin> + <groupId>com.github.spotbugs</groupId> + <artifactId>spotbugs-maven-plugin</artifactId> + <configuration> + <fork>true</fork> + <excludeFilterFile>${spotbugs.exclude}</excludeFilterFile> + <failThreshold>High</failThreshold> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file
diff --git a/api/src/main/java/jakarta/xml/bind/Binder.java b/api/src/main/java/jakarta/xml/bind/Binder.java new file mode 100644 index 0000000..d53dba5 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/Binder.java
@@ -0,0 +1,418 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import org.w3c.dom.Node; + +import javax.xml.validation.Schema; + +/** + * Enable synchronization between XML infoset nodes and Jakarta XML Binding objects + * representing same XML document. + * + * <p> + * An instance of this class maintains the association between XML nodes of + * an infoset preserving view and a Jakarta XML Binding representation of an XML document. + * Navigation between the two views is provided by the methods + * {@link #getXMLNode(Object)} and {@link #getJAXBNode(Object)}. + * + * <p> + * Modifications can be made to either the infoset preserving view or the + * Jakarta XML Binding representation of the document while the other view remains + * unmodified. The binder is able to synchronize the changes made in the + * modified view back into the other view using the appropriate + * Binder update methods, {@link #updateXML(Object, Object)} or + * {@link #updateJAXB(Object)}. + * + * <p> + * A typical usage scenario is the following: + * <ul> + * <li>load XML document into an XML infoset representation</li> + * <li>{@link #unmarshal(Object)} XML infoset view to Jakarta XML Binding view. + * (Note to conserve resources, it is possible to only unmarshal a + * subtree of the XML infoset view to the Jakarta XML Binding view.)</li> + * <li>application access/updates Jakarta XML Binding view of XML document.</li> + * <li>{@link #updateXML(Object)} synchronizes modifications to Jakarta XML Binding view + * back into the XML infoset view. Update operation preserves as + * much of original XML infoset as possible (i.e. comments, PI, ...)</li> + * </ul> + * + * <p> + * A Binder instance is created using the factory method + * {@link JAXBContext#createBinder()} or {@link JAXBContext#createBinder(Class)}. + * + * @param <XmlNode> the template parameter, <code>XmlNode</code>, is the + * root interface/class for the XML infoset preserving representation. + * A Binder implementation is required to minimally support + * an <code>XmlNode</code> value of <code>org.w3c.dom.Node.class</code>. + * A Binder implementation can support alternative XML infoset + * preserving representations. + * + * @author + * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * Joseph Fialli + * + * @since 1.6, JAXB 2.0 + */ +public abstract class Binder<XmlNode> { + + /** + * Do-nothing constructor for the derived classes. + */ + protected Binder() {} + + /** + * Unmarshal XML infoset view to a Jakarta XML Binding object tree. + * + * <p> + * This method is similar to {@link Unmarshaller#unmarshal(Node)} + * with the addition of maintaining the association between XML nodes + * and the produced Jakarta XML Binding objects, enabling future update operations, + * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}. + * + * <p> + * When {@link #getSchema()} is non-null, <code>xmlNode</code> + * and its descendants is validated during this operation. + * + * <p> + * This method throws {@link UnmarshalException} when the Binder's + * {@link JAXBContext} does not have a mapping for the XML element name + * or the type, specifiable via {@code @xsi:type}, of {@code xmlNode} + * to a Jakarta XML Binding mapped class. The method {@link #unmarshal(Object, Class)} + * enables an application to specify the Jakarta XML Binding mapped class that + * the {@code xmlNode} should be mapped to. + * + * @param xmlNode + * the document/element to unmarshal XML data from. + * + * @return + * the newly created root object of the Jakarta XML Binding object tree. + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Binder} is unable to perform the XML to Java + * binding. + * @throws IllegalArgumentException + * If the node parameter is null + */ + public abstract Object unmarshal( XmlNode xmlNode ) throws JAXBException; + + /** + * Unmarshal XML root element by provided {@code declaredType} + * to a Jakarta XML Binding object tree. + * + * <p> + * Implements <a href="Unmarshaller.html#unmarshalByDeclaredType">Unmarshal by Declared Type</a> + * + * <p> + * This method is similar to {@link Unmarshaller#unmarshal(Node, Class)} + * with the addition of maintaining the association between XML nodes + * and the produced Jakarta XML Binding objects, enabling future update operations, + * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}. + * + * <p> + * When {@link #getSchema()} is non-null, <code>xmlNode</code> + * and its descendants is validated during this operation. + * + * @param xmlNode + * the document/element to unmarshal XML data from. + * @param declaredType + * appropriate Jakarta XML Binding mapped class to hold {@code node}'s XML data. + * @param <T> the declared type + * + * @return + * <a href="JAXBElement.html">JAXBElement</a> representation + * of {@code node} + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Binder} is unable to perform the XML to Java + * binding. + * @throws IllegalArgumentException + * If any of the input parameters are null + * @since 1.6, JAXB 2.0 + */ + public abstract <T> JAXBElement<T> unmarshal( XmlNode xmlNode, Class<T> declaredType ) throws JAXBException; + + /** + * Marshal a Jakarta XML Binding object tree to a new XML document. + * + * <p> + * This method is similar to {@link Marshaller#marshal(Object, Node)} + * with the addition of maintaining the association between Jakarta XML Binding objects + * and the produced XML nodes, + * enabling future update operations such as + * {@link #updateXML(Object, Object)} or {@link #updateJAXB(Object)}. + * + * <p> + * When {@link #getSchema()} is non-null, the marshalled + * xml content is validated during this operation. + * + * @param jaxbObject + * The content tree to be marshalled. + * @param xmlNode + * The parameter must be a Node that accepts children. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Binder} is unable to marshal {@code jaxbObject} (or any + * object reachable from {@code jaxbObject}). + * + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + public abstract void marshal( Object jaxbObject, XmlNode xmlNode ) throws JAXBException; + + /** + * Gets the XML element associated with the given Jakarta XML Binding object. + * + * <p> + * Once a Jakarta XML Binding object tree is associated with an XML fragment, + * this method enables navigation between the two trees. + * + * <p> + * An association between an XML element and a Jakarta XML Binding object is + * established by the bind methods and the update methods. + * Note that this association is partial; not all XML elements + * have associated Jakarta XML Binding objects, and not all Jakarta XML Binding objects have + * associated XML elements. + * + * @param jaxbObject An instance that is reachable from a prior + * call to a bind or update method that returned + * a Jakarta XML Binding object tree. + * + * @return + * null if the specified Jakarta XML Binding object is not known to this + * {@link Binder}, or if it is not associated with an + * XML element. + * + * @throws IllegalArgumentException + * If the jaxbObject parameter is null + */ + public abstract XmlNode getXMLNode( Object jaxbObject ); + + /** + * Gets the Jakarta XML Binding object associated with the given XML element. + * + * <p> + * Once a Jakarta XML Binding object tree is associated with an XML fragment, + * this method enables navigation between the two trees. + * + * <p> + * An association between an XML element and a Jakarta XML Binding object is + * established by the unmarshal, marshal and update methods. + * Note that this association is partial; not all XML elements + * have associated Jakarta XML Binding objects, and not all Jakarta XML Binding objects have + * associated XML elements. + * + * @param xmlNode the XML element + * + * @return + * null if the specified XML node is not known to this + * {@link Binder}, or if it is not associated with a + * Jakarta XML Binding object. + * + * @throws IllegalArgumentException + * If the node parameter is null + */ + public abstract Object getJAXBNode( XmlNode xmlNode ); + + /** + * Takes a Jakarta XML Binding object and updates + * its associated XML node and its descendants. + * + * <p> + * This is a convenience method of: + * {@snippet : + * updateXML( jaxbObject, getXMLNode(jaxbObject)); + * } + * + * @param jaxbObject the XML Binding object + * + * @return the XML node associated with XML Binding object + * + * @throws JAXBException + * If any unexpected problem occurs updating corresponding XML content. + * @throws IllegalArgumentException + * If the jaxbObject parameter is null + */ + public abstract XmlNode updateXML( Object jaxbObject ) throws JAXBException; + + /** + * Changes in Jakarta XML Binding object tree are updated in its associated XML parse tree. + * + * <p> + * This operation can be thought of as an "in-place" marshalling. + * The difference is that instead of creating a whole new XML tree, + * this operation updates an existing tree while trying to preserve + * the XML as much as possible. + * + * <p> + * For example, unknown elements/attributes in XML that were not bound + * to Jakarta XML Binding will be left untouched (whereas a marshalling operation + * would create a new tree that doesn't contain any of those.) + * + * <p> + * As a side effect, this operation updates the association between + * XML nodes and Jakarta XML Binding objects. + * + * @param jaxbObject root of potentially modified Jakarta XML Binding object tree + * @param xmlNode root of update target XML parse tree + * + * @return + * Returns the updated XML node. Typically, this is the same + * node you passed in as <i>xmlNode</i>, but it maybe + * a different object, for example when the tag name of the object + * has changed. + * + * @throws JAXBException + * If any unexpected problem occurs updating corresponding XML content. + * @throws IllegalArgumentException + * If any of the input parameters are null + */ + public abstract XmlNode updateXML( Object jaxbObject, XmlNode xmlNode ) throws JAXBException; + + /** + * Takes an XML node and updates its associated Jakarta XML Binding object and its descendants. + * + * <p> + * This operation can be thought of as an "in-place" unmarshalling. + * The difference is that instead of creating a whole new Jakarta XML Binding tree, + * this operation updates an existing tree, reusing as much Jakarta XML Binding objects + * as possible. + * + * <p> + * As a side effect, this operation updates the association between + * XML nodes and Jakarta XML Binding objects. + * + * @param xmlNode the XML node + * + * @return + * Returns the updated Jakarta XML Binding object. Typically, this is the same + * object that was returned from earlier + * {@link #marshal(Object,Object)} or + * {@link #updateJAXB(Object)} method invocation, + * but it maybe + * a different object, for example when the name of the XML + * element has changed. + * + * @throws JAXBException + * If any unexpected problem occurs updating corresponding Jakarta XML Binding mapped content. + * @throws IllegalArgumentException + * If node parameter is null + */ + public abstract Object updateJAXB( XmlNode xmlNode ) throws JAXBException; + + + /** + * Specifies whether marshal, unmarshal and update methods + * performs validation on their XML content. + * + * @param schema set to null to disable validation. + * + * @see Unmarshaller#setSchema(Schema) + */ + public abstract void setSchema( Schema schema ); + + /** + * Gets the last {@link Schema} object (including null) set by the + * {@link #setSchema(Schema)} method. + * + * @return the Schema object for validation or null if not present + */ + public abstract Schema getSchema(); + + /** + * Allow an application to register a {@code ValidationEventHandler}. + * <p> + * The {@code ValidationEventHandler} will be called by the Jakarta XML Binding Provider + * if any validation errors are encountered during calls to any of the + * Binder unmarshal, marshal and update methods. + * + * <p> + * Calling this method with a null parameter will cause the Binder + * to revert back to the default event handler. + * + * @param handler the validation event handler + * @throws JAXBException if an error was encountered while setting the + * event handler + */ + public abstract void setEventHandler( ValidationEventHandler handler ) throws JAXBException; + + /** + * Return the current event handler or the default event handler if one + * hasn't been set. + * + * @return the current ValidationEventHandler or the default event handler + * if it hasn't been set + * @throws JAXBException if an error was encountered while getting the + * current event handler + */ + public abstract ValidationEventHandler getEventHandler() throws JAXBException; + + /** + * + * Set the particular property in the underlying implementation of + * {@code Binder}. This method can only be used to set one of + * the standard Jakarta XML Binding defined unmarshal/marshal properties + * or a provider specific property for binder, unmarshal or marshal. + * Attempting to set an undefined property will result in + * a PropertyException being thrown. See + * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a> + * and + * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>. + * + * @param name the name of the property to be set. This value can either + * be specified using one of the constant fields or a user + * supplied string. + * @param value the value of the property to be set + * + * @throws PropertyException when there is an error processing the given + * property or value + * @throws IllegalArgumentException + * If the name parameter is null + */ + abstract public void setProperty( String name, Object value ) throws PropertyException; + + + /** + * Get the particular property in the underlying implementation of + * {@code Binder}. This method can only + * be used to get one of + * the standard Jakarta XML Binding defined unmarshal/marshal properties + * or a provider specific property for binder, unmarshal or marshal. + * Attempting to get an undefined property will result in + * a PropertyException being thrown. See + * <a href="Unmarshaller.html#supportedProps">Supported Unmarshal Properties</a> + * and + * <a href="Marshaller.html#supportedProps">Supported Marshal Properties</a>. + * + * @param name the name of the property to retrieve + * @return the value of the requested property + * + * @throws PropertyException + * when there is an error retrieving the given property or value + * property name + * @throws IllegalArgumentException + * If the name parameter is null + */ + abstract public Object getProperty( String name ) throws PropertyException; + +}
diff --git a/api/src/main/java/jakarta/xml/bind/ContextFinder.java b/api/src/main/java/jakarta/xml/bind/ContextFinder.java new file mode 100644 index 0000000..6424a09 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ContextFinder.java
@@ -0,0 +1,491 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Map; +import java.util.function.Predicate; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + + +/** + * This class is package private and therefore is not exposed as part of the + * Jakarta XML Binding API. + * <p> + * This code is designed to implement the XML Binding spec pluggability feature + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see JAXBContext + */ +class ContextFinder { + + private static final Logger logger; + + /** + * When JAXB is in J2SE, rt.jar has to have a JAXB implementation. + * However, rt.jar cannot have META-INF/services/jakarta.xml.bind.JAXBContext + * because if it has, it will take precedence over any file that applications have + * in their jar files. + * + * <p> + * When the user bundles his own Jakarta XML Binding implementation, we'd like to use it, and we + * want the platform default to be used only when there's no other Jakarta XML Binding provider. + * + * <p> + * For this reason, we have to hard-code the class name into the API. + */ + //XXX: should we define and rely on "default" in jakarta? + static final String DEFAULT_FACTORY_CLASS = "org.glassfish.jaxb.runtime.v2.ContextFactory"; + + static { + logger = Logger.getLogger("jakarta.xml.bind"); + try { + if (AccessController.doPrivileged(new GetPropertyAction("jaxb.debug")) != null) { + // disconnect the logger from a bigger framework (if any) + // and take the matters into our own hands + logger.setUseParentHandlers(false); + logger.setLevel(Level.ALL); + ConsoleHandler handler = new ConsoleHandler(); + handler.setLevel(Level.ALL); + logger.addHandler(handler); + } else { + // don't change the setting of this logger + // to honor what other frameworks + // have done on configurations. + } + } catch (Throwable t) { + // just to be extra safe. in particular System.getProperty may throw + // SecurityException. + } + } + + private static ServiceLoaderUtil.ExceptionHandler<JAXBException> EXCEPTION_HANDLER = + new ServiceLoaderUtil.ExceptionHandler<>() { + @Override + public JAXBException createException(Throwable throwable, String message) { + return new JAXBException(message, throwable); + } + }; + + /** + * If the {@link InvocationTargetException} wraps an exception that shouldn't be wrapped, + * throw the wrapped exception. Otherwise, returns exception to be wrapped for further processing. + */ + private static Throwable handleInvocationTargetException(InvocationTargetException x) throws JAXBException { + Throwable t = x.getTargetException(); + if (t != null) { + if (t instanceof JAXBException) + // one of our exceptions, just re-throw + throw (JAXBException) t; + if (t instanceof RuntimeException) + // avoid wrapping exceptions unnecessarily + throw (RuntimeException) t; + if (t instanceof Error) + throw (Error) t; + return t; + } + return x; + } + + + /** + * Determine if two types (JAXBContext in this case) will generate a ClassCastException. + * <p> + * For example, (targetType)originalType + * + * @param originalType + * The Class object of the type being cast + * @param targetType + * The Class object of the type that is being cast to + * @return JAXBException to be thrown. + */ + private static JAXBException handleClassCastException(Class<?> originalType, Class<?> targetType) { + final URL targetTypeURL = which(targetType); + + return new JAXBException(Messages.format(Messages.ILLEGAL_CAST, + // we don't care where the impl class is, we want to know where JAXBContext lives in the impl + // class' ClassLoader + getClassClassLoader(originalType).getResource("jakarta/xml/bind/JAXBContext.class"), + targetTypeURL)); + } + + /** + * Create an instance of a class using the specified ClassLoader + */ + static JAXBContext newInstance(String contextPath, + Class<?>[] contextPathClasses, + String className, + ClassLoader classLoader, + Map<String, ?> properties) throws JAXBException { + + try { + Class<?> spFactory = ServiceLoaderUtil.safeLoadClass(className, DEFAULT_FACTORY_CLASS, classLoader); + return newInstance(contextPath, contextPathClasses, spFactory, classLoader, properties); + } catch (ClassNotFoundException x) { + throw new JAXBException(Messages.format(Messages.DEFAULT_PROVIDER_NOT_FOUND), x); + + } catch (RuntimeException | JAXBException x) { + // avoid wrapping RuntimeException to JAXBException, + // because it indicates a bug in this code. + // JAXBException re-thrown as is + throw x; + } catch (Exception x) { + // can't catch JAXBException because the method is hidden behind + // reflection. Root element collisions detected in the call to + // createContext() are reported as JAXBExceptions - just re-throw it + // some other type of exception - just wrap it + throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x); + } + } + + static JAXBContext newInstance(String contextPath, + Class<?>[] contextPathClasses, + Class<?> spFactory, + ClassLoader classLoader, + Map<String, ?> properties) throws JAXBException { + + try { + + ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, spFactory); + + /* + * jakarta.xml.bind.context.factory points to a class which has a + * static method called 'createContext' that + * returns a jakarta.xml.bind.JAXBContext. + */ + + Object context = null; + + // first check the method that takes Map as the third parameter. + // this is added in 2.0. + try { + Method m = spFactory.getMethod("createContext", String.class, ClassLoader.class, Map.class); + // any failure in invoking this method would be considered fatal + Object obj = instantiateProviderIfNecessary(spFactory); + context = m.invoke(obj, contextPath, classLoader, properties); + } catch (NoSuchMethodException ignored) { + // it's not an error for the provider not to have this method. + } + + if (context == null) { + // try the old method that doesn't take properties. compatible with 1.0. + // it is an error for an implementation not to have both forms of the createContext method. + Method m = spFactory.getMethod("createContext", String.class, ClassLoader.class); + Object obj = instantiateProviderIfNecessary(spFactory); + // any failure in invoking this method would be considered fatal + context = m.invoke(obj, contextPath, classLoader); + } + + if (!(context instanceof JAXBContext)) { + // the cast would fail, so generate an exception with a nice message + throw handleClassCastException(context.getClass(), JAXBContext.class); + } + + return (JAXBContext) context; + } catch (InvocationTargetException x) { + // throw if it is exception not to be wrapped + // otherwise, wrap with a JAXBException + Throwable e = handleInvocationTargetException(x); + throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, spFactory, e), e); + + } catch (Exception x) { + // can't catch JAXBException because the method is hidden behind + // reflection. Root element collisions detected in the call to + // createContext() are reported as JAXBExceptions - just re-throw it + // some other type of exception - just wrap it + throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, spFactory, x), x); + } + } + + private static Object instantiateProviderIfNecessary(final Class<?> implClass) throws JAXBException { + try { + if (JAXBContextFactory.class.isAssignableFrom(implClass)) { + return AccessController.doPrivileged(new PrivilegedExceptionAction<>() { + @Override + public Object run() throws Exception { + return implClass.getConstructor().newInstance(); + } + }); + } + return null; + } catch (PrivilegedActionException x) { + Throwable e = (x.getCause() == null) ? x : x.getCause(); + throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, implClass, e), e); + } + } + + /** + * Create an instance of a class using the thread context ClassLoader + */ + private static JAXBContext newInstance(Class<?>[] classes, Map<String, ?> properties, String className) throws JAXBException { + return newInstance(classes, properties, className, getContextClassLoader()); + } + + /** + * Create an instance of a class using passed in ClassLoader + */ + private static JAXBContext newInstance(Class<?>[] classes, Map<String, ?> properties, String className, ClassLoader loader) throws JAXBException { + + Class<?> spi; + try { + spi = ServiceLoaderUtil.safeLoadClass(className, DEFAULT_FACTORY_CLASS, loader); + } catch (ClassNotFoundException e) { + throw new JAXBException(Messages.format(Messages.DEFAULT_PROVIDER_NOT_FOUND), e); + } + + if (logger.isLoggable(Level.FINE)) { + // extra check to avoid costly which operation if not logged + logger.log(Level.FINE, "loaded {0} from {1}", new Object[]{className, which(spi)}); + } + + return newInstance(classes, properties, spi); + } + + static JAXBContext newInstance(Class<?>[] classes, + Map<String, ?> properties, + Class<?> spFactory) throws JAXBException { + try { + ModuleUtil.delegateAddOpensToImplModule(classes, spFactory); + + Method m = spFactory.getMethod("createContext", Class[].class, Map.class); + Object obj = instantiateProviderIfNecessary(spFactory); + Object context = m.invoke(obj, classes, properties); + if (!(context instanceof JAXBContext)) { + // the cast would fail, so generate an exception with a nice message + throw handleClassCastException(context.getClass(), JAXBContext.class); + } + return (JAXBContext) context; + + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new JAXBException(e); + } catch (InvocationTargetException e) { + // throw if it is exception not to be wrapped + // otherwise, wrap with a JAXBException + Throwable x = handleInvocationTargetException(e); + + throw new JAXBException(x); + } + } + + static JAXBContext find(String factoryId, + String contextPath, + ClassLoader classLoader, + Map<String, ?> properties) throws JAXBException { + + if (contextPath == null || contextPath.isEmpty()) { + // no context is specified + throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH)); + } + + //ModuleUtil is mr-jar class, scans context path for jaxb classes on jdk9 and higher + Class<?>[] contextPathClasses = ModuleUtil.getClassesFromContextPath(contextPath, classLoader); + + String factoryName = classNameFromSystemProperties(); + if (factoryName != null) return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties); + + if (properties != null) { + Object factory = properties.get(factoryId); + if (factory != null) { + if (factory instanceof String) { + factoryName = (String) factory; + } else { + throw new JAXBException(Messages.format(Messages.ILLEGAL_CAST, factory.getClass().getName(), "String")); + } + } + if (factoryName != null) { + return newInstance(contextPath, contextPathClasses, factoryName, classLoader, properties); + } + } + + JAXBContextFactory obj = ServiceLoaderUtil.firstByServiceLoader( + JAXBContextFactory.class, logger, EXCEPTION_HANDLER); + + if (obj != null) { + ModuleUtil.delegateAddOpensToImplModule(contextPathClasses, obj.getClass()); + return obj.createContext(contextPath, classLoader, properties); + } + + Iterable<Class<? extends JAXBContextFactory>> ctxFactories = ServiceLoaderUtil.lookupsUsingOSGiServiceLoader( + JAXBContext.JAXB_CONTEXT_FACTORY, logger); + + if (ctxFactories != null) { + for (Class<? extends JAXBContextFactory> ctxFactory : ctxFactories) { + try { + return newInstance(contextPath, contextPathClasses, ctxFactory, classLoader, properties); + } catch (Throwable t) { + logger.log(Level.FINE, t, () -> "Error instantiating provider " + ctxFactory); + } + } + } + + // else no provider found + logger.fine("Trying to create the platform default provider"); + return newInstance(contextPath, contextPathClasses, DEFAULT_FACTORY_CLASS, classLoader, properties); + } + + static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JAXBException { + String factoryClassName = classNameFromSystemProperties(); + if (factoryClassName != null) return newInstance(classes, properties, factoryClassName); + + if (properties != null) { + Object ctxFactory = properties.get(JAXBContext.JAXB_CONTEXT_FACTORY); + if (ctxFactory != null) { + if (ctxFactory instanceof String) { + factoryClassName = (String) ctxFactory; + } else { + throw new JAXBException(Messages.format(Messages.ILLEGAL_CAST, ctxFactory.getClass().getName(), "String")); + } + } + if (factoryClassName != null) { + //Providers are not required to understand JAXB_CONTEXT_FACTORY property + //and they must throw a JAXBException if they see it, so we need to remove it + //from properties passed to them + Map<String, ?> props = properties.entrySet() + .stream() + .filter(Predicate.not(e -> JAXBContext.JAXB_CONTEXT_FACTORY.equals(e.getKey()))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return newInstance(classes, props, factoryClassName); + } + } + + JAXBContextFactory factory = + ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER); + + if (factory != null) { + ModuleUtil.delegateAddOpensToImplModule(classes, factory.getClass()); + return factory.createContext(classes, properties); + } + + logger.fine("Trying to create the platform default provider"); + Class<?> ctxFactoryClass = + ServiceLoaderUtil.lookupUsingOSGiServiceLoader(JAXBContext.JAXB_CONTEXT_FACTORY, logger); + + if (ctxFactoryClass != null) { + return newInstance(classes, properties, ctxFactoryClass); + } + + // else no provider found + logger.fine("Trying to create the platform default provider"); + return newInstance(classes, properties, DEFAULT_FACTORY_CLASS); + } + + private static String classNameFromSystemProperties() throws JAXBException { + + String factoryClassName = getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY); + if (factoryClassName != null) { + return factoryClassName; + } + + return null; + } + + private static String getSystemProperty(String property) { + logger.log(Level.FINE, "Checking system property {0}", property); + String value = AccessController.doPrivileged(new GetPropertyAction(property)); + if (value != null) { + logger.log(Level.FINE, " found {0}", value); + } else { + logger.log(Level.FINE, " not found"); + } + return value; + } + + /** + * Search the given ClassLoader for an instance of the specified class and + * return a string representation of the URL that points to the resource. + * + * @param clazz + * The class to search for + * @param loader + * The ClassLoader to search. If this parameter is null, then the + * system class loader will be searched + * @return + * the URL for the class or null if it wasn't found + */ + static URL which(Class<?> clazz, ClassLoader loader) { + + String classnameAsResource = clazz.getName().replace('.', '/') + ".class"; + + if (loader == null) { + loader = getSystemClassLoader(); + } + + return loader.getResource(classnameAsResource); + } + + /** + * Get the URL for the Class from it's ClassLoader. + * <p> + * Convenience method for {@link #which(Class, ClassLoader)}. + * <p> + * Equivalent to calling: which(clazz, clazz.getClassLoader()) + * + * @param clazz + * The class to search for + * @return + * the URL for the class or null if it wasn't found + */ + static URL which(Class<?> clazz) { + return which(clazz, getClassClassLoader(clazz)); + } + + private static ClassLoader getContextClassLoader() { + if (System.getSecurityManager() == null) { + return Thread.currentThread().getContextClassLoader(); + } else { + return AccessController.doPrivileged( + new PrivilegedAction<>() { + @Override + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + } + + private static ClassLoader getClassClassLoader(final Class<?> c) { + if (System.getSecurityManager() == null) { + return c.getClassLoader(); + } else { + return AccessController.doPrivileged( + new PrivilegedAction<>() { + @Override + public ClassLoader run() { + return c.getClassLoader(); + } + }); + } + } + + private static ClassLoader getSystemClassLoader() { + if (System.getSecurityManager() == null) { + return ClassLoader.getSystemClassLoader(); + } else { + return AccessController.doPrivileged( + new PrivilegedAction<>() { + @Override + public ClassLoader run() { + return ClassLoader.getSystemClassLoader(); + } + }); + } + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/DataBindingException.java b/api/src/main/java/jakarta/xml/bind/DataBindingException.java new file mode 100644 index 0000000..6ea2438 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/DataBindingException.java
@@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * Exception that represents a failure in a Jakarta XML Binding operation. + * + * <p> + * This exception differs from {@link JAXBException} in that + * this is an unchecked exception, while {@code JAXBException} + * is a checked exception. + * + * @see JAXB + * @since 1.6, JAXB 2.1 + */ +public class DataBindingException extends RuntimeException { + + private static final long serialVersionUID = 4743686626270704879L; + + public DataBindingException(String message, Throwable cause) { + super(message, cause); + } + + public DataBindingException(Throwable cause) { + super(cause); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/DatatypeConverter.java b/api/src/main/java/jakarta/xml/bind/DatatypeConverter.java new file mode 100644 index 0000000..c6db93e --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/DatatypeConverter.java
@@ -0,0 +1,677 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import javax.xml.namespace.NamespaceContext; + +/** + * <p> + * The javaType binding declaration can be used to customize the binding of + * an XML schema datatype to a Java datatype. Customizations can involve + * writing a parse and print method for parsing and printing lexical + * representations of an XML schema datatype respectively. However, writing + * parse and print methods requires knowledge of the lexical representations ( + * <a href="http://www.w3.org/TR/xmlschema-2/"> XML Schema Part2: Datatypes + * specification </a>) and hence may be difficult to write. + * </p> + * <p> + * This class makes it easier to write parse and print methods. It defines + * static parse and print methods that provide access to a Jakarta XML Binding provider's + * implementation of parse and print methods. These methods are invoked by + * custom parse and print methods. For example, the binding of xsd:dateTime + * to a long can be customized using parse and print methods as follows: + * {@snippet : + * // Customized parse method + * public long myParseCal( String dateTimeString ) { + * java.util.Calendar cal = DatatypeConverter.parseDateTime(dateTimeString); + * long longval = convert_calendar_to_long(cal); //application specific + * return longval; + * } + * + * // Customized print method + * public String myPrintCal( Long longval ) { + * java.util.Calendar cal = convert_long_to_calendar(longval) ; //application specific + * String dateTimeString = DatatypeConverter.printDateTime(cal); + * return dateTimeString; + * } + * } + * <p> + * There is a static parse and print method corresponding to each parse and + * print method respectively in the {@link DatatypeConverterInterface + * DatatypeConverterInterface}. + * <p> + * The static methods defined in the class can also be used to specify + * a parse or a print method in a javaType binding declaration. + * </p> + * <p> + * Jakarta XML Binding Providers are required to call the + * {@link #setDatatypeConverter(DatatypeConverterInterface) + * setDatatypeConverter} api at some point before the first marshal or unmarshal + * operation (perhaps during the call to JAXBContext.newInstance). This step is + * necessary to configure the converter that should be used to perform the + * print and parse functionality. + * </p> + * + * <p> + * A print method for an XML schema datatype can output any lexical + * representation that is valid with respect to the XML schema datatype. + * If an error is encountered during conversion, then an IllegalArgumentException, + * or a subclass of IllegalArgumentException must be thrown by the method. + * </p> + * + * @author <ul><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Ryan Shoemaker,Sun Microsystems Inc.</li></ul> + * @see DatatypeConverterInterface + * @see ParseConversionEvent + * @see PrintConversionEvent + * @since 1.6, JAXB 1.0 + */ +final public class DatatypeConverter { + + // delegate to this instance of DatatypeConverter + private static volatile DatatypeConverterInterface theConverter = null; + + private final static JAXBPermission SET_DATATYPE_CONVERTER_PERMISSION = + new JAXBPermission("setDatatypeConverter"); + + private DatatypeConverter() { + // private constructor + } + + /** + * This method is for Jakarta XML Binding provider use only. + * <p> + * Jakarta XML Binding Providers are required to call this method at some point before + * allowing any of the Jakarta XML Binding client marshal or unmarshal operations to + * occur. This is necessary to configure the datatype converter that + * should be used to perform the print and parse conversions. + * + * <p> + * Calling this api repeatedly will have no effect - the + * DatatypeConverterInterface instance passed into the first invocation is + * the one that will be used from then on. + * + * @param converter an instance of a class that implements the + * DatatypeConverterInterface class - this parameter must not be null. + * @throws IllegalArgumentException if the parameter is null + * @throws SecurityException + * If the {@link SecurityManager} in charge denies the access to + * set the datatype converter. + * @see JAXBPermission + */ + public static void setDatatypeConverter( DatatypeConverterInterface converter ) { + if( converter == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) ); + } else if( theConverter == null ) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(SET_DATATYPE_CONVERTER_PERMISSION); + theConverter = converter; + } + } + + private static synchronized void initConverter() { + theConverter = new DatatypeConverterImpl(); + } + + /** + * <p> + * Convert the lexical XSD string argument into a String value. + * @param lexicalXSDString + * A string containing a lexical representation of + * xsd:string. + * @return + * A String value represented by the string argument. + */ + public static String parseString( String lexicalXSDString ) { + if (theConverter == null) initConverter(); + return theConverter.parseString( lexicalXSDString ); + } + + /** + * <p> + * Convert the string argument into a BigInteger value. + * @param lexicalXSDInteger + * A string containing a lexical representation of + * xsd:integer. + * @return + * A BigInteger value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDInteger</code> is not a valid string representation of a {@link java.math.BigInteger} value. + */ + public static java.math.BigInteger parseInteger( String lexicalXSDInteger ) { + if (theConverter == null) initConverter(); + return theConverter.parseInteger( lexicalXSDInteger ); + } + + /** + * <p> + * Convert the string argument into an int value. + * @param lexicalXSDInt + * A string containing a lexical representation of + * xsd:int. + * @return + * An int value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDInt</code> is not a valid string representation of an <code>int</code> value. + */ + public static int parseInt( String lexicalXSDInt ) { + if (theConverter == null) initConverter(); + return theConverter.parseInt( lexicalXSDInt ); + } + + /** + * <p> + * Converts the string argument into a long value. + * @param lexicalXSDLong + * A string containing lexical representation of + * xsd:long. + * @return + * A long value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDLong</code> is not a valid string representation of a <code>long</code> value. + */ + public static long parseLong( String lexicalXSDLong ) { + if (theConverter == null) initConverter(); + return theConverter.parseLong( lexicalXSDLong ); + } + + /** + * <p> + * Converts the string argument into a short value. + * @param lexicalXSDShort + * A string containing lexical representation of + * xsd:short. + * @return + * A short value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDShort</code> is not a valid string representation of a <code>short</code> value. + */ + public static short parseShort( String lexicalXSDShort ) { + if (theConverter == null) initConverter(); + return theConverter.parseShort( lexicalXSDShort ); + } + + /** + * <p> + * Converts the string argument into a BigDecimal value. + * @param lexicalXSDDecimal + * A string containing lexical representation of + * xsd:decimal. + * @return + * A BigDecimal value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDDecimal</code> is not a valid string representation of {@link java.math.BigDecimal}. + */ + public static java.math.BigDecimal parseDecimal( String lexicalXSDDecimal ) { + if (theConverter == null) initConverter(); + return theConverter.parseDecimal( lexicalXSDDecimal ); + } + + /** + * <p> + * Converts the string argument into a float value. + * @param lexicalXSDFloat + * A string containing lexical representation of + * xsd:float. + * @return + * A float value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDFloat</code> is not a valid string representation of a <code>float</code> value. + */ + public static float parseFloat( String lexicalXSDFloat ) { + if (theConverter == null) initConverter(); + return theConverter.parseFloat( lexicalXSDFloat ); + } + + /** + * <p> + * Converts the string argument into a double value. + * @param lexicalXSDDouble + * A string containing lexical representation of + * xsd:double. + * @return + * A double value represented by the string argument. + * @throws NumberFormatException <code>lexicalXSDDouble</code> is not a valid string representation of a <code>double</code> value. + */ + public static double parseDouble( String lexicalXSDDouble ) { + if (theConverter == null) initConverter(); + return theConverter.parseDouble( lexicalXSDDouble ); + } + + /** + * <p> + * Converts the string argument into a boolean value. + * @param lexicalXSDBoolean + * A string containing lexical representation of + * xsd:boolean. + * @return + * A boolean value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:boolean. + */ + public static boolean parseBoolean( String lexicalXSDBoolean ) { + if (theConverter == null) initConverter(); + return theConverter.parseBoolean( lexicalXSDBoolean ); + } + + /** + * <p> + * Converts the string argument into a byte value. + * @param lexicalXSDByte + * A string containing lexical representation of + * xsd:byte. + * @return + * A byte value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:byte. + */ + public static byte parseByte( String lexicalXSDByte ) { + if (theConverter == null) initConverter(); + return theConverter.parseByte( lexicalXSDByte ); + } + + /** + * <p> + * Converts the string argument into a byte value. + * + * <p> + * String parameter {@code lexicalXSDQname} must conform to lexical value space specifed at + * <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part 2:Datatypes specification:QNames</a> + * + * @param lexicalXSDQName + * A string containing lexical representation of xsd:QName. + * @param nsc + * A namespace context for interpreting a prefix within a QName. + * @return + * A QName value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to XML Schema Part 2 specification or + * if namespace prefix of {@code lexicalXSDQname} is not bound to a URI in NamespaceContext {@code nsc}. + */ + public static javax.xml.namespace.QName parseQName( String lexicalXSDQName, + NamespaceContext nsc) { + if (theConverter == null) initConverter(); + return theConverter.parseQName( lexicalXSDQName, nsc ); + } + + /** + * <p> + * Converts the string argument into a Calendar value. + * @param lexicalXSDDateTime + * A string containing lexical representation of + * xsd:datetime. + * @return + * A Calendar object represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:dateTime. + */ + public static java.util.Calendar parseDateTime( String lexicalXSDDateTime ) { + if (theConverter == null) initConverter(); + return theConverter.parseDateTime( lexicalXSDDateTime ); + } + + /** + * <p> + * Converts the string argument into an array of bytes. + * @param lexicalXSDBase64Binary + * A string containing lexical representation + * of xsd:base64Binary. + * @return + * An array of bytes represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:base64Binary + */ + public static byte[] parseBase64Binary( String lexicalXSDBase64Binary ) { + if (theConverter == null) initConverter(); + return theConverter.parseBase64Binary( lexicalXSDBase64Binary ); + } + + /** + * <p> + * Converts the string argument into an array of bytes. + * @param lexicalXSDHexBinary + * A string containing lexical representation of + * xsd:hexBinary. + * @return + * An array of bytes represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:hexBinary. + */ + public static byte[] parseHexBinary( String lexicalXSDHexBinary ) { + if (theConverter == null) initConverter(); + return theConverter.parseHexBinary( lexicalXSDHexBinary ); + } + + /** + * <p> + * Converts the string argument into a long value. + * @param lexicalXSDUnsignedInt + * A string containing lexical representation + * of xsd:unsignedInt. + * @return + * A long value represented by the string argument. + * @throws NumberFormatException if string parameter can not be parsed into a {@code long} value. + */ + public static long parseUnsignedInt( String lexicalXSDUnsignedInt ) { + if (theConverter == null) initConverter(); + return theConverter.parseUnsignedInt( lexicalXSDUnsignedInt ); + } + + /** + * <p> + * Converts the string argument into an int value. + * @param lexicalXSDUnsignedShort + * A string containing lexical + * representation of xsd:unsignedShort. + * @return + * An int value represented by the string argument. + * @throws NumberFormatException if string parameter can not be parsed into an {@code int} value. + */ + public static int parseUnsignedShort( String lexicalXSDUnsignedShort ) { + if (theConverter == null) initConverter(); + return theConverter.parseUnsignedShort( lexicalXSDUnsignedShort ); + } + + /** + * <p> + * Converts the string argument into a Calendar value. + * @param lexicalXSDTime + * A string containing lexical representation of + * xsd:time. + * @return + * A Calendar value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Time. + */ + public static java.util.Calendar parseTime( String lexicalXSDTime ) { + if (theConverter == null) initConverter(); + return theConverter.parseTime( lexicalXSDTime ); + } + /** + * <p> + * Converts the string argument into a Calendar value. + * @param lexicalXSDDate + * A string containing lexical representation of + * xsd:Date. + * @return + * A Calendar value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Date. + */ + public static java.util.Calendar parseDate( String lexicalXSDDate ) { + if (theConverter == null) initConverter(); + return theConverter.parseDate( lexicalXSDDate ); + } + + /** + * <p> + * Return a string containing the lexical representation of the + * simple type. + * @param lexicalXSDAnySimpleType + * A string containing lexical + * representation of the simple type. + * @return + * A string containing the lexical representation of the + * simple type. + */ + public static String parseAnySimpleType( String lexicalXSDAnySimpleType ) { + if (theConverter == null) initConverter(); + return theConverter.parseAnySimpleType( lexicalXSDAnySimpleType ); + } + /** + * <p> + * Converts the string argument into a string. + * @param val + * A string value. + * @return + * A string containing a lexical representation of xsd:string. + */ + // also indicate the print methods produce a lexical + // representation for given Java datatypes. + + public static String printString( String val ) { + if (theConverter == null) initConverter(); + return theConverter.printString( val ); + } + + /** + * <p> + * Converts a BigInteger value into a string. + * @param val + * A BigInteger value + * @return + * A string containing a lexical representation of xsd:integer + * @throws IllegalArgumentException {@code val} is null. + */ + public static String printInteger( java.math.BigInteger val ) { + if (theConverter == null) initConverter(); + return theConverter.printInteger( val ); + } + + /** + * <p> + * Converts an int value into a string. + * @param val + * An int value + * @return + * A string containing a lexical representation of xsd:int + */ + public static String printInt( int val ) { + if (theConverter == null) initConverter(); + return theConverter.printInt( val ); + } + + /** + * <p> + * Converts A long value into a string. + * @param val + * A long value + * @return + * A string containing a lexical representation of xsd:long + */ + public static String printLong( long val ) { + if (theConverter == null) initConverter(); + return theConverter.printLong( val ); + } + + /** + * <p> + * Converts a short value into a string. + * @param val + * A short value + * @return + * A string containing a lexical representation of xsd:short + */ + public static String printShort( short val ) { + if (theConverter == null) initConverter(); + return theConverter.printShort( val ); + } + + /** + * <p> + * Converts a BigDecimal value into a string. + * @param val + * A BigDecimal value + * @return + * A string containing a lexical representation of xsd:decimal + * @throws IllegalArgumentException {@code val} is null. + */ + public static String printDecimal( java.math.BigDecimal val ) { + if (theConverter == null) initConverter(); + return theConverter.printDecimal( val ); + } + + /** + * <p> + * Converts a float value into a string. + * @param val + * A float value + * @return + * A string containing a lexical representation of xsd:float + */ + public static String printFloat( float val ) { + if (theConverter == null) initConverter(); + return theConverter.printFloat( val ); + } + + /** + * <p> + * Converts a double value into a string. + * @param val + * A double value + * @return + * A string containing a lexical representation of xsd:double + */ + public static String printDouble( double val ) { + if (theConverter == null) initConverter(); + return theConverter.printDouble( val ); + } + + /** + * <p> + * Converts a boolean value into a string. + * @param val + * A boolean value + * @return + * A string containing a lexical representation of xsd:boolean + */ + public static String printBoolean( boolean val ) { + if (theConverter == null) initConverter(); + return theConverter.printBoolean( val ); + } + + /** + * <p> + * Converts a byte value into a string. + * @param val + * A byte value + * @return + * A string containing a lexical representation of xsd:byte + */ + public static String printByte( byte val ) { + if (theConverter == null) initConverter(); + return theConverter.printByte( val ); + } + + /** + * <p> + * Converts a QName instance into a string. + * @param val + * A QName value + * @param nsc + * A namespace context for interpreting a prefix within a QName. + * @return + * A string containing a lexical representation of QName + * @throws IllegalArgumentException if {@code val} is null or + * if {@code nsc} is non-null or {@code nsc.getPrefix(nsprefixFromVal)} is null. + */ + public static String printQName( javax.xml.namespace.QName val, + NamespaceContext nsc ) { + if (theConverter == null) initConverter(); + return theConverter.printQName( val, nsc ); + } + + /** + * <p> + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:dateTime + * @throws IllegalArgumentException if {@code val} is null. + */ + public static String printDateTime( java.util.Calendar val ) { + if (theConverter == null) initConverter(); + return theConverter.printDateTime( val ); + } + + /** + * <p> + * Converts an array of bytes into a string. + * @param val + * An array of bytes + * @return + * A string containing a lexical representation of xsd:base64Binary + * @throws IllegalArgumentException if {@code val} is null. + */ + public static String printBase64Binary( byte[] val ) { + if (theConverter == null) initConverter(); + return theConverter.printBase64Binary( val ); + } + + /** + * <p> + * Converts an array of bytes into a string. + * @param val + * An array of bytes + * @return + * A string containing a lexical representation of xsd:hexBinary + * @throws IllegalArgumentException if {@code val} is null. + */ + public static String printHexBinary( byte[] val ) { + if (theConverter == null) initConverter(); + return theConverter.printHexBinary( val ); + } + + /** + * <p> + * Converts a long value into a string. + * @param val + * A long value + * @return + * A string containing a lexical representation of xsd:unsignedInt + */ + public static String printUnsignedInt( long val ) { + if (theConverter == null) initConverter(); + return theConverter.printUnsignedInt( val ); + } + + /** + * <p> + * Converts an int value into a string. + * @param val + * An int value + * @return + * A string containing a lexical representation of xsd:unsignedShort + */ + public static String printUnsignedShort( int val ) { + if (theConverter == null) initConverter(); + return theConverter.printUnsignedShort( val ); + } + + /** + * <p> + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:time + * @throws IllegalArgumentException if {@code val} is null. + */ + public static String printTime( java.util.Calendar val ) { + if (theConverter == null) initConverter(); + return theConverter.printTime( val ); + } + + /** + * <p> + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:date + * @throws IllegalArgumentException if {@code val} is null. + */ + public static String printDate( java.util.Calendar val ) { + if (theConverter == null) initConverter(); + return theConverter.printDate( val ); + } + + /** + * <p> + * Converts a string value into a string. + * @param val + * A string value + * @return + * A string containing a lexical representation of xsd:AnySimpleType + */ + public static String printAnySimpleType( String val ) { + if (theConverter == null) initConverter(); + return theConverter.printAnySimpleType( val ); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/DatatypeConverterImpl.java b/api/src/main/java/jakarta/xml/bind/DatatypeConverterImpl.java new file mode 100644 index 0000000..052ddb0 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/DatatypeConverterImpl.java
@@ -0,0 +1,1069 @@ +/* + * Copyright (c) 2007, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.DatatypeConfigurationException; + +/** + * This class is the Jakarta XML Binding CI's default implementation of the + * {@link DatatypeConverterInterface}. + * + * <p> + * When client applications specify the use of the static print/parse + * methods in {@link DatatypeConverter}, it will delegate + * to this class. + * + * <p> + * This class is responsible for whitespace normalization. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @since JAXB 2.1 + */ +final class DatatypeConverterImpl implements DatatypeConverterInterface { + + /** + * To avoid re-creating instances, we cache one instance. + */ + public static final DatatypeConverterInterface theInstance = new DatatypeConverterImpl(); + + protected DatatypeConverterImpl() { + } + + @Override + public String parseString(String lexicalXSDString) { + return lexicalXSDString; + } + + @Override + public BigInteger parseInteger(String lexicalXSDInteger) { + return _parseInteger(lexicalXSDInteger); + } + + public static BigInteger _parseInteger(CharSequence s) { + return new BigInteger(removeOptionalPlus(WhiteSpaceProcessor.trim(s)).toString()); + } + + @Override + public String printInteger(BigInteger val) { + return _printInteger(val); + } + + public static String _printInteger(BigInteger val) { + if (null == val) throw new IllegalArgumentException("val is null"); + return val.toString(); + } + + @Override + public int parseInt(String s) { + return _parseInt(s); + } + + /** + * Faster but less robust {@code String->int} conversion. + * <p> + * Note that: + * <ol> + * <li>XML Schema allows '+', but {@link Integer#valueOf(String)} is not. + * <li>XML Schema allows leading and trailing (but not in-between) whitespaces. + * {@link Integer#valueOf(String)} doesn't allow any. + * </ol> + */ + public static int _parseInt(CharSequence s) { + int len = s.length(); + int sign = 1; + + int r = 0; + + for (int i = 0; i < len; i++) { + char ch = s.charAt(i); + if (WhiteSpaceProcessor.isWhiteSpace(ch)) { + // skip whitespace + } else if ('0' <= ch && ch <= '9') { + r = r * 10 + (ch - '0'); + } else if (ch == '-') { + sign = -1; + } else if (ch == '+') { + // noop + } else { + throw new NumberFormatException("Not a number: " + s); + } + } + + return r * sign; + } + + @Override + public long parseLong(String lexicalXSLong) { + return _parseLong(lexicalXSLong); + } + + public static long _parseLong(CharSequence s) { + return Long.parseLong(removeOptionalPlus(WhiteSpaceProcessor.trim(s)).toString()); + } + + @Override + public short parseShort(String lexicalXSDShort) { + return _parseShort(lexicalXSDShort); + } + + public static short _parseShort(CharSequence s) { + return (short) _parseInt(s); + } + + @Override + public String printShort(short val) { + return _printShort(val); + } + + public static String _printShort(short val) { + return String.valueOf(val); + } + + @Override + public BigDecimal parseDecimal(String content) { + return _parseDecimal(content); + } + + public static BigDecimal _parseDecimal(CharSequence content) { + content = WhiteSpaceProcessor.trim(content); + + if (content.length() <= 0) { + return null; + } + + return new BigDecimal(content.toString()); + + // from purely XML Schema perspective, + // this implementation has a problem, since + // in xs:decimal "1.0" and "1" is equal whereas the above + // code will return different values for those two forms. + // + // the code was originally using com.sun.msv.datatype.xsd.NumberType.load, + // but a profiling showed that the process of normalizing "1.0" into "1" + // could take non-trivial time. + // + // also, from the user's point of view, one might be surprised if + // 1 (not 1.0) is returned from "1.000" + } + + @Override + public float parseFloat(String lexicalXSDFloat) { + return _parseFloat(lexicalXSDFloat); + } + + public static float _parseFloat(CharSequence _val) { + String s = WhiteSpaceProcessor.trim(_val).toString(); + /* Incompatibilities of XML Schema's float "xfloat" and Java's float "jfloat" + + * jfloat.valueOf ignores leading and trailing whitespaces, + whereas this is not allowed in xfloat. + * jfloat.valueOf allows "float type suffix" (f, F) to be + appended after float literal (e.g., 1.52e-2f), whereas + this is not the case of xfloat. + + gray zone + --------- + * jfloat allows ".523". And there is no clear statement that mentions + this case in xfloat. Although probably this is allowed. + * + */ + + if (s.equals("NaN")) { + return Float.NaN; + } + if (s.equals("INF")) { + return Float.POSITIVE_INFINITY; + } + if (s.equals("-INF")) { + return Float.NEGATIVE_INFINITY; + } + + if (s.isEmpty() + || !isDigitOrPeriodOrSign(s.charAt(0)) + || !isDigitOrPeriodOrSign(s.charAt(s.length() - 1))) { + throw new NumberFormatException(); + } + + // these screening process is necessary due to the wobble of Float.valueOf method + return Float.parseFloat(s); + } + + @Override + public String printFloat(float v) { + return _printFloat(v); + } + + public static String _printFloat(float v) { + if (Float.isNaN(v)) { + return "NaN"; + } + if (v == Float.POSITIVE_INFINITY) { + return "INF"; + } + if (v == Float.NEGATIVE_INFINITY) { + return "-INF"; + } + return String.valueOf(v); + } + + @Override + public double parseDouble(String lexicalXSDDouble) { + return _parseDouble(lexicalXSDDouble); + } + + public static double _parseDouble(CharSequence _val) { + String val = WhiteSpaceProcessor.trim(_val).toString(); + + if (val.equals("NaN")) { + return Double.NaN; + } + if (val.equals("INF")) { + return Double.POSITIVE_INFINITY; + } + if (val.equals("-INF")) { + return Double.NEGATIVE_INFINITY; + } + + if (val.isEmpty() + || !isDigitOrPeriodOrSign(val.charAt(0)) + || !isDigitOrPeriodOrSign(val.charAt(val.length() - 1))) { + throw new NumberFormatException(val); + } + + + // these screening process is necessary due to the wobble of Float.valueOf method + return Double.parseDouble(val); + } + + @Override + public boolean parseBoolean(String lexicalXSDBoolean) { + return _parseBoolean(lexicalXSDBoolean); + } + + public static Boolean _parseBoolean(CharSequence literal) { + if (literal == null) { + throw new IllegalArgumentException("String \"null\" is not valid boolean value."); + } + + int i = 0; + int len = literal.length(); + char ch; + boolean value = false; + + if (literal.length() <= 0) { + throw new IllegalArgumentException("String \"\" is not valid boolean value."); + } + + do { + ch = literal.charAt(i++); + } while (WhiteSpaceProcessor.isWhiteSpace(ch) && i < len); + + int strIndex = 0; + + switch (ch) { + case '1': + value = true; + break; + case '0': + value = false; + break; + case 't': + String strTrue = "rue"; + do { + ch = literal.charAt(i++); + } while ((strTrue.charAt(strIndex++) == ch) && i < len && strIndex < 3); + + if (strIndex == 3 && strTrue.charAt(strIndex - 1) == ch) { + value = true; + } else { + throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value."); + } + + break; + case 'f': + String strFalse = "alse"; + do { + ch = literal.charAt(i++); + } while ((strFalse.charAt(strIndex++) == ch) && i < len && strIndex < 4); + + + if (strIndex == 4 && strFalse.charAt(strIndex - 1) == ch) { + value = false; + } else { + throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value."); + } + + break; + } + + while (i < len && WhiteSpaceProcessor.isWhiteSpace(literal.charAt(i))) { + i++; + } + + if (i == len) { + return value; + } + throw new IllegalArgumentException("String \"" + literal + "\" is not valid boolean value."); + } + + @Override + public String printBoolean(boolean val) { + return val ? "true" : "false"; + } + + public static String _printBoolean(boolean val) { + return val ? "true" : "false"; + } + + @Override + public byte parseByte(String lexicalXSDByte) { + return _parseByte(lexicalXSDByte); + } + + public static byte _parseByte(CharSequence literal) { + return (byte) _parseInt(literal); + } + + @Override + public String printByte(byte val) { + return _printByte(val); + } + + public static String _printByte(byte val) { + return String.valueOf(val); + } + + @Override + public QName parseQName(String lexicalXSDQName, NamespaceContext nsc) { + return _parseQName(lexicalXSDQName, nsc); + } + + /** + * @return null if fails to convert. + */ + public static QName _parseQName(CharSequence text, NamespaceContext nsc) { + int length = text.length(); + + // trim whitespace + int start = 0; + while (start < length && WhiteSpaceProcessor.isWhiteSpace(text.charAt(start))) { + start++; + } + + int end = length; + while (end > start && WhiteSpaceProcessor.isWhiteSpace(text.charAt(end - 1))) { + end--; + } + + if (end == start) { + throw new IllegalArgumentException("input is empty"); + } + + + String uri; + String localPart; + String prefix; + + // search ':' + int idx = start + 1; // no point in searching the first char. that's not valid. + while (idx < end && text.charAt(idx) != ':') { + idx++; + } + + if (idx == end) { + uri = nsc.getNamespaceURI(""); + localPart = text.subSequence(start, end).toString(); + prefix = ""; + } else { + // Prefix exists, check everything + prefix = text.subSequence(start, idx).toString(); + localPart = text.subSequence(idx + 1, end).toString(); + uri = nsc.getNamespaceURI(prefix); + // uri can never be null according to javadoc, + // but some users reported that there are implementations that return null. + if (uri == null || uri.isEmpty()) // crap. the NamespaceContext interface is broken. + // error: unbound prefix + { + throw new IllegalArgumentException("prefix " + prefix + " is not bound to a namespace"); + } + } + + return new QName(uri, localPart, prefix); + } + + @Override + public Calendar parseDateTime(String lexicalXSDDateTime) { + return _parseDateTime(lexicalXSDDateTime); + } + + public static GregorianCalendar _parseDateTime(CharSequence s) { + String val = WhiteSpaceProcessor.trim(s).toString(); + return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar(); + } + + @Override + public String printDateTime(Calendar val) { + return _printDateTime(val); + } + + public static String _printDateTime(Calendar val) { + if (null == val) throw new IllegalArgumentException("val is null"); + return CalendarFormatter.doFormat("%Y-%M-%DT%h:%m:%s%z", val); + } + + @Override + public byte[] parseBase64Binary(String lexicalXSDBase64Binary) { + return _parseBase64Binary(lexicalXSDBase64Binary); + } + + @Override + public byte[] parseHexBinary(String s) { + final int len = s.length(); + + // "111" is not a valid hex encoding. + if (len % 2 != 0) { + throw new IllegalArgumentException("hexBinary needs to be even-length: " + s); + } + + byte[] out = new byte[len / 2]; + + for (int i = 0; i < len; i += 2) { + int h = hexToBin(s.charAt(i)); + int l = hexToBin(s.charAt(i + 1)); + if (h == -1 || l == -1) { + throw new IllegalArgumentException("contains illegal character for hexBinary: " + s); + } + + out[i / 2] = (byte) (h * 16 + l); + } + + return out; + } + + private static int hexToBin(char ch) { + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + if ('A' <= ch && ch <= 'F') { + return ch - 'A' + 10; + } + if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 10; + } + return -1; + } + private static final char[] hexCode = "0123456789ABCDEF".toCharArray(); + + @Override + public String printHexBinary(byte[] data) { + if (null == data) throw new IllegalArgumentException("data is null"); + StringBuilder r = new StringBuilder(data.length * 2); + for (byte b : data) { + r.append(hexCode[(b >> 4) & 0xF]); + r.append(hexCode[(b & 0xF)]); + } + return r.toString(); + } + + @Override + public long parseUnsignedInt(String lexicalXSDUnsignedInt) { + return _parseLong(lexicalXSDUnsignedInt); + } + + @Override + public String printUnsignedInt(long val) { + return _printLong(val); + } + + @Override + public int parseUnsignedShort(String lexicalXSDUnsignedShort) { + return _parseInt(lexicalXSDUnsignedShort); + } + + @Override + public Calendar parseTime(String lexicalXSDTime) { + return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime).toGregorianCalendar(); + } + + @Override + public String printTime(Calendar val) { + if (null == val) throw new IllegalArgumentException("val is null"); + return CalendarFormatter.doFormat("%h:%m:%s%z", val); + } + + @Override + public Calendar parseDate(String lexicalXSDDate) { + return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate).toGregorianCalendar(); + } + + @Override + public String printDate(Calendar val) { + return _printDate(val); + } + + public static String _printDate(Calendar val) { + if (null == val) throw new IllegalArgumentException("val is null"); + return CalendarFormatter.doFormat("%Y-%M-%D%z",val); + } + + @Override + public String parseAnySimpleType(String lexicalXSDAnySimpleType) { + return lexicalXSDAnySimpleType; +// return (String)SimpleURType.theInstance._createValue( lexicalXSDAnySimpleType, null ); + } + + @Override + public String printString(String val) { +// return StringType.theInstance.convertToLexicalValue( val, null ); + return val; + } + + @Override + public String printInt(int val) { + return _printInt(val); + } + + public static String _printInt(int val) { + return String.valueOf(val); + } + + @Override + public String printLong(long val) { + return _printLong(val); + } + + public static String _printLong(long val) { + return String.valueOf(val); + } + + @Override + public String printDecimal(BigDecimal val) { + return _printDecimal(val); + } + + public static String _printDecimal(BigDecimal val) { + if (null == val) throw new IllegalArgumentException("val is null"); + return val.toPlainString(); + } + + @Override + public String printDouble(double v) { + return _printDouble(v); + } + + public static String _printDouble(double v) { + if (Double.isNaN(v)) { + return "NaN"; + } + if (v == Double.POSITIVE_INFINITY) { + return "INF"; + } + if (v == Double.NEGATIVE_INFINITY) { + return "-INF"; + } + return String.valueOf(v); + } + + @Override + public String printQName(QName val, NamespaceContext nsc) { + return _printQName(val, nsc); + } + + public static String _printQName(QName val, NamespaceContext nsc) { + // Double-check + String qname; + String prefix = nsc.getPrefix(val.getNamespaceURI()); + String localPart = val.getLocalPart(); + + if (prefix == null || prefix.isEmpty()) { // be defensive + qname = localPart; + } else { + qname = prefix + ':' + localPart; + } + + return qname; + } + + @Override + public String printBase64Binary(byte[] val) { + return _printBase64Binary(val); + } + + @Override + public String printUnsignedShort(int val) { + return String.valueOf(val); + } + + @Override + public String printAnySimpleType(String val) { + return val; + } + + /** + * Just return the string passed as a parameter but + * installs an instance of this class as the DatatypeConverter + * implementation. Used from static fixed value initializers. + */ + public static String installHook(String s) { + DatatypeConverter.setDatatypeConverter(theInstance); + return s; + } +// base64 decoder + private static final byte[] decodeMap = initDecodeMap(); + private static final byte PADDING = 127; + + private static byte[] initDecodeMap() { + byte[] map = new byte[128]; + int i; + for (i = 0; i < 128; i++) { + map[i] = -1; + } + + for (i = 'A'; i <= 'Z'; i++) { + map[i] = (byte) (i - 'A'); + } + for (i = 'a'; i <= 'z'; i++) { + map[i] = (byte) (i - 'a' + 26); + } + for (i = '0'; i <= '9'; i++) { + map[i] = (byte) (i - '0' + 52); + } + map['+'] = 62; + map['/'] = 63; + map['='] = PADDING; + + return map; + } + + /** + * computes the length of binary data speculatively. + * + * <p> + * Our requirement is to create byte[] of the exact length to store the binary data. + * If we do this in a straight-forward way, it takes two passes over the data. + * Experiments show that this is a non-trivial overhead (35% or so is spent on + * the first pass in calculating the length.) + * + * <p> + * So the approach here is that we compute the length speculatively, without looking + * at the whole contents. The obtained speculative value is never less than the + * actual length of the binary data, but it may be bigger. So if the speculation + * goes wrong, we'll pay the cost of reallocation and buffer copying. + * + * <p> + * If the base64 text is tightly packed with no indentation nor illegal char + * (like what most web services produce), then the speculation of this method + * will be correct, so we get the performance benefit. + */ + private static int guessLength(String text) { + final int len = text.length(); + + // compute the tail '=' chars + int j = len - 1; + for (; j >= 0; j--) { + byte code = decodeMap[text.charAt(j)]; + if (code == PADDING) { + continue; + } + if (code == -1) // most likely this base64 text is indented. go with the upper bound + { + return text.length() / 4 * 3; + } + break; + } + + j++; // text.charAt(j) is now at some base64 char, so +1 to make it the size + int padSize = len - j; + if (padSize > 2) // something is wrong with base64. be safe and go with the upper bound + { + return text.length() / 4 * 3; + } + + // so far this base64 looks like it's unindented tightly packed base64. + // take a chance and create an array with the expected size + return text.length() / 4 * 3 - padSize; + } + + /** + * @param text + * base64Binary data is likely to be long, and decoding requires + * each character to be accessed twice (once for counting length, another + * for decoding.) + * <p> + * A benchmark showed that taking {@link String} is faster, presumably + * because JIT can inline a lot of string access (with data of 1K chars, it was twice as fast) + */ + public static byte[] _parseBase64Binary(String text) { + final int buflen = guessLength(text); + if (buflen < 3) { + throw new IllegalArgumentException("base64 text invalid."); + } + final byte[] out = new byte[buflen]; + int o = 0; + + final int len = text.length(); + int i; + + final byte[] quadruplet = new byte[4]; + int q = 0; + + // convert each quadruplet to three bytes. + for (i = 0; i < len; i++) { + char ch = text.charAt(i); + byte v = decodeMap[ch]; + + if (v != -1) { + quadruplet[q++] = v; + } + + if (q == 4) { + + // quadruplet is now filled. + out[o++] = (byte) ((quadruplet[0] << 2) | (quadruplet[1] >> 4)); + if (quadruplet[2] != PADDING) { + out[o++] = (byte) ((quadruplet[1] << 4) | (quadruplet[2] >> 2)); + } + if (quadruplet[3] != PADDING) { + out[o++] = (byte) ((quadruplet[2] << 6) | (quadruplet[3])); + } + q = 0; + } + } + + if (buflen == o) // speculation worked out to be OK + { + return out; + } + + // we overestimated, so need to create a new buffer + byte[] nb = new byte[o]; + System.arraycopy(out, 0, nb, 0, o); + return nb; + } + private static final char[] encodeMap = initEncodeMap(); + + private static char[] initEncodeMap() { + char[] map = new char[64]; + int i; + for (i = 0; i < 26; i++) { + map[i] = (char) ('A' + i); + } + for (i = 26; i < 52; i++) { + map[i] = (char) ('a' + (i - 26)); + } + for (i = 52; i < 62; i++) { + map[i] = (char) ('0' + (i - 52)); + } + map[62] = '+'; + map[63] = '/'; + + return map; + } + + public static char encode(int i) { + return encodeMap[i & 0x3F]; + } + + public static byte encodeByte(int i) { + return (byte) encodeMap[i & 0x3F]; + } + + public static String _printBase64Binary(byte[] input) { + if (null == input) throw new IllegalArgumentException("input is null"); + return _printBase64Binary(input, 0, input.length); + } + + public static String _printBase64Binary(byte[] input, int offset, int len) { + char[] buf = new char[((len + 2) / 3) * 4]; + int ptr = _printBase64Binary(input, offset, len, buf, 0); + assert ptr == buf.length; + return new String(buf); + } + + /** + * Encodes a byte array into a char array by doing base64 encoding. + * <p> + * The caller must supply a big enough buffer. + * + * @return + * the value of {@code ptr+((len+2)/3)*4}, which is the new offset + * in the output buffer where the further bytes should be placed. + */ + public static int _printBase64Binary(byte[] input, int offset, int len, char[] buf, int ptr) { + // encode elements until only 1 or 2 elements are left to encode + int remaining = len; + int i; + for (i = offset;remaining >= 3; remaining -= 3, i += 3) { + buf[ptr++] = encode(input[i] >> 2); + buf[ptr++] = encode( + ((input[i] & 0x3) << 4) + | ((input[i + 1] >> 4) & 0xF)); + buf[ptr++] = encode( + ((input[i + 1] & 0xF) << 2) + | ((input[i + 2] >> 6) & 0x3)); + buf[ptr++] = encode(input[i + 2] & 0x3F); + } + // encode when exactly 1 element (left) to encode + if (remaining == 1) { + buf[ptr++] = encode(input[i] >> 2); + buf[ptr++] = encode(((input[i]) & 0x3) << 4); + buf[ptr++] = '='; + buf[ptr++] = '='; + } + // encode when exactly 2 elements (left) to encode + if (remaining == 2) { + buf[ptr++] = encode(input[i] >> 2); + buf[ptr++] = encode(((input[i] & 0x3) << 4) + | ((input[i + 1] >> 4) & 0xF)); + buf[ptr++] = encode((input[i + 1] & 0xF) << 2); + buf[ptr++] = '='; + } + return ptr; + } + + /** + * Encodes a byte array into another byte array by first doing base64 encoding + * then encoding the result in ASCII. + * <p> + * The caller must supply a big enough buffer. + * + * @return + * the value of {@code ptr+((len+2)/3)*4}, which is the new offset + * in the output buffer where the further bytes should be placed. + */ + public static int _printBase64Binary(byte[] input, int offset, int len, byte[] out, int ptr) { + byte[] buf = out; + int remaining = len; + int i; + for (i=offset; remaining >= 3; remaining -= 3, i += 3 ) { + buf[ptr++] = encodeByte(input[i]>>2); + buf[ptr++] = encodeByte( + ((input[i]&0x3)<<4) | + ((input[i+1]>>4)&0xF)); + buf[ptr++] = encodeByte( + ((input[i+1]&0xF)<<2)| + ((input[i+2]>>6)&0x3)); + buf[ptr++] = encodeByte(input[i+2]&0x3F); + } + // encode when exactly 1 element (left) to encode + if (remaining == 1) { + buf[ptr++] = encodeByte(input[i]>>2); + buf[ptr++] = encodeByte(((input[i])&0x3)<<4); + buf[ptr++] = '='; + buf[ptr++] = '='; + } + // encode when exactly 2 elements (left) to encode + if (remaining == 2) { + buf[ptr++] = encodeByte(input[i]>>2); + buf[ptr++] = encodeByte( + ((input[i]&0x3)<<4) | + ((input[i+1]>>4)&0xF)); + buf[ptr++] = encodeByte((input[i+1]&0xF)<<2); + buf[ptr++] = '='; + } + + return ptr; + } + + private static CharSequence removeOptionalPlus(CharSequence s) { + int len = s.length(); + + if (len <= 1 || s.charAt(0) != '+') { + return s; + } + + s = s.subSequence(1, len); + char ch = s.charAt(0); + if ('0' <= ch && ch <= '9') { + return s; + } + if ('.' == ch) { + return s; + } + + throw new NumberFormatException(); + } + + private static boolean isDigitOrPeriodOrSign(char ch) { + if ('0' <= ch && ch <= '9') { + return true; + } + if (ch == '+' || ch == '-' || ch == '.') { + return true; + } + return false; + } + private static final DatatypeFactory datatypeFactory; + + static { + try { + datatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new Error(e); + } + } + + private static final class CalendarFormatter { + + public static String doFormat(String format, Calendar cal) throws IllegalArgumentException { + int fidx = 0; + int flen = format.length(); + StringBuilder buf = new StringBuilder(); + + while (fidx < flen) { + char fch = format.charAt(fidx++); + + if (fch != '%') { // not a meta character + buf.append(fch); + continue; + } + + // seen meta character. we don't do error check against the format + switch (format.charAt(fidx++)) { + case 'Y': // year + formatYear(cal, buf); + break; + + case 'M': // month + formatMonth(cal, buf); + break; + + case 'D': // days + formatDays(cal, buf); + break; + + case 'h': // hours + formatHours(cal, buf); + break; + + case 'm': // minutes + formatMinutes(cal, buf); + break; + + case 's': // parse seconds. + formatSeconds(cal, buf); + break; + + case 'z': // time zone + formatTimeZone(cal, buf); + break; + + default: + // illegal meta character. impossible. + throw new InternalError(); + } + } + + return buf.toString(); + } + + private static void formatYear(Calendar cal, StringBuilder buf) { + int year = cal.get(Calendar.YEAR); + + String s; + if (year <= 0) // negative value + { + s = Integer.toString(1 - year); + } else // positive value + { + s = Integer.toString(year); + } + + while (s.length() < 4) { + s = '0' + s; + } + if (year <= 0) { + s = '-' + s; + } + + buf.append(s); + } + + private static void formatMonth(Calendar cal, StringBuilder buf) { + formatTwoDigits(cal.get(Calendar.MONTH) + 1, buf); + } + + private static void formatDays(Calendar cal, StringBuilder buf) { + formatTwoDigits(cal.get(Calendar.DAY_OF_MONTH), buf); + } + + private static void formatHours(Calendar cal, StringBuilder buf) { + formatTwoDigits(cal.get(Calendar.HOUR_OF_DAY), buf); + } + + private static void formatMinutes(Calendar cal, StringBuilder buf) { + formatTwoDigits(cal.get(Calendar.MINUTE), buf); + } + + private static void formatSeconds(Calendar cal, StringBuilder buf) { + formatTwoDigits(cal.get(Calendar.SECOND), buf); + if (cal.isSet(Calendar.MILLISECOND)) { // milliseconds + int n = cal.get(Calendar.MILLISECOND); + if (n != 0) { + String ms = Integer.toString(n); + while (ms.length() < 3) { + ms = '0' + ms; // left 0 paddings. + } + buf.append('.'); + buf.append(ms); + } + } + } + + /** formats time zone specifier. */ + private static void formatTimeZone(Calendar cal, StringBuilder buf) { + TimeZone tz = cal.getTimeZone(); + + if (tz == null) { + return; + } + + // otherwise print out normally. + int offset = tz.getOffset(cal.getTime().getTime()); + + if (offset == 0) { + buf.append('Z'); + return; + } + + if (offset >= 0) { + buf.append('+'); + } else { + buf.append('-'); + offset *= -1; + } + + offset /= 60 * 1000; // offset is in milliseconds + + formatTwoDigits(offset / 60, buf); + buf.append(':'); + formatTwoDigits(offset % 60, buf); + } + + /** formats Integer into two-character-wide string. */ + private static void formatTwoDigits(int n, StringBuilder buf) { + // n is always non-negative. + if (n < 10) { + buf.append('0'); + } + buf.append(n); + } + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/DatatypeConverterInterface.java b/api/src/main/java/jakarta/xml/bind/DatatypeConverterInterface.java new file mode 100644 index 0000000..38885da --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/DatatypeConverterInterface.java
@@ -0,0 +1,469 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * <p> + * The DatatypeConverterInterface is for Jakarta XML Binding provider use only. A + * Jakarta XML Binding provider must supply a class that implements this interface. + * Jakarta XML Binding Providers are required to call the + * {@link DatatypeConverter#setDatatypeConverter(DatatypeConverterInterface) + * DatatypeConverter.setDatatypeConverter} api at + * some point before the first marshal or unmarshal operation (perhaps during + * the call to JAXBContext.newInstance). This step is necessary to configure + * the converter that should be used to perform the print and parse + * functionality. Calling this api repeatedly will have no effect - the + * DatatypeConverter instance passed into the first invocation is the one that + * will be used from then on. + * + * <p> + * This interface defines the parse and print methods. There is one + * parse and print method for each XML schema datatype specified in the + * the default binding Table 5-1 in the Jakarta XML Binding specification. + * + * <p> + * The parse and print methods defined here are invoked by the static parse + * and print methods defined in the {@link DatatypeConverter DatatypeConverter} + * class. + * + * <p> + * A parse method for an XML schema datatype must be capable of converting any + * lexical representation of the XML schema datatype ( specified by the + * <a href="http://www.w3.org/TR/xmlschema-2/"> XML Schema Part2: Datatypes + * specification</a> into a value in the value space of the XML schema datatype. + * If an error is encountered during conversion, then an IllegalArgumentException + * or a subclass of IllegalArgumentException must be thrown by the method. + * + * <p> + * A print method for an XML schema datatype can output any lexical + * representation that is valid with respect to the XML schema datatype. + * If an error is encountered during conversion, then an IllegalArgumentException, + * or a subclass of IllegalArgumentException must be thrown by the method. + * + * <p> + * The prefix xsd: is used to refer to XML schema datatypes + * <a href="http://www.w3.org/TR/xmlschema-2/"> XML Schema Part2: Datatypes + * specification.</a> + * + * @author <ul> + * <li>Sekhar Vajjhala, Sun Microsystems, Inc.</li> + * <li>Joe Fialli, Sun Microsystems Inc.</li> + * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li> + * <li>Ryan Shoemaker,Sun Microsystems Inc.</li> + * </ul> + * @see DatatypeConverter + * @see ParseConversionEvent + * @see PrintConversionEvent + * @since 1.6, JAXB 1.0 + */ + +public interface DatatypeConverterInterface { + /** + * Convert the string argument into a string. + * @param lexicalXSDString + * A lexical representation of the XML Schema datatype xsd:string + * @return + * A string that is the same as the input string. + */ + String parseString(String lexicalXSDString); + + /** + * Convert the string argument into a BigInteger value. + * @param lexicalXSDInteger + * A string containing a lexical representation of + * xsd:integer. + * @return + * A BigInteger value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDInteger} is not a valid string representation of a {@link java.math.BigInteger} value. + */ + java.math.BigInteger parseInteger(String lexicalXSDInteger); + + /** + * Convert the string argument into an int value. + * @param lexicalXSDInt + * A string containing a lexical representation of + * xsd:int. + * @return + * An int value represented byte the string argument. + * @throws NumberFormatException {@code lexicalXSDInt} is not a valid string representation of an {@code int} value. + */ + int parseInt(String lexicalXSDInt); + + /** + * Converts the string argument into a long value. + * @param lexicalXSDLong + * A string containing lexical representation of + * xsd:long. + * @return + * A long value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDLong} is not a valid string representation of a {@code long} value. + */ + long parseLong(String lexicalXSDLong); + + /** + * Converts the string argument into a short value. + * @param lexicalXSDShort + * A string containing lexical representation of + * xsd:short. + * @return + * A short value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDShort} is not a valid string representation of a {@code short} value. + */ + short parseShort(String lexicalXSDShort); + + /** + * Converts the string argument into a BigDecimal value. + * @param lexicalXSDDecimal + * A string containing lexical representation of + * xsd:decimal. + * @return + * A BigDecimal value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDDecimal} is not a valid string representation of {@link java.math.BigDecimal}. + */ + java.math.BigDecimal parseDecimal(String lexicalXSDDecimal); + + /** + * Converts the string argument into a float value. + * @param lexicalXSDFloat + * A string containing lexical representation of + * xsd:float. + * @return + * A float value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDFloat} is not a valid string representation of a {@code float} value. + */ + float parseFloat(String lexicalXSDFloat); + + /** + * Converts the string argument into a double value. + * @param lexicalXSDDouble + * A string containing lexical representation of + * xsd:double. + * @return + * A double value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDDouble} is not a valid string representation of a {@code double} value. + */ + double parseDouble(String lexicalXSDDouble); + + /** + * Converts the string argument into a boolean value. + * @param lexicalXSDBoolean + * A string containing lexical representation of + * xsd:boolean. + * @return + * A boolean value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:boolean. + */ + boolean parseBoolean(String lexicalXSDBoolean); + + /** + * Converts the string argument into a byte value. + * @param lexicalXSDByte + * A string containing lexical representation of + * xsd:byte. + * @return + * A byte value represented by the string argument. + * @throws NumberFormatException {@code lexicalXSDByte} does not contain a parseable byte. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:byte. + */ + byte parseByte(String lexicalXSDByte); + + /** + * Converts the string argument into a QName value. + * + * <p> + * String parameter {@code lexicalXSDQname} must conform to lexical value space specifed at + * <a href="http://www.w3.org/TR/xmlschema-2/#QName">XML Schema Part 2:Datatypes specification:QNames</a> + * + * @param lexicalXSDQName + * A string containing lexical representation of xsd:QName. + * @param nsc + * A namespace context for interpreting a prefix within a QName. + * @return + * A QName value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to XML Schema Part 2 specification or + * if namespace prefix of {@code lexicalXSDQname} is not bound to a URI in NamespaceContext {@code nsc}. + */ + javax.xml.namespace.QName parseQName(String lexicalXSDQName, + javax.xml.namespace.NamespaceContext nsc); + + /** + * Converts the string argument into a Calendar value. + * @param lexicalXSDDateTime + * A string containing lexical representation of + * xsd:datetime. + * @return + * A Calendar object represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:dateTime. + */ + java.util.Calendar parseDateTime(String lexicalXSDDateTime); + + /** + * Converts the string argument into an array of bytes. + * @param lexicalXSDBase64Binary + * A string containing lexical representation + * of xsd:base64Binary. + * @return + * An array of bytes represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:base64Binary + */ + byte[] parseBase64Binary(String lexicalXSDBase64Binary); + + /** + * Converts the string argument into an array of bytes. + * @param lexicalXSDHexBinary + * A string containing lexical representation of + * xsd:hexBinary. + * @return + * An array of bytes represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:hexBinary. + */ + byte[] parseHexBinary(String lexicalXSDHexBinary); + + /** + * Converts the string argument into a long value. + * @param lexicalXSDUnsignedInt + * A string containing lexical representation + * of xsd:unsignedInt. + * @return + * A long value represented by the string argument. + * @throws NumberFormatException if string parameter can not be parsed into a {@code long} value. + */ + long parseUnsignedInt(String lexicalXSDUnsignedInt); + + /** + * Converts the string argument into an int value. + * @param lexicalXSDUnsignedShort + * A string containing lexical + * representation of xsd:unsignedShort. + * @return + * An int value represented by the string argument. + * @throws NumberFormatException if string parameter can not be parsed into an {@code int} value. + */ + int parseUnsignedShort(String lexicalXSDUnsignedShort); + + /** + * Converts the string argument into a Calendar value. + * @param lexicalXSDTime + * A string containing lexical representation of + * xsd:Time. + * @return + * A Calendar value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Time. + */ + java.util.Calendar parseTime(String lexicalXSDTime); + + /** + * Converts the string argument into a Calendar value. + * @param lexicalXSDDate + * A string containing lexical representation of + * xsd:Date. + * @return + * A Calendar value represented by the string argument. + * @throws IllegalArgumentException if string parameter does not conform to lexical value space defined in XML Schema Part 2: Datatypes for xsd:Date. + */ + java.util.Calendar parseDate(String lexicalXSDDate); + + /** + * Return a string containing the lexical representation of the + * simple type. + * @param lexicalXSDAnySimpleType + * A string containing lexical + * representation of the simple type. + * @return + * A string containing the lexical representation of the + * simple type. + */ + String parseAnySimpleType(String lexicalXSDAnySimpleType); + + /** + * Converts the string argument into a string. + * @param val + * A string value. + * @return + * A string containing a lexical representation of xsd:string + */ + String printString(String val); + + /** + * Converts a BigInteger value into a string. + * @param val + * A BigInteger value + * @return + * A string containing a lexical representation of xsd:integer + * @throws IllegalArgumentException {@code val} is null. + */ + String printInteger(java.math.BigInteger val); + + /** + * Converts an int value into a string. + * @param val + * An int value + * @return + * A string containing a lexical representation of xsd:int + */ + String printInt(int val); + + + /** + * Converts a long value into a string. + * @param val + * A long value + * @return + * A string containing a lexical representation of xsd:long + */ + String printLong(long val); + + /** + * Converts a short value into a string. + * @param val + * A short value + * @return + * A string containing a lexical representation of xsd:short + */ + String printShort(short val); + + /** + * Converts a BigDecimal value into a string. + * @param val + * A BigDecimal value + * @return + * A string containing a lexical representation of xsd:decimal + * @throws IllegalArgumentException {@code val} is null. + */ + String printDecimal(java.math.BigDecimal val); + + /** + * Converts a float value into a string. + * @param val + * A float value + * @return + * A string containing a lexical representation of xsd:float + */ + String printFloat(float val); + + /** + * Converts a double value into a string. + * @param val + * A double value + * @return + * A string containing a lexical representation of xsd:double + */ + String printDouble(double val); + + /** + * Converts a boolean value into a string. + * @param val + * A boolean value + * @return + * A string containing a lexical representation of xsd:boolean + */ + String printBoolean(boolean val); + + /** + * Converts a byte value into a string. + * @param val + * A byte value + * @return + * A string containing a lexical representation of xsd:byte + */ + String printByte(byte val); + + /** + * Converts a QName instance into a string. + * @param val + * A QName value + * @param nsc + * A namespace context for interpreting a prefix within a QName. + * @return + * A string containing a lexical representation of QName + * @throws IllegalArgumentException if {@code val} is null or + * if {@code nsc} is non-null or {@code nsc.getPrefix(nsprefixFromVal)} is null. + */ + String printQName(javax.xml.namespace.QName val, + javax.xml.namespace.NamespaceContext nsc); + + /** + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:dateTime + * @throws IllegalArgumentException if {@code val} is null. + */ + String printDateTime(java.util.Calendar val); + + /** + * Converts an array of bytes into a string. + * @param val + * an array of bytes + * @return + * A string containing a lexical representation of xsd:base64Binary + * @throws IllegalArgumentException if {@code val} is null. + */ + String printBase64Binary(byte[] val); + + /** + * Converts an array of bytes into a string. + * @param val + * an array of bytes + * @return + * A string containing a lexical representation of xsd:hexBinary + * @throws IllegalArgumentException if {@code val} is null. + */ + String printHexBinary(byte[] val); + + /** + * Converts a long value into a string. + * @param val + * A long value + * @return + * A string containing a lexical representation of xsd:unsignedInt + */ + String printUnsignedInt(long val); + + /** + * Converts an int value into a string. + * @param val + * An int value + * @return + * A string containing a lexical representation of xsd:unsignedShort + */ + String printUnsignedShort(int val); + + /** + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:time + * @throws IllegalArgumentException if {@code val} is null. + */ + String printTime(java.util.Calendar val); + + /** + * Converts a Calendar value into a string. + * @param val + * A Calendar value + * @return + * A string containing a lexical representation of xsd:date + * @throws IllegalArgumentException if {@code val} is null. + */ + String printDate(java.util.Calendar val); + + /** + * Converts a string value into a string. + * @param val + * A string value + * @return + * A string containing a lexical representation of xsd:AnySimpleType + */ + String printAnySimpleType(String val); +}
diff --git a/api/src/main/java/jakarta/xml/bind/Element.java b/api/src/main/java/jakarta/xml/bind/Element.java new file mode 100644 index 0000000..a23ca10 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/Element.java
@@ -0,0 +1,27 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This is an element marker interface. + * <p> + * Under certain circumstances, it is necessary for the binding compiler to + * generate derived java content classes that implement this interface. In + * those cases, client applications must supply element instances rather than + * types of elements. For more detail, see section 5.7 "Element Declaration" + * and 5.7.1 "Bind to Java Element Interface" of the specification. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @since 1.6, JAXB 1.0 + */ + +public interface Element { +}
diff --git a/api/src/main/java/jakarta/xml/bind/GetPropertyAction.java b/api/src/main/java/jakarta/xml/bind/GetPropertyAction.java new file mode 100644 index 0000000..607eda3 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/GetPropertyAction.java
@@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.security.PrivilegedAction; + +/** + * {@link PrivilegedAction} that gets the system property value. + * @author Kohsuke Kawaguchi + */ +final class GetPropertyAction implements PrivilegedAction<String> { + private final String propertyName; + + public GetPropertyAction(String propertyName) { + this.propertyName = propertyName; + } + + @Override + public String run() { + return System.getProperty(propertyName); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXB.java b/api/src/main/java/jakarta/xml/bind/JAXB.java new file mode 100644 index 0000000..0e99cf2 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXB.java
@@ -0,0 +1,614 @@ +/* + * Copyright (c) 2006, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import jakarta.xml.bind.annotation.XmlRootElement; +import javax.xml.namespace.QName; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.lang.ref.WeakReference; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; + +/** + * Class that defines convenience methods for common, simple use of Jakarta XML Binding. + * + * <p> + * Methods defined in this class are convenience methods that combine several basic operations + * in the {@link JAXBContext}, {@link Unmarshaller}, and {@link Marshaller}. + * + * They are designed + * to be the preferred methods for developers new to Jakarta XML Binding. They have + * the following characteristics: + * + * <ol> + * <li>Generally speaking, the performance is not necessarily optimal. + * It is expected that people who need to write performance + * critical code will use the rest of the Jakarta XML Binding API directly. + * <li>Errors that happen during the processing is wrapped into + * {@link DataBindingException} (which will have {@link JAXBException} + * as its {@link Throwable#getCause() cause}. It is expected that + * people who prefer the checked exception would use + * the rest of the Jakarta XML Binding API directly. + * </ol> + * + * <p> + * In addition, the {@code unmarshal} methods have the following characteristic: + * + * <ol> + * <li>Schema validation is not performed on the input XML. + * The processing will try to continue even if there + * are errors in the XML, as much as possible. Only as + * the last resort, this method fails with {@link DataBindingException}. + * </ol> + * + * <p> + * Similarly, the {@code marshal} methods have the following characteristic: + * <ol> + * <li>The processing will try to continue even if the Java object tree + * does not meet the validity requirement. Only as + * the last resort, this method fails with {@link DataBindingException}. + * </ol> + * + * + * <p> + * All the methods on this class require non-null arguments to all parameters. + * The {@code unmarshal} methods either fail with an exception or return + * a non-null value. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.1 + */ +public final class JAXB { + /** + * No instantiation is allowed. + */ + private JAXB() {} + + /** + * To improve the performance, we'll cache the last {@link JAXBContext} used. + */ + private static final class Cache { + final Class<?> type; + final JAXBContext context; + + public Cache(Class<?> type) throws JAXBException { + this.type = type; + this.context = JAXBContext.newInstance(type); + } + } + + /** + * Cache. We don't want to prevent the {@link Cache#type} from GC-ed, + * hence {@link WeakReference}. + */ + private static volatile WeakReference<Cache> cache; + + /** + * Obtains the {@link JAXBContext} from the given type, + * by using the cache if possible. + * + * <p> + * We don't use locks to control access to {@link #cache}, but this code + * should be thread-safe thanks to the immutable {@link Cache} and {@code volatile}. + */ + private static <T> JAXBContext getContext(Class<T> type) throws JAXBException { + WeakReference<Cache> c = cache; + if(c!=null) { + Cache d = c.get(); + if(d!=null && d.type==type) + return d.context; + } + + // overwrite the cache + Cache d = new Cache(type); + cache = new WeakReference<>(d); + + return d.context; + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * Reads the entire file as XML. + */ + public static <T> T unmarshal( File xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(new StreamSource(xml), type); + return item.getValue(); + } catch (JAXBException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The resource pointed by the URL is read in its entirety. + */ + public static <T> T unmarshal( URL xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The URI is {@link URI#toURL() turned into URL} and then + * follows the handling of {@code URL}. + */ + public static <T> T unmarshal( URI xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The string is first interpreted as an absolute {@code URI}. + * If it's not {@link URI#isAbsolute() a valid absolute URI}, + * then it's interpreted as a {@code File} + */ + public static <T> T unmarshal( String xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The entire stream is read as an XML infoset. + * Upon a successful completion, the stream will be closed by this method. + */ + public static <T> T unmarshal( InputStream xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The character stream is read as an XML infoset. + * The encoding declaration in the XML will be ignored. + * Upon a successful completion, the stream will be closed by this method. + */ + public static <T> T unmarshal( Reader xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + /** + * Reads in a Java object tree from the given XML input. + * + * @param xml + * The XML infoset that the {@link Source} represents is read. + */ + public static <T> T unmarshal( Source xml, Class<T> type ) { + try { + JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type); + return item.getValue(); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + + + /** + * Creates {@link Source} from various XML representation. + * See {@link #unmarshal} for the conversion rules. + */ + private static Source toSource(Object xml) throws IOException { + if(xml==null) + throw new IllegalArgumentException("no XML is given"); + + if (xml instanceof String) { + try { + xml=new URI((String)xml); + } catch (URISyntaxException e) { + xml=new File((String)xml); + } + } + if (xml instanceof File) { + File file = (File) xml; + return new StreamSource(file); + } + if (xml instanceof URI) { + URI uri = (URI) xml; + xml=uri.toURL(); + } + if (xml instanceof URL) { + URL url = (URL) xml; + return new StreamSource(url.toExternalForm()); + } + if (xml instanceof InputStream) { + InputStream in = (InputStream) xml; + return new StreamSource(in); + } + if (xml instanceof Reader) { + Reader r = (Reader) xml; + return new StreamSource(r); + } + if (xml instanceof Source) { + return (Source) xml; + } + throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass()); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * XML will be written to this file. If it already exists, + * it will be overwritten. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, File xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The XML will be {@link URLConnection#getOutputStream() sent} to the + * resource pointed by this URL. Note that not all {@code URL}s support + * such operation, and exact semantics depends on the {@code URL} + * implementations. In case of {@link HttpURLConnection HTTP URLs}, + * this will perform HTTP POST. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, URL xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The URI is {@link URI#toURL() turned into URL} and then + * follows the handling of {@code URL}. See above. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, URI xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The string is first interpreted as an absolute {@code URI}. + * If it's not {@link URI#isAbsolute() a valid absolute URI}, + * then it's interpreted as a {@code File} + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, String xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The XML will be sent to the given {@link OutputStream}. + * Upon a successful completion, the stream will be closed by this method. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, OutputStream xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The XML will be sent as a character stream to the given {@link Writer}. + * Upon a successful completion, the stream will be closed by this method. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, Writer xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * The XML will be sent to the {@link Result} object. + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + public static void marshal( Object jaxbObject, Result xml ) { + _marshal(jaxbObject,xml); + } + + /** + * Writes a Java object tree to XML and store it to the specified location. + * + * <p> + * This method is a convenience method that combines several basic operations + * in the {@link JAXBContext} and {@link Marshaller}. This method is designed + * to be the preferred method for developers new to Jakarta XML Binding. This method + * has the following characteristics: + * + * <ol> + * <li>Generally speaking, the performance is not necessarily optimal. + * It is expected that those people who need to write performance + * critical code will use the rest of the Jakarta XML Binding API directly. + * <li>Errors that happen during the processing is wrapped into + * {@link DataBindingException} (which will have {@link JAXBException} + * as its {@link Throwable#getCause() cause}. It is expected that + * those people who prefer the checked exception would use + * the rest of the Jakarta XML Binding API directly. + * </ol> + * + * @param jaxbObject + * The Java object to be marshalled into XML. If this object is + * a {@link JAXBElement}, it will provide the root tag name and + * the body. If this object has {@link XmlRootElement} + * on its class definition, that will be used as the root tag name + * and the given object will provide the body. Otherwise, + * the root tag name is inferred from + * {@link Class#getSimpleName() the short class name}. + * This parameter must not be null. + * + * @param xml + * Represents the receiver of XML. Objects of the following types are allowed. + * + * <table> + * <caption>Allowed Objects</caption> + * <tr> + * <th>Type</th> + * <th>Operation</th> + * </tr><tr> + * <td>{@link File}</td> + * <td>XML will be written to this file. If it already exists, + * it will be overwritten.</td> + * </tr><tr> + * <td>{@link URL}</td> + * <td>The XML will be {@link URLConnection#getOutputStream() sent} to the + * resource pointed by this URL. Note that not all {@code URL}s support + * such operation, and exact semantics depends on the {@code URL} + * implementations. In case of {@link HttpURLConnection HTTP URLs}, + * this will perform HTTP POST.</td> + * </tr><tr> + * <td>{@link URI}</td> + * <td>The URI is {@link URI#toURL() turned into URL} and then + * follows the handling of {@code URL}. See above.</td> + * </tr><tr> + * <td>{@link String}</td> + * <td>The string is first interpreted as an absolute {@code URI}. + * If it's not {@link URI#isAbsolute() a valid absolute URI}, + * then it's interpreted as a {@code File}</td> + * </tr><tr> + * <td>{@link OutputStream}</td> + * <td>The XML will be sent to the given {@link OutputStream}. + * Upon a successful completion, the stream will be closed by this method.</td> + * </tr><tr> + * <td>{@link Writer}</td> + * <td>The XML will be sent as a character stream to the given {@link Writer}. + * Upon a successful completion, the stream will be closed by this method.</td> + * </tr><tr> + * <td>{@link Result}</td> + * <td>The XML will be sent to the {@link Result} object.</td> + * </tr></table> + * + * @throws DataBindingException + * If the operation fails, such as due to I/O error, unbindable classes. + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + private static void _marshal( Object jaxbObject, Object xml ) { + try { + JAXBContext context; + + if(jaxbObject instanceof JAXBElement) { + context = getContext(((JAXBElement<?>)jaxbObject).getDeclaredType()); + } else { + Class<?> clazz = jaxbObject.getClass(); + XmlRootElement r = clazz.getAnnotation(XmlRootElement.class); + context = getContext(clazz); + if(r==null) { + // we need to infer the name + jaxbObject = new JAXBElement(new QName(inferName(clazz)),clazz,jaxbObject); + } + } + + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); + m.marshal(jaxbObject, toResult(xml)); + } catch (JAXBException | IOException e) { + throw new DataBindingException(e); + } + } + + private static String inferName(Class<?> clazz) { + // XXX - behaviour of this method must be same as of Introspector.decapitalize + // which is not used to avoid dependency on java.desktop + String simpleName = clazz.getSimpleName(); + if (simpleName.isEmpty()) { + return simpleName; + } + if (simpleName.length() > 1 && Character.isUpperCase(simpleName.charAt(1)) + && Character.isUpperCase(simpleName.charAt(0))) { + return simpleName; + } + char[] chars = simpleName.toCharArray(); + chars[0] = Character.toLowerCase(chars[0]); + return new String(chars); + } + + /** + * Creates {@link Result} from various XML representation. + * See {@link #_marshal(Object,Object)} for the conversion rules. + */ + private static Result toResult(Object xml) throws IOException { + if(xml==null) + throw new IllegalArgumentException("no XML is given"); + + if (xml instanceof String) { + try { + xml=new URI((String)xml); + } catch (URISyntaxException e) { + xml=new File((String)xml); + } + } + if (xml instanceof File) { + File file = (File) xml; + return new StreamResult(file); + } + if (xml instanceof URI) { + URI uri = (URI) xml; + xml=uri.toURL(); + } + if (xml instanceof URL) { + URL url = (URL) xml; + URLConnection con = url.openConnection(); + con.setDoOutput(true); + con.setDoInput(false); + con.connect(); + return new StreamResult(con.getOutputStream()); + } + if (xml instanceof OutputStream) { + OutputStream os = (OutputStream) xml; + return new StreamResult(os); + } + if (xml instanceof Writer) { + Writer w = (Writer)xml; + return new StreamResult(w); + } + if (xml instanceof Result) { + return (Result) xml; + } + throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass()); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBContext.java b/api/src/main/java/jakarta/xml/bind/JAXBContext.java new file mode 100644 index 0000000..de223f0 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBContext.java
@@ -0,0 +1,716 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import org.w3c.dom.Node; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +/** + * The {@code JAXBContext} class provides the client's entry point to the + * Jakarta XML Binding API. It provides an abstraction for managing the XML/Java binding + * information necessary to implement the Jakarta XML Binding binding framework operations: + * unmarshal, marshal and validate. + * + * <p>A client application normally obtains new instances of this class using + * one of these two styles for newInstance methods, although there are other + * specialized forms of the method available: + * + * <ul> + * <li>{@link #newInstance(String, ClassLoader) JAXBContext.newInstance( "com.acme.foo:com.acme.bar" )} <br> + * The JAXBContext instance is initialized from a list of colon + * separated Java package names. Each java package contains + * Jakarta XML Binding mapped classes, schema-derived classes and/or user annotated + * classes. Additionally, the java package may contain Jakarta XML Binding package annotations + * that must be processed. (see JLS, Section 7.4.1 "Named Packages"). + * </li> + * <li>{@link #newInstance(Class...) JAXBContext.newInstance( com.acme.foo.Foo.class )} <br> + * The JAXBContext instance is initialized with class(es) + * passed as parameter(s) and classes that are statically reachable from + * these class(es). See {@link #newInstance(Class...)} for details. + * </li> + * </ul> + * + * <p><i> + * The provider must call the + * {@link DatatypeConverter#setDatatypeConverter(DatatypeConverterInterface) + * DatatypeConverter.setDatatypeConverter} api prior to any client + * invocations of the marshal and unmarshal methods. This is necessary to + * configure the datatype converter that will be used during these operations.</i> + * + * <a id="Unmarshalling"></a> + * <h2>Unmarshalling</h2> + * <p> + * The {@link Unmarshaller} class provides the client application the ability + * to convert XML data into a tree of Java content objects. + * The unmarshal method allows for + * any global XML element declared in the schema to be unmarshalled as + * the root of an instance document. + * Additionally, the unmarshal method allows for an unrecognized root element that + * has an xsi:type attribute's value that references a type definition declared in + * the schema to be unmarshalled as the root of an instance document. + * The {@code JAXBContext} object + * allows the merging of global elements and type definitions across a set of schemas (listed + * in the {@code contextPath}). Since each schema in the schema set can belong + * to distinct namespaces, the unification of schemas to an unmarshalling + * context must be namespace independent. This means that a client + * application is able to unmarshal XML documents that are instances of + * any of the schemas listed in the {@code contextPath}. For example: + * + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" ); + * Unmarshaller u = jc.createUnmarshaller(); + * FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) ); // ok + * BarObject barObj = (BarObject)u.unmarshal( new File( "bar.xml" ) ); // ok + * BazObject bazObj = (BazObject)u.unmarshal( new File( "baz.xml" ) ); // error, "com.acme.baz" not in contextPath + * } + * + * <p> + * The client application may also generate Java content trees explicitly rather + * than unmarshalling existing XML data. For all Jakarta XML Binding-annotated value classes, + * an application can create content using constructors. + * For schema-derived interface/implementation classes and for the + * creation of elements that are not bound to a Jakarta XML Binding-annotated + * class, an application needs to have access and knowledge about each of + * the schema derived {@code ObjectFactory} classes that exist in each of + * java packages contained in the {@code contextPath}. For each schema + * derived java class, there is a static factory method that produces objects + * of that type. For example, + * assume that after compiling a schema, you have a package {@code com.acme.foo} + * that contains a schema derived interface named {@code PurchaseOrder}. In + * order to create objects of that type, the client application would use the + * factory method like this: + * + * {@snippet : + * com.acme.foo.PurchaseOrder po = + * com.acme.foo.ObjectFactory.createPurchaseOrder(); + * } + * + * <p> + * Once the client application has an instance of the schema derived object, + * it can use the mutator methods to set content on it. + * + * <p> + * For more information on the generated {@code ObjectFactory} classes, see + * Section 4.2 <i>Java Package</i> of the specification. + * + * <p> + * <i>The provider must generate a class in each + * package that contains all of the necessary object factory methods for that + * package named ObjectFactory as well as the static + * {@code newInstance( javaContentInterface )} method</i> + * + * <h3>Marshalling</h3> + * <p> + * The {@link Marshaller} class provides the client application the ability + * to convert a Java content tree back into XML data. There is no difference + * between marshalling a content tree that is created manually using the factory + * methods and marshalling a content tree that is the result an {@code unmarshal} + * operation. Clients can marshal a java content tree back to XML data + * to a {@code java.io.OutputStream} or a {@code java.io.Writer}. The + * marshalling process can alternatively produce SAX2 event streams to a + * registered {@code ContentHandler} or produce a DOM Node object. + * Client applications have control over the output encoding as well as + * whether to marshal the XML data as a complete document or + * as a fragment. + * + * <p> + * Here is a simple example that unmarshalls an XML document and then marshals + * it back out: + * + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * + * // unmarshal from foo.xml + * Unmarshaller u = jc.createUnmarshaller(); + * FooObject fooObj = (FooObject)u.unmarshal( new File( "foo.xml" ) ); + * + * // marshal to System.out + * Marshaller m = jc.createMarshaller(); + * m.marshal( fooObj, System.out ); + * } + * + * + * <h3>Validation</h3> + * <p> + * In Jakarta XML Binding, the {@link Unmarshaller} has included convenience methods that expose + * the JAXP {@link javax.xml.validation} framework. Please refer to the + * {@link Unmarshaller#setSchema(javax.xml.validation.Schema)} API for more + * information. + * + * + * <h3>Jakarta XML Binding Runtime Framework Compatibility</h3> + * <p> + * The following JAXB 1.0 restriction only applies to binding schema to + * interfaces/implementation classes. + * Since this binding does not require a common runtime system, a Jakarta XML Binding + * client application must not attempt to mix runtime objects ({@code JAXBContext, + * Marshaller}, etc. ) from different providers. This does not + * mean that the client application isn't portable, it simply means that a + * client has to use a runtime system provided by the same provider that was + * used to compile the schema. + * + * + * <h3>Discovery of Jakarta XML Binding implementation</h3> + * <p> + * To create an instance of {@link JAXBContext}, one of {@code JAXBContext.newInstance(...)} methods is invoked. After + * JAX-B implementation is discovered, call is delegated to appropriate provider's method {@code createContext(...)} + * passing parameters from the original call. + * <p> + * JAX-B implementation discovery happens each time {@code JAXBContext.newInstance} is invoked. If there is no user + * specific configuration provided, default JAX-B provider must be returned. + * <p> + * Implementation discovery consists of following steps: + * + * <ol> + * + * <li> + * If the system property {@link #JAXB_CONTEXT_FACTORY} exists, then its value is assumed to be the provider + * factory class. This phase of the look up enables per-JVM override of the Jakarta XML Binding implementation. + * + * <li> + * If the property {@link #JAXB_CONTEXT_FACTORY} exists in the {@code Map<String, ?>} passed to {@link #newInstance(Class[], Map)} + * or to {@link #newInstance(String, ClassLoader, Map)}, then its value is assumed to be the fully qualified provider factory class name. + * This phase of the look up enables context sensitive selection of the Jakarta XML Binding implementation. + * + * <li> + * Provider of {@link jakarta.xml.bind.JAXBContextFactory} is loaded using the service-provider loading + * facilities, defined by the {@link java.util.ServiceLoader} class, to attempt + * to locate and load an implementation of the service using the {@linkplain + * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}: the service-provider loading facility + * will use the {@linkplain java.lang.Thread#getContextClassLoader() current thread's context class loader} + * to attempt to load the context factory. If the context class loader is null, the + * {@linkplain ClassLoader#getSystemClassLoader() system class loader} will be used. + * <br> + * In case of {@link java.util.ServiceConfigurationError service + * configuration error} a {@link jakarta.xml.bind.JAXBException} will be thrown. + * + * <li> + * Finally, if all the steps above fail, then the rest of the look up is unspecified. That said, + * the recommended behavior is to simply look for some hard-coded platform default Jakarta XML Binding implementation. + * This phase of the look up is so that the environment can have its own Jakarta XML Binding implementation as the last resort. + * </ol> + * + * <p> + * Once the provider factory class is discovered, context creation is delegated to one of its + * {@code createContext(...)} methods. + * + * @implNote + * Within the last step, if Glassfish AS environment detected, its specific service loader is used to find factory class. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li> + * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li> + * <li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * + * @see Marshaller + * @see Unmarshaller + * @see <a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.4.1">S 7.4.1 "Named Packages" + * in Java Language Specification</a> + * + * @since 1.6, JAXB 1.0 + */ +public abstract class JAXBContext { + + /** + * The name of the property that contains the name of the class capable + * of creating new {@code JAXBContext} objects. + */ + public static final String JAXB_CONTEXT_FACTORY = "jakarta.xml.bind.JAXBContextFactory"; + + protected JAXBContext() { + } + + + /** + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * This is a convenience method to invoke the + * {@link #newInstance(String,ClassLoader)} method with + * the context class loader of the current thread. + * + * @param contextPath the context path + * + * @return the new instance of a {@code JAXBContext} class + * + * @throws JAXBException if an error was encountered while creating the + * {@code JAXBContext} such as + * <ol> + * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li> + * <li>an ambiguity among global elements contained in the contextPath</li> + * <li>failure to locate a value for the context factory provider property</li> + * <li>mixing schema derived packages from different providers on the same contextPath</li> + * <li>packages are not open to {@code jakarta.xml.bind} module</li> + * </ol> + */ + public static JAXBContext newInstance( String contextPath ) + throws JAXBException { + + //return newInstance( contextPath, JAXBContext.class.getClassLoader() ); + return newInstance( contextPath, getContextClassLoader()); + } + + /** + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * The client application must supply a context path which is a list of + * colon (':', \u005Cu003A) separated java package names that contain + * schema-derived classes and/or fully qualified Jakarta XML Binding-annotated classes. + * Schema-derived + * code is registered with the JAXBContext by the + * ObjectFactory.class generated per package. + * Alternatively than being listed in the context path, programmer + * annotated Jakarta XML Binding mapped classes can be listed in a + * {@code jaxb.index} resource file, format described below. + * Note that a java package can contain both schema-derived classes and + * user annotated Jakarta XML Binding classes. Additionally, the java package may + * contain Jakarta XML Binding package annotations that must be processed. (see JLS, + * Section 7.4.1 "Named Packages"). + * </p> + * + * <p> + * Every package listed on the contextPath must meet <b>one or both</b> of the + * following conditions otherwise a {@code JAXBException} will be thrown: + * </p> + * <ol> + * <li>it must contain ObjectFactory.class</li> + * <li>it must contain jaxb.index</li> + * </ol> + * + * <p> + * <b>Format for jaxb.index</b> + * <p> + * The file contains a newline-separated list of class names. + * Space and tab characters, as well as blank + * lines, are ignored. The comment character + * is '#' (0x23); on each line all characters following the first comment + * character are ignored. The file must be encoded in UTF-8. Classes that + * are reachable, as defined in {@link #newInstance(Class...)}, from the + * listed classes are also registered with JAXBContext. + * <p> + * Constraints on class name occurring in a {@code jaxb.index} file are: + * <ul> + * <li>Must not end with ".class".</li> + * <li>Class names are resolved relative to package containing + * {@code jaxb.index} file. Only classes occuring directly in package + * containing {@code jaxb.index} file are allowed.</li> + * <li>Fully qualified class names are not allowed. + * A qualified class name,relative to current package, + * is only allowed to specify a nested or inner class.</li> + * </ul> + * + * <p> + * If there are any global XML element name collisions across the various + * packages listed on the {@code contextPath}, a {@code JAXBException} + * will be thrown. + * + * <p> + * Mixing generated interface/impl bindings from multiple Jakarta XML Binding Providers + * in the same context path may result in a {@code JAXBException} + * being thrown. + * + * <p> + * The steps involved in discovering the Jakarta XML Binding implementation is discussed in the class javadoc. + * + * @param contextPath + * List of java package names that contain schema + * derived class and/or java to schema (Jakarta XML Binding-annotated) + * mapped classes. + * Packages in {@code contextPath} that are in named modules must be + * {@code open} to at least the {@code jakarta.xml.bind} module. + * @param classLoader + * This class loader will be used to locate the implementation + * classes. + * + * @return a new instance of a {@code JAXBContext} + * @throws JAXBException if an error was encountered while creating the + * {@code JAXBContext} such as + * <ol> + * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li> + * <li>an ambiguity among global elements contained in the contextPath</li> + * <li>failure to locate a value for the context factory provider property</li> + * <li>mixing schema derived packages from different providers on the same contextPath</li> + * <li>packages are not open to {@code jakarta.xml.bind} module</li> + * </ol> + */ + public static JAXBContext newInstance( String contextPath, ClassLoader classLoader ) throws JAXBException { + + return newInstance(contextPath,classLoader,Collections.emptyMap()); + } + + /** + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * This is mostly the same as {@link JAXBContext#newInstance(String, ClassLoader)}, + * but this version allows you to pass in provider-specific properties to configure + * the instantiation of {@link JAXBContext}. + * + * <p> + * The interpretation of properties is up to implementations. Implementations must + * throw {@code JAXBException} if it finds properties that it doesn't understand. + * + * @param contextPath + * List of java package names that contain schema + * derived class and/or java to schema (Jakarta XML Binding-annotated) + * mapped classes. + * Packages in {@code contextPath} that are in named modules must be + * {@code open} to at least the {@code jakarta.xml.bind} module. + * @param classLoader + * This class loader will be used to locate the implementation classes. + * @param properties + * provider-specific or provider selection-specific properties. + * Can be null, which means the same thing as passing in an empty map. + * + * @return a new instance of a {@code JAXBContext} + * @throws JAXBException if an error was encountered while creating the + * {@code JAXBContext} such as + * <ol> + * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li> + * <li>an ambiguity among global elements contained in the contextPath</li> + * <li>failure to locate a value for the context factory provider property</li> + * <li>mixing schema derived packages from different providers on the same contextPath</li> + * <li>packages are not open to {@code jakarta.xml.bind} module</li> + * </ol> + * @since 1.6, JAXB 2.0 + */ + public static JAXBContext newInstance( String contextPath, + ClassLoader classLoader, + Map<String,?> properties ) throws JAXBException { + + return ContextFinder.find( + /* The default property name according to the Jakarta XML Binding spec */ + JAXB_CONTEXT_FACTORY, + + /* the context path supplied by the client app */ + contextPath, + + /* class loader to be used */ + classLoader, + properties ); + } + +// TODO: resurrect this once we introduce external annotations +// /** +// * Create a new instance of a {@code JAXBContext} class. +// * +// * <p> +// * The client application must supply a list of classes that the new +// * context object needs to recognize. +// * +// * Not only the new context will recognize all the classes specified, +// * but it will also recognize any classes that are directly/indirectly +// * referenced statically from the specified classes. +// * +// * For example, in the following Java code, if you do +// * {@code newInstance(Foo.class)}, the newly created {@link JAXBContext} +// * will recognize both {@code Foo} and {@code Bar}, but not {@code Zot}: +// * {@snippet : +// * class Foo { +// * Bar b; +// * } +// * class Bar { int x; } +// * class Zot extends Bar { int y; } +// * } +// * +// * Therefore, a typical client application only needs to specify the +// * top-level classes, but it needs to be careful. +// * +// * TODO: if we are to define other mechanisms, refer to them. +// * +// * @param externalBindings +// * list of external binding files. Can be null or empty if none is used. +// * when specified, those files determine how the classes are bound. +// * +// * @param classesToBeBound +// * list of java classes to be recognized by the new {@link JAXBContext}. +// * Can be empty, in which case a {@link JAXBContext} that only knows about +// * spec-defined classes will be returned. +// * +// * @return +// * A new instance of a {@code JAXBContext}. +// * +// * @throws JAXBException +// * if an error was encountered while creating the +// * {@code JAXBContext}, such as (but not limited to): +// * <ol> +// * <li>No Jakarta XML Binding implementation was discovered +// * <li>Classes use Jakarta XML Binding annotations incorrectly +// * <li>Classes have colliding annotations (i.e., two classes with the same type name) +// * <li>Specified external bindings are incorrect +// * <li>The Jakarta XML Binding implementation was unable to locate +// * provider-specific out-of-band information (such as additional +// * files generated at the development time.) +// * </ol> +// * +// * @throws IllegalArgumentException +// * if the parameter contains {@code null} (i.e., {@code newInstance(null);}) +// * +// * @since JAXB 2.0 +// */ +// public static JAXBContext newInstance( Source[] externalBindings, Class... classesToBeBound ) +// throws JAXBException { +// +// // empty class list is not an error, because the context will still include +// // spec-specified classes like String and Integer. +// // if(classesToBeBound.length==0) +// // throw new IllegalArgumentException(); +// +// // but it is an error to have nulls in it. +// for( int i=classesToBeBound.length-1; i>=0; i-- ) +// if(classesToBeBound[i]==null) +// throw new IllegalArgumentException(); +// +// return ContextFinder.find(externalBindings,classesToBeBound); +// } + + /** + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * The client application must supply a list of classes that the new + * context object needs to recognize. + * <p> + * Not only the new context will recognize all the classes specified, + * but it will also recognize any classes that are directly/indirectly + * referenced statically from the specified classes. Subclasses of + * referenced classes nor {@code @XmlTransient} referenced classes + * are not registered with JAXBContext. + * <p> + * For example, in the following Java code, if you do + * {@code newInstance(Foo.class)}, the newly created {@link JAXBContext} + * will recognize both {@code Foo} and {@code Bar}, but not {@code Zot} or {@code FooBar}: + * {@snippet : + * class Foo { + * @XmlTransient FooBar c; + * Bar b; + * } + * class Bar { int x; } + * class Zot extends Bar { int y; } + * class FooBar { } + * } + * + * Therefore, a typical client application only needs to specify the + * top-level classes, but it needs to be careful. + * + * <p> + * Note that for each java package registered with JAXBContext, + * when the optional package annotations exist, they must be processed. + * (see JLS, Section 7.4.1 "Named Packages"). + * + * <p> + * The steps involved in discovering the Jakarta XML Binding implementation is discussed in the class javadoc. + * + * @param classesToBeBound + * List of java classes to be recognized by the new {@link JAXBContext}. + * Classes in {@code classesToBeBound} that are in named modules must be in a package + * that is {@code open} to at least the {@code jakarta.xml.bind} module. + * Can be empty, in which case a {@link JAXBContext} that only knows about + * spec-defined classes will be returned. + * + * @return + * A new instance of a {@code JAXBContext}. + * + * @throws JAXBException + * if an error was encountered while creating the + * {@code JAXBContext}, such as (but not limited to): + * <ol> + * <li>No Jakarta XML Binding implementation was discovered + * <li>Classes use Jakarta XML Binding annotations incorrectly + * <li>Classes have colliding annotations (i.e., two classes with the same type name) + * <li>The Jakarta XML Binding implementation was unable to locate + * provider-specific out-of-band information (such as additional + * files generated at the development time.) + * <li>{@code classesToBeBound} are not open to {@code jakarta.xml.bind} module + * </ol> + * + * @throws IllegalArgumentException + * if the parameter contains {@code null} (i.e., {@code newInstance(null);}) + * + * @since 1.6, JAXB 2.0 + */ + public static JAXBContext newInstance( Class<?> ... classesToBeBound ) + throws JAXBException { + + return newInstance(classesToBeBound,Collections.emptyMap()); + } + + /** + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * An overloading of {@link JAXBContext#newInstance(Class...)} + * to configure 'properties' for this instantiation of {@link JAXBContext}. + * + * <p> + * The interpretation of properties is up to implementations. Implementations must + * throw {@code JAXBException} if it finds properties that it doesn't understand. + * + * @param classesToBeBound + * List of java classes to be recognized by the new {@link JAXBContext}. + * Classes in {@code classesToBeBound} that are in named modules must be in a package + * that is {@code open} to at least the {@code jakarta.xml.bind} module. + * Can be empty, in which case a {@link JAXBContext} that only knows about + * spec-defined classes will be returned. + * @param properties + * provider-specific or provider selection-specific properties. + * Can be null, which means the same thing as passing in an empty map. + * + * @return + * A new instance of a {@code JAXBContext}. + * + * @throws JAXBException + * if an error was encountered while creating the + * {@code JAXBContext}, such as (but not limited to): + * <ol> + * <li>No Jakarta XML Binding implementation was discovered + * <li>Classes use Jakarta XML Binding annotations incorrectly + * <li>Classes have colliding annotations (i.e., two classes with the same type name) + * <li>The Jakarta XML Binding implementation was unable to locate + * provider-specific out-of-band information (such as additional + * files generated at the development time.) + * <li>{@code classesToBeBound} are not open to {@code jakarta.xml.bind} module + * </ol> + * + * @throws IllegalArgumentException + * if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);}) + * + * @since 1.6, JAXB 2.0 + */ + public static JAXBContext newInstance( Class<?>[] classesToBeBound, Map<String,?> properties ) + throws JAXBException { + + if (classesToBeBound == null) { + throw new IllegalArgumentException(); + } + + // but it is an error to have nulls in it. + for (int i = classesToBeBound.length - 1; i >= 0; i--) { + if (classesToBeBound[i] == null) { + throw new IllegalArgumentException(); + } + } + + return ContextFinder.find(classesToBeBound,properties); + } + + /** + * Create an {@code Unmarshaller} object that can be used to convert XML + * data into a java content tree. + * + * @return an {@code Unmarshaller} object + * + * @throws JAXBException if an error was encountered while creating the + * {@code Unmarshaller} object + */ + public abstract Unmarshaller createUnmarshaller() throws JAXBException; + + + /** + * Create a {@code Marshaller} object that can be used to convert a + * java content tree into XML data. + * + * @return a {@code Marshaller} object + * + * @throws JAXBException if an error was encountered while creating the + * {@code Marshaller} object + */ + public abstract Marshaller createMarshaller() throws JAXBException; + + + /** + * Creates a {@code Binder} object that can be used for + * associative/in-place unmarshalling/marshalling. + * + * @param domType select the DOM API to use by passing in its DOM Node class + * + * @param <T> the DOM API type + * + * @return always a new valid {@code Binder} object. + * + * @throws UnsupportedOperationException + * if DOM API corresponding to {@code domType} is not supported by + * the implementation. + * + * @since 1.6, JAXB 2.0 + */ + public <T> Binder<T> createBinder(Class<T> domType) { + // to make JAXB 1.0 implementations work, this method must not be + // abstract + throw new UnsupportedOperationException(); + } + + /** + * Creates a {@code Binder} for W3C DOM. + * + * @return always a new valid {@code Binder} object. + * + * @since 1.6, JAXB 2.0 + */ + public Binder<Node> createBinder() { + return createBinder(Node.class); + } + + /** + * Creates a {@code JAXBIntrospector} object that can be used to + * introspect Jakarta XML Binding objects. + * + * @return + * always return a non-null valid {@code JAXBIntrospector} object. + * + * @throws UnsupportedOperationException + * Calling this method on JAXB 1.0 implementations will throw + * an UnsupportedOperationException. + * + * @since 1.6, JAXB 2.0 + */ + public JAXBIntrospector createJAXBIntrospector() { + // to make JAXB 1.0 implementations work, this method must not be + // abstract + throw new UnsupportedOperationException(); + } + + /** + * Generates the schema documents for this context. + * + * @param outputResolver + * this object controls the output to which schemas + * will be sent. + * + * @throws IOException + * if {@link SchemaOutputResolver} throws an {@link IOException}. + * + * @throws UnsupportedOperationException + * Calling this method on JAXB 1.0 implementations will throw + * an UnsupportedOperationException. + * + * @since 1.6, JAXB 2.0 + */ + public void generateSchema(SchemaOutputResolver outputResolver) throws IOException { + // to make JAXB 1.0 implementations work, this method must not be + // abstract + throw new UnsupportedOperationException(); + } + + private static ClassLoader getContextClassLoader() { + if (System.getSecurityManager() == null) { + return Thread.currentThread().getContextClassLoader(); + } else { + return java.security.AccessController.doPrivileged( + (java.security.PrivilegedAction<ClassLoader>) () + -> Thread.currentThread().getContextClassLoader()); + } + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBContextFactory.java b/api/src/main/java/jakarta/xml/bind/JAXBContextFactory.java new file mode 100644 index 0000000..cfde648 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBContextFactory.java
@@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.util.Map; + +/** + * <p>Factory that creates new <code>JAXBContext</code> instances. + * <p> + * JAXBContextFactory can be located using {@link java.util.ServiceLoader#load(Class)} + * + * @since 9, JAXB 2.3 + */ +public interface JAXBContextFactory { + + /** + * <p> + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * For semantics see {@link jakarta.xml.bind.JAXBContext#newInstance(Class[], java.util.Map)} + * + * @param classesToBeBound + * List of java classes to be recognized by the new {@link JAXBContext}. + * Classes in {@code classesToBeBound} that are in named modules must be in a package + * that is {@code open} to at least the {@code jakarta.xml.bind} module. + * Can be empty, in which case a {@link JAXBContext} that only knows about + * spec-defined classes will be returned. + * @param properties + * provider-specific properties. Can be null, which means the same thing as passing + * in an empty map. + * + * @return + * A new instance of a {@code JAXBContext}. + * + * @throws JAXBException + * if an error was encountered while creating the + * {@code JAXBContext}, such as (but not limited to): + * <ol> + * <li>No Jakarta XML Binding implementation was discovered + * <li>Classes use Jakarta XML Binding annotations incorrectly + * <li>Classes have colliding annotations (i.e., two classes with the same type name) + * <li>The Jakarta XML Binding implementation was unable to locate + * provider-specific out-of-band information (such as additional + * files generated at the development time.) + * <li>{@code classesToBeBound} are not open to {@code jakarta.xml.bind} module + * </ol> + * + * @throws IllegalArgumentException + * if the parameter contains {@code null} (i.e., {@code newInstance(null,someMap);}) + * + * @since 9, JAXB 2.3 + */ + JAXBContext createContext(Class<?>[] classesToBeBound, + Map<String, ?> properties ) throws JAXBException; + + /** + * <p> + * Create a new instance of a {@code JAXBContext} class. + * + * <p> + * For semantics see {@link jakarta.xml.bind.JAXBContext#newInstance(String, ClassLoader, java.util.Map)} + * + * <p> + * The interpretation of properties is up to implementations. Implementations must + * throw {@code JAXBException} if it finds properties that it doesn't understand. + * + * @param contextPath + * List of java package names that contain schema derived classes. + * Classes in {@code classesToBeBound} that are in named modules must be in a package + * that is {@code open} to at least the {@code jakarta.xml.bind} module. + * @param classLoader + * This class loader will be used to locate the implementation classes. + * @param properties + * provider-specific properties. Can be null, which means the same thing as passing + * in an empty map. + * + * @return a new instance of a {@code JAXBContext} + * @throws JAXBException if an error was encountered while creating the + * {@code JAXBContext} such as + * <ol> + * <li>failure to locate either ObjectFactory.class or jaxb.index in the packages</li> + * <li>an ambiguity among global elements contained in the contextPath</li> + * <li>failure to locate a value for the context factory provider property</li> + * <li>mixing schema derived packages from different providers on the same contextPath</li> + * <li>packages are not open to {@code jakarta.xml.bind} module</li> + * </ol> + * + * @since 9, JAXB 2.3 + */ + JAXBContext createContext(String contextPath, + ClassLoader classLoader, + Map<String, ?> properties ) throws JAXBException; + +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBElement.java b/api/src/main/java/jakarta/xml/bind/JAXBElement.java new file mode 100644 index 0000000..77511fb --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBElement.java
@@ -0,0 +1,205 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import javax.xml.namespace.QName; +import java.io.Serializable; + +/** + * <p>Jakarta XML Binding representation of an Xml Element.</p> + * + * <p>This class represents information about an Xml Element from both the element + * declaration within a schema and the element instance value within an xml document + * with the following properties + * <ul> + * <li>element's xml tag <b>{@code name}</b></li> + * <li><b>{@code value}</b> represents the element instance's attribute(s) and content model</li> + * <li>element declaration's <b>{@code declaredType}</b> ({@code xs:element @type} attribute)</li> + * <li><b>{@code scope}</b> of element declaration</li> + * <li>boolean <b>{@code nil}</b> property. (element instance's <b>{@code xsi:nil}</b> attribute)</li> + * </ul> + * + * <p>The {@code declaredType} and {@code scope} property are the + * Jakarta XML Binding class binding for the xml type definition. + * </p> + * + * <p><b>{@code Scope}</b> is either {@link GlobalScope} or the Java class representing the + * complex type definition containing the schema element declaration. + * </p> + * + * <p>There is a property constraint that if <b>{@code value}</b> is {@code null}, + * then {@code nil} must be {@code true}. The converse is not true to enable + * representing a nil element with attribute(s). If {@code nil} is true, it is possible + * that {@code value} is non-null so it can hold the value of the attributes + * associated with a nil element. + * </p> + * + * @author Kohsuke Kawaguchi, Joe Fialli + * @since 1.6, JAXB 2.0 + */ + +public class JAXBElement<T> implements Serializable { + + /** xml element tag name */ + final protected QName name; + + /** Java datatype binding for xml element declaration's type. */ + final protected Class<T> declaredType; + + /** Scope of xml element declaration representing this xml element instance. + * Can be one of the following values: + * - {@link GlobalScope} for global xml element declaration. + * - local element declaration has a scope set to the Java class + * representation of complex type definition containing + * xml element declaration. + */ + final protected Class<?> scope; + + /** xml element value. + Represents content model and attributes of an xml element instance. */ + protected T value; + + /** true iff the xml element instance has xsi:nil="true". */ + protected boolean nil = false; + + /** + * Designates global scope for an xml element. + */ + public static final class GlobalScope { + private GlobalScope() {} + } + + /** + * <p>Construct an xml element instance.</p> + * + * @param name Java binding of xml element tag name + * @param declaredType Java binding of xml element declaration's type + * @param scope + * Java binding of scope of xml element declaration. + * Passing null is the same as passing {@code GlobalScope.class} + * @param value + * Java instance representing xml element's value. + * @see #getScope() + * @see #isTypeSubstituted() + */ + public JAXBElement(QName name, + Class<T> declaredType, + Class<?> scope, + T value) { + if(declaredType==null || name==null) + throw new IllegalArgumentException(); + this.declaredType = declaredType; + if(scope==null) scope = GlobalScope.class; + this.scope = scope; + this.name = name; + setValue(value); + } + + /** + * Construct an xml element instance. + * <p> + * This is just a convenience method for {@code new JAXBElement(name,declaredType,GlobalScope.class,value)} + */ + public JAXBElement(QName name, Class<T> declaredType, T value ) { + this(name,declaredType,GlobalScope.class,value); + } + + /** + * Returns the Java binding of the xml element declaration's type attribute. + */ + public Class<T> getDeclaredType() { + return declaredType; + } + + /** + * Returns the xml element tag name. + */ + public QName getName() { + return name; + } + + /** + * <p>Set the content model and attributes of this xml element.</p> + * + * <p>When this property is set to {@code null}, {@code isNil()} must by {@code true}. + * Details of constraint are described at {@link #isNil()}.</p> + * + * @see #isTypeSubstituted() + */ + public void setValue(T t) { + this.value = t; + } + + /** + * <p>Return the content model and attribute values for this element.</p> + * + * <p>See {@link #isNil()} for a description of a property constraint when + * this value is {@code null}</p> + */ + public T getValue() { + return value; + } + + /** + * Returns scope of xml element declaration. + * + * @see #isGlobalScope() + * @return {@code GlobalScope.class} if this element is of global scope. + */ + public Class<?> getScope() { + return scope; + } + + /** + * <p>Returns {@code true} iff this element instance content model + * is nil.</p> + * + * <p>This property always returns {@code true} when {@link #getValue()} is null. + * Note that the converse is not true, when this property is {@code true}, + * {@link #getValue()} can contain a non-null value for attribute(s). It is + * valid for a nil xml element to have attribute(s).</p> + */ + public boolean isNil() { + return (value == null) || nil; + } + + /** + * <p>Set whether this element has nil content.</p> + * + * @see #isNil() + */ + public void setNil(boolean value) { + this.nil = value; + } + + /* Convenience methods + * (Not necessary but they do unambiguously conceptualize + * the rationale behind this class' fields.) + */ + + /** + * Returns true iff this xml element declaration is global. + */ + public boolean isGlobalScope() { + return this.scope == GlobalScope.class; + } + + /** + * Returns true iff this xml element instance's value has a different + * type than xml element declaration's declared type. + */ + public boolean isTypeSubstituted() { + if(value==null) return false; + return value.getClass() != declaredType; + } + + private static final long serialVersionUID = 1L; +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBException.java b/api/src/main/java/jakarta/xml/bind/JAXBException.java new file mode 100644 index 0000000..fa312ef --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBException.java
@@ -0,0 +1,173 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.io.PrintWriter; + +/** + * This is the root exception class for all Jakarta XML Binding exceptions. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see JAXBContext + * @see Marshaller + * @see Unmarshaller + * @since 1.6, JAXB 1.0 + */ +public class JAXBException extends Exception { + + /** + * Vendor specific error code + * + */ + private String errorCode; + + /** + * Exception reference + * + */ + private volatile Throwable linkedException; + + static final long serialVersionUID = -5621384651494307979L; + + /** + * Construct a JAXBException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public JAXBException(String message) { + this( message, null, null ); + } + + /** + * Construct a JAXBException with the specified detail message and vendor + * specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public JAXBException(String message, String errorCode) { + this( message, errorCode, null ); + } + + /** + * Construct a JAXBException with a linkedException. The detail message and + * vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public JAXBException(Throwable exception) { + this( null, null, exception ); + } + + /** + * Construct a JAXBException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public JAXBException(String message, Throwable exception) { + this( message, null, exception ); + } + + /** + * Construct a JAXBException with the specified detail message, vendor + * specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public JAXBException(String message, String errorCode, Throwable exception) { + super( message ); + this.errorCode = errorCode; + this.linkedException = exception; + } + + /** + * Get the vendor specific error code + * + * @return a string specifying the vendor specific error code + */ + public String getErrorCode() { + return this.errorCode; + } + + /** + * Get the linked exception + * + * @return the linked Exception, null if none exists + */ + public Throwable getLinkedException() { + return linkedException; + } + + /** + * Add a linked Exception. + * + * @param exception the linked Exception (A null value is permitted and + * indicates that the linked exception does not exist or + * is unknown). + */ + public void setLinkedException( Throwable exception ) { + this.linkedException = exception; + } + + /** + * Returns a short description of this JAXBException. + * + */ + @Override + public String toString() { + return linkedException == null ? + super.toString() : + super.toString() + "\n - with linked exception:\n[" + + linkedException.toString()+ "]"; + } + + /** + * Prints this JAXBException and its stack trace (including the stack trace + * of the linkedException if it is non-null) to the PrintStream. + * + * @param s PrintStream to use for output + */ + @Override + public void printStackTrace( java.io.PrintStream s ) { + super.printStackTrace(s); + } + + /** + * Prints this JAXBException and its stack trace (including the stack trace + * of the linkedException if it is non-null) to {@code System.err}. + * + */ + @Override + public void printStackTrace() { + super.printStackTrace(); + } + + /** + * Prints this JAXBException and its stack trace (including the stack trace + * of the linkedException if it is non-null) to the PrintWriter. + * + * @param s PrintWriter to use for output + */ + @Override + public void printStackTrace(PrintWriter s) { + super.printStackTrace(s); + } + + @Override + public Throwable getCause() { + return linkedException; + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBIntrospector.java b/api/src/main/java/jakarta/xml/bind/JAXBIntrospector.java new file mode 100644 index 0000000..04a5e2d --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBIntrospector.java
@@ -0,0 +1,83 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import javax.xml.namespace.QName; + +/** + * Provide access to Jakarta XML Binding xml binding data for a Jakarta XML Binding object. + * + * <p> + * Initially, the intent of this class is to just conceptualize how + * a Jakarta XML Binding application developer can access xml binding information, + * independent if binding model is java to schema or schema to java. + * Since accessing the XML element name related to a Jakarta XML Binding element is + * a highly requested feature, demonstrate access to this + * binding information. + * <p> + * The factory method to get a <code>JAXBIntrospector</code> instance is + * {@link JAXBContext#createJAXBIntrospector()}. + * + * @see JAXBContext#createJAXBIntrospector() + * @since 1.6, JAXB 2.0 + */ +public abstract class JAXBIntrospector { + + /** + * Do-nothing constructor for the derived classes. + */ + protected JAXBIntrospector() {} + + /** + * <p>Return true if <code>object</code> represents a Jakarta XML Binding element.</p> + * <p>Parameter <code>object</code> is a Jakarta XML Binding element for following cases: + * <ol> + * <li>It is an instance of <code>jakarta.xml.bind.JAXBElement</code>.</li> + * <li>The class of <code>object</code> is annotated with + * <code>@XmlRootElement</code>. + * </li> + * </ol> + * + * @see #getElementName(Object) + */ + public abstract boolean isElement(Object object); + + /** + * <p>Get xml element qname for <code>jaxbElement</code>.</p> + * + * @param jaxbElement is an object that {@link #isElement(Object)} returned true. + * + * @return xml element qname associated with jaxbElement; + * null if <code>jaxbElement</code> is not a JAXBElement. + */ + public abstract QName getElementName(Object jaxbElement); + + /** + * <p>Get the element value of a Jakarta XML Binding element.</p> + * + * <p>Convenience method to abstract whether working with either + * a jakarta.xml.bind.JAXBElement instance or an instance of + * {@code @XmlRootElement} annotated Java class.</p> + * + * @param jaxbElement object that #isElement(Object) returns true. + * + * @return The element value of the <code>jaxbElement</code>. + */ + public static Object getValue(Object jaxbElement) { + if (jaxbElement instanceof JAXBElement) { + return ((JAXBElement<?>)jaxbElement).getValue(); + } else { + // assume that class of this instance is + // annotated with @XmlRootElement. + return jaxbElement; + } + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/JAXBPermission.java b/api/src/main/java/jakarta/xml/bind/JAXBPermission.java new file mode 100644 index 0000000..170a896 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/JAXBPermission.java
@@ -0,0 +1,82 @@ +/* + * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.security.BasicPermission; + +/** + * This class is for Jakarta XML Binding permissions. A {@code JAXBPermission} + * contains a name (also referred to as a "target name") but + * no actions list; you either have the named permission + * or you don't. + * + * <P> + * The target name is the name of the Jakarta XML Binding permission (see below). + * + * <P> + * The following table lists all the possible {@code JAXBPermission} target names, + * and for each provides a description of what the permission allows + * and a discussion of the risks of granting code the permission. + * + * <table class="striped"> + * <caption style="display:none">Permission target name, what the permission allows, and associated risks"</caption> + * <thead> + * <tr> + * <th scope="col">Permission Target Name</th> + * <th scope="col">What the Permission Allows</th> + * <th scope="col">Risks of Allowing this Permission</th> + * </tr> + * </thead> + * + * <tbody style="text-align:left"> + * <tr> + * <th scope="row">setDatatypeConverter</th> + * <td> + * Allows the code to set VM-wide {@link DatatypeConverterInterface} + * via {@link DatatypeConverter#setDatatypeConverter(DatatypeConverterInterface) the setDatatypeConverter method} + * that all the methods on {@link DatatypeConverter} uses. + * </td> + * <td> + * Malicious code can set {@link DatatypeConverterInterface}, which has + * VM-wide singleton semantics, before a genuine Jakarta XML Binding implementation sets one. + * This allows malicious code to gain access to objects that it may otherwise + * not have access to, such as {@code java.awt.Frame#getFrames()} that belongs to + * another application running in the same JVM. + * </td> + * </tr> + * </tbody> + * </table> + * + * @see java.security.BasicPermission + * @see java.security.Permission + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.lang.SecurityManager + * + * @author Joe Fialli + * @since 1.7, JAXB 2.2 + */ + +/* code was borrowed originally from java.lang.RuntimePermission. */ +public final class JAXBPermission extends BasicPermission { + /** + * Creates a new JAXBPermission with the specified name. + * + * @param name + * The name of the JAXBPermission. As of 2.2 only "setDatatypeConverter" + * is defined. + */ + public JAXBPermission(String name) { + super(name); + } + + private static final long serialVersionUID = 1L; +}
diff --git a/api/src/main/java/jakarta/xml/bind/MarshalException.java b/api/src/main/java/jakarta/xml/bind/MarshalException.java new file mode 100644 index 0000000..cc8b199 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/MarshalException.java
@@ -0,0 +1,88 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This exception indicates that an error has occurred while performing + * a marshal operation that the provider is unable to recover from. + * + * <p> + * The {@code ValidationEventHandler} can cause this exception to be thrown + * during the marshal operations. See + * {@link ValidationEventHandler#handleEvent(ValidationEvent) + * ValidationEventHandler.handleEvent(ValidationEvent)}. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see JAXBException + * @see Marshaller + * @since 1.6, JAXB 1.0 + */ +public class MarshalException extends JAXBException { + + private static final long serialVersionUID = 1570397297836071517L; + + /** + * Construct a MarshalException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public MarshalException( String message ) { + this( message, null, null ); + } + + /** + * Construct a MarshalException with the specified detail message and vendor + * specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public MarshalException( String message, String errorCode ) { + this( message, errorCode, null ); + } + + /** + * Construct a MarshalException with a linkedException. The detail message and + * vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public MarshalException( Throwable exception ) { + this( null, null, exception ); + } + + /** + * Construct a MarshalException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public MarshalException( String message, Throwable exception ) { + this( message, null, exception ); + } + + /** + * Construct a MarshalException with the specified detail message, vendor + * specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public MarshalException( String message, String errorCode, Throwable exception ) { + super( message, errorCode, exception ); + } + +} + +
diff --git a/api/src/main/java/jakarta/xml/bind/Marshaller.java b/api/src/main/java/jakarta/xml/bind/Marshaller.java new file mode 100644 index 0000000..62d85e3 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/Marshaller.java
@@ -0,0 +1,807 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.attachment.AttachmentMarshaller; +import javax.xml.validation.Schema; +import java.io.File; + +/** + * <p> + * The {@code Marshaller} class is responsible for governing the process + * of serializing Java content trees back into XML data. It provides the basic + * marshalling methods: + * + * <p> + * <i>Assume the following setup code for all following code fragments:</i> + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * Object element = u.unmarshal( new File( "foo.xml" ) ); + * Marshaller m = jc.createMarshaller(); + * } + * + * <p> + * Marshalling to a File: + * {@snippet : + * OutputStream os = new FileOutputStream( "nosferatu.xml" ); + * m.marshal( element, os ); + * } + * + * <p> + * Marshalling to a SAX ContentHandler: + * {@snippet : + * // assume MyContentHandler instanceof ContentHandler + * m.marshal( element, new MyContentHandler() ); + * } + * + * <p> + * Marshalling to a DOM Node: + * {@snippet : + * DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + * dbf.setNamespaceAware(true); + * DocumentBuilder db = dbf.newDocumentBuilder(); + * Document doc = db.newDocument(); + * + * m.marshal( element, doc ); + * } + * + * <p> + * Marshalling to a java.io.OutputStream: + * {@snippet : + * m.marshal( element, System.out ); + * } + * + * <p> + * Marshalling to a java.io.Writer: + * {@snippet : + * m.marshal( element, new PrintWriter( System.out ) ); + * } + * + * <p> + * Marshalling to a javax.xml.transform.SAXResult: + * {@snippet : + * // assume MyContentHandler instanceof ContentHandler + * SAXResult result = new SAXResult( new MyContentHandler() ); + * + * m.marshal( element, result ); + * } + * + * <p> + * Marshalling to a javax.xml.transform.DOMResult: + * {@snippet : + * DOMResult result = new DOMResult(); + * + * m.marshal( element, result ); + * } + * + * <p> + * Marshalling to a javax.xml.transform.StreamResult: + * {@snippet : + * StreamResult result = new StreamResult( System.out ); + * + * m.marshal( element, result ); + * } + * + * <p> + * Marshalling to a javax.xml.stream.XMLStreamWriter: + * {@snippet : + * XMLStreamWriter xmlStreamWriter = + * XMLOutputFactory.newInstance().createXMLStreamWriter( ... ); + * + * m.marshal( element, xmlStreamWriter ); + * } + * + * <p> + * Marshalling to a javax.xml.stream.XMLEventWriter: + * {@snippet : + * XMLEventWriter xmlEventWriter = + * XMLOutputFactory.newInstance().createXMLEventWriter( ... ); + * + * m.marshal( element, xmlEventWriter ); + * } + * + * <p> + * <a id="elementMarshalling"></a> + * <b>Marshalling content tree rooted by a Jakarta XML Binding element</b><br> + * <blockquote> + * The first parameter of the overloaded + * {@code Marshaller.marshal(java.lang.Object, ...)} methods must be a + * Jakarta XML Binding element as computed by + * {@link JAXBIntrospector#isElement(java.lang.Object)}; + * otherwise, a {@code Marshaller.marshal} method must throw a + * {@link MarshalException}. There exist two mechanisms + * to enable marshalling an instance that is not a Jakarta XML Binding element. + * One method is to wrap the instance as a value of a {@link JAXBElement}, + * and pass the wrapper element as the first parameter to + * a {@code Marshaller.marshal} method. For java to schema binding, it + * is also possible to simply annotate the instance's class with + * @{@link XmlRootElement}. + * </blockquote> + * + * <p> + * <b>Encoding</b><br> + * <blockquote> + * By default, the Marshaller will use UTF-8 encoding when generating XML data + * to a {@code java.io.OutputStream}, or a {@code java.io.Writer}. Use the + * {@link #setProperty(String,Object) setProperty} API to change the output + * encoding used during these marshal operations. Client applications are + * expected to supply a valid character encoding name as defined in the + * <a href="http://www.w3.org/TR/2000/REC-xml-20001006#charencoding">W3C XML 1.0 + * Recommendation</a> and supported by your Java Platform. + * </blockquote> + * + * <p> + * <b>Validation and Well-Formedness</b><br> + * <blockquote> + * <p> + * Client applications are not required to validate the Java content tree prior + * to calling any of the marshal API's. Furthermore, there is no requirement + * that the Java content tree be valid with respect to its original schema in + * order to marshal it back into XML data. Different Jakarta XML Binding Providers will + * support marshalling invalid Java content trees at varying levels, however + * all Jakarta XML Binding Providers must be able to marshal a valid content tree back to + * XML data. A Jakarta XML Binding Provider must throw a {@code MarshalException} when it + * is unable to complete the marshal operation due to invalid content. Some + * Jakarta XML Binding Providers will fully allow marshalling invalid content, others will fail + * on the first validation error. + * <p> + * Even when schema validation is not explicitly enabled for the marshal operation, + * it is possible that certain types of validation events will be detected + * during the operation. Validation events will be reported to the registered + * event handler. If the client application has not registered an event handler + * prior to invoking one of the marshal API's, then events will be delivered to + * a default event handler which will terminate the marshal operation after + * encountering the first error or fatal error. Note that for Jakarta XML Binding and + * later versions, {@link jakarta.xml.bind.helpers.DefaultValidationEventHandler} is + * no longer used. + * </blockquote> + * + * <p> + * <a id="supportedProps"></a> + * <b>Supported Properties</b><br> + * <blockquote> + * <p> + * All Jakarta XML Binding Providers are required to support the following set of properties. + * Some providers may support additional properties. + * <dl> + * <dt>{@code jaxb.encoding} - value must be a java.lang.String</dt> + * <dd>The output encoding to use when marshalling the XML data. The + * Marshaller will use "UTF-8" by default if this property is not + * specified.</dd> + * <dt>{@code jaxb.formatted.output} - value must be a java.lang.Boolean</dt> + * <dd>This property controls whether or not the Marshaller will format + * the resulting XML data with line breaks and indentation. A + * true value for this property indicates human readable indented + * xml data, while a false value indicates unformatted xml data. + * The Marshaller will default to false (unformatted) if this + * property is not specified.</dd> + * <dt>{@code jaxb.schemaLocation} - value must be a java.lang.String</dt> + * <dd>This property allows the client application to specify an + * xsi:schemaLocation attribute in the generated XML data. The format of + * the schemaLocation attribute value is discussed in an easy to + * understand, non-normative form in + * <a href="http://www.w3.org/TR/xmlschema-0/#schemaLocation">Section 5.6 + * of the W3C XML Schema Part 0: Primer</a> and specified in + * <a href="http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions"> + * Section 2.6 of the W3C XML Schema Part 1: Structures</a>.</dd> + * <dt>{@code jaxb.noNamespaceSchemaLocation} - value must be a java.lang.String</dt> + * <dd>This property allows the client application to specify an + * xsi:noNamespaceSchemaLocation attribute in the generated XML + * data. The format of the schemaLocation attribute value is discussed in + * an easy to understand, non-normative form in + * <a href="http://www.w3.org/TR/xmlschema-0/#schemaLocation">Section 5.6 + * of the W3C XML Schema Part 0: Primer</a> and specified in + * <a href="http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions"> + * Section 2.6 of the W3C XML Schema Part 1: Structures</a>.</dd> + * <dt>{@code jaxb.fragment} - value must be a java.lang.Boolean</dt> + * <dd>This property determines whether or not document level events will be + * generated by the Marshaller. If the property is not specified, the + * default is {@code false}. This property has different implications depending + * on which marshal api you are using - when this property is set to true:<br> + * <ul> + * <li>{@link #marshal(Object,org.xml.sax.ContentHandler) marshal(Object,ContentHandler)} - the Marshaller won't + * invoke {@link org.xml.sax.ContentHandler#startDocument()} and + * {@link org.xml.sax.ContentHandler#endDocument()}.</li> + * <li>{@link #marshal(Object,org.w3c.dom.Node) marshal(Object,Node)} - the property has no effect on this + * API.</li> + * <li>{@link #marshal(Object,java.io.OutputStream) marshal(Object,OutputStream)} - the Marshaller won't + * generate an xml declaration.</li> + * <li>{@link #marshal(Object,java.io.Writer) marshal(Object,Writer)} - the Marshaller won't + * generate an xml declaration.</li> + * <li>{@link #marshal(Object,javax.xml.transform.Result) marshal(Object,Result)} - depends on the kind of + * Result object, see semantics for Node, ContentHandler, and Stream APIs</li> + * <li>{@link #marshal(Object,javax.xml.stream.XMLEventWriter) marshal(Object,XMLEventWriter)} - the + * Marshaller will not generate {@link javax.xml.stream.events.XMLEvent#START_DOCUMENT} and + * {@link javax.xml.stream.events.XMLEvent#END_DOCUMENT} events.</li> + * <li>{@link #marshal(Object,javax.xml.stream.XMLStreamWriter) marshal(Object,XMLStreamWriter)} - the + * Marshaller will not generate {@link javax.xml.stream.events.XMLEvent#START_DOCUMENT} and + * {@link javax.xml.stream.events.XMLEvent#END_DOCUMENT} events.</li> + * </ul> + * </dd> + * </dl> + * </blockquote> + * + * <p> + * <a id="marshalEventCallback"></a> + * <b>Marshal Event Callbacks</b><br> + * <blockquote> + * "The {@link Marshaller} provides two styles of callback mechanisms + * that allow application specific processing during key points in the + * unmarshalling process. In 'class defined' event callbacks, application + * specific code placed in Jakarta XML Binding mapped classes is triggered during + * marshalling. 'External listeners' allow for centralized processing + * of marshal events in one callback method rather than by type event callbacks. + * + * <p> + * Class defined event callback methods allow any Jakarta XML Binding mapped class to specify + * its own specific callback methods by defining methods with the following method signatures: + * {@snippet : + * // Invoked by Marshaller after it has created an instance of this object. + * boolean beforeMarshal(Marshaller); + * + * // Invoked by Marshaller after it has marshalled all properties of this object. + * void afterMarshal(Marshaller); + * } + * The class defined event callback methods should be used when the callback method requires + * access to non-public methods and/or fields of the class. + * <p> + * The external listener callback mechanism enables the registration of a {@link Listener} + * instance with a {@link Marshaller#setListener(Listener)}. The external listener receives all callback events, + * allowing for more centralized processing than per class defined callback methods. + * <p> + * The 'class defined' and external listener event callback methods are independent of each other, + * both can be called for one event. The invocation ordering when both listener callback methods exist is + * defined in {@link Listener#beforeMarshal(Object)} and {@link Listener#afterMarshal(Object)}. + * <p> + * An event callback method throwing an exception terminates the current marshal process. + * </blockquote> + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see JAXBContext + * @see Unmarshaller + * @since 1.6, JAXB 1.0 + */ +public interface Marshaller { + + /** + * The name of the property used to specify the output encoding in + * the marshalled XML data. + */ + String JAXB_ENCODING = + "jaxb.encoding"; + + /** + * The name of the property used to specify whether the marshalled + * XML data is formatted with linefeeds and indentation. + */ + String JAXB_FORMATTED_OUTPUT = + "jaxb.formatted.output"; + + /** + * The name of the property used to specify the xsi:schemaLocation + * attribute value to place in the marshalled XML output. + */ + String JAXB_SCHEMA_LOCATION = + "jaxb.schemaLocation"; + + /** + * The name of the property used to specify the + * xsi:noNamespaceSchemaLocation attribute value to place in the marshalled + * XML output. + */ + String JAXB_NO_NAMESPACE_SCHEMA_LOCATION = + "jaxb.noNamespaceSchemaLocation"; + + /** + * The name of the property used to specify whether the marshaller + * will generate document level events (ie calling startDocument or endDocument). + */ + String JAXB_FRAGMENT = + "jaxb.fragment"; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into the specified + * {@code javax.xml.transform.Result}. + * + * <p> + * All Jakarta XML Binding Providers must at least support + * {@link javax.xml.transform.dom.DOMResult}, + * {@link javax.xml.transform.sax.SAXResult}, and + * {@link javax.xml.transform.stream.StreamResult}. It can + * support other derived classes of {@code Result} as well. + * + * @param jaxbElement + * The root of content tree to be marshalled. + * @param result + * XML will be sent to this Result + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + void marshal(Object jaxbElement, javax.xml.transform.Result result) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into an output stream. + * + * @param jaxbElement + * The root of content tree to be marshalled. + * @param os + * XML will be added to this stream. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + void marshal(Object jaxbElement, java.io.OutputStream os) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into a file. + * + * @param jaxbElement + * The root of content tree to be marshalled. + * @param output + * File to be written. If this file already exists, it will be overwritten. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + * @since 1.6, JAXB 2.1 + */ + void marshal(Object jaxbElement, File output) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into a Writer. + * + * @param jaxbElement + * The root of content tree to be marshalled. + * @param writer + * XML will be sent to this writer. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + void marshal(Object jaxbElement, java.io.Writer writer) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into SAX2 events. + * + * @param jaxbElement + * The root of content tree to be marshalled. + * @param handler + * XML will be sent to this handler as SAX2 events. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + void marshal(Object jaxbElement, org.xml.sax.ContentHandler handler) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into a DOM tree. + * + * @param jaxbElement + * The content tree to be marshalled. + * @param node + * DOM nodes will be added as children of this node. + * This parameter must be a Node that accepts children + * ({@link org.w3c.dom.Document}, + * {@link org.w3c.dom.DocumentFragment}, or + * {@link org.w3c.dom.Element}) + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + */ + void marshal(Object jaxbElement, org.w3c.dom.Node node) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into a + * {@link javax.xml.stream.XMLStreamWriter}. + * + * @param jaxbElement + * The content tree to be marshalled. + * @param writer + * XML will be sent to this writer. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + * @since 1.6, JAXB 2.0 + */ + void marshal(Object jaxbElement, javax.xml.stream.XMLStreamWriter writer) + throws JAXBException; + + /** + * Marshal the content tree rooted at {@code jaxbElement} into a + * {@link javax.xml.stream.XMLEventWriter}. + * + * @param jaxbElement + * The content tree rooted at jaxbElement to be marshalled. + * @param writer + * XML will be sent to this writer. + * + * @throws JAXBException + * If any unexpected problem occurs during the marshalling. + * @throws MarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Marshaller} is unable to marshal {@code jaxbElement} (or any + * object reachable from {@code jaxbElement}). See <a href="#elementMarshalling"> + * Marshalling a Jakarta XML Binding element</a>. + * @throws IllegalArgumentException + * If any of the method parameters are null + * @since 1.6, JAXB 2.0 + */ + void marshal(Object jaxbElement, javax.xml.stream.XMLEventWriter writer) + throws JAXBException; + + /** + * Get a DOM tree view of the content tree(Optional). + * <p> + * If the returned DOM tree is updated, these changes are also + * visible in the content tree. + * Use {@link #marshal(Object, org.w3c.dom.Node)} to force + * a deep copy of the content tree to a DOM representation. + * + * @param contentTree - Jakarta XML Binding Java representation of XML content + * + * @return the DOM tree view of the contentTree + * + * @throws UnsupportedOperationException + * If the Jakarta XML Binding provider implementation does not support a + * DOM view of the content tree + * + * @throws IllegalArgumentException + * If any of the method parameters are null + * + * @throws JAXBException + * If any unexpected problem occurs + * + */ + org.w3c.dom.Node getNode(java.lang.Object contentTree) + throws JAXBException; + + /** + * Set the particular property in the underlying implementation of + * {@code Marshaller}. This method can only be used to set one of + * the standard Jakarta XML Binding defined properties above or a provider specific + * property. Attempting to set an undefined property will result in + * a PropertyException being thrown. See <a href="#supportedProps"> + * Supported Properties</a>. + * + * @param name the name of the property to be set. This value can either + * be specified using one of the constant fields or a user + * supplied string. + * @param value the value of the property to be set + * + * @throws PropertyException when there is an error processing the given + * property or value + * @throws IllegalArgumentException + * If the name parameter is null + */ + void setProperty(String name, Object value) + throws PropertyException; + + /** + * Get the particular property in the underlying implementation of + * {@code Marshaller}. This method can only be used to get one of + * the standard Jakarta XML Binding defined properties above or a provider specific + * property. Attempting to get an undefined property will result in + * a PropertyException being thrown. See <a href="#supportedProps"> + * Supported Properties</a>. + * + * @param name the name of the property to retrieve + * @return the value of the requested property + * + * @throws PropertyException + * when there is an error retrieving the given property or value + * property name + * @throws IllegalArgumentException + * If the name parameter is null + */ + Object getProperty(String name) throws PropertyException; + + /** + * Allow an application to register a validation event handler. + * <p> + * The validation event handler will be called by the Jakarta XML Binding Provider if any + * validation errors are encountered during calls to any of the marshal + * API's. If the client application does not register a validation event + * handler before invoking one of the marshal methods, then validation + * events will be handled by the default event handler which will terminate + * the marshal operation after the first error or fatal error is encountered. + * <p> + * Calling this method with a null parameter will cause the Marshaller + * to revert back to the default event handler. + * + * @param handler the validation event handler + * @throws JAXBException if an error was encountered while setting the + * event handler + */ + void setEventHandler(ValidationEventHandler handler) + throws JAXBException; + + /** + * Return the current event handler or the default event handler if one + * hasn't been set. + * + * @return the current ValidationEventHandler or the default event handler + * if it hasn't been set + * @throws JAXBException if an error was encountered while getting the + * current event handler + */ + ValidationEventHandler getEventHandler() + throws JAXBException; + + + + /** + * Associates a configured instance of {@link XmlAdapter} with this marshaller. + * + * <p> + * This is a convenience method that invokes {@code setAdapter(adapter.getClass(),adapter);}. + * + * @param adapter + * The instance of the adapter to be used. If null, it will un-register + * the current adapter set for this type. + * + * @param <A> the type of the adapter + * + * @see #setAdapter(Class,XmlAdapter) + * @throws IllegalArgumentException + * if the adapter parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> void setAdapter(A adapter); + + /** + * Associates a configured instance of {@link XmlAdapter} with this marshaller. + * + * <p> + * Every marshaller internally maintains a + * {@link java.util.Map}<{@link Class},{@link XmlAdapter}>, + * which it uses for marshalling classes whose fields/methods are annotated + * with {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter}. + * + * <p> + * This method allows applications to use a configured instance of {@link XmlAdapter}. + * When an instance of an adapter is not given, a marshaller will create + * one by invoking its default constructor. + * + * @param type + * The type of the adapter. The specified instance will be used when + * {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()} + * refers to this type. + * @param adapter + * The instance of the adapter to be used. If null, it will un-register + * the current adapter set for this type. + * @param <A> the type of the adapter + * + * @throws IllegalArgumentException + * if the type parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter); + + /** + * Gets the adapter associated with the specified type. + * This is the reverse operation of the {@link #setAdapter} method. + * + * @param type + * The type of the adapter. The specified instance will be used when + * {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()} + * refers to this type. + * + * @param <A> the type of the adapter + * + * @return + * The adapter associated with the specified type. + * + * @throws IllegalArgumentException + * if the type parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type); + + + /** + * Associate a context that enables binary data within an XML document + * to be transmitted as XML-binary optimized attachment. + * The attachment is referenced from the XML document content model + * by content-id URIs(cid) references stored within the xml document. + * + * @param am the attachment marshaller to be set + * + * @throws IllegalStateException if attempt to concurrently call this + * method during a marshal operation. + */ + void setAttachmentMarshaller(AttachmentMarshaller am); + + AttachmentMarshaller getAttachmentMarshaller(); + + /** + * Specify the JAXP {@link javax.xml.validation.Schema Schema} + * object that should be used to validate subsequent marshal operations + * against. Passing null into this method will disable validation. + * + * <p> + * This method allows the caller to validate the marshalled XML as it's marshalled. + * + * <p> + * Initially this property is set to {@code null}. + * + * @param schema Schema object to validate marshal operations against or null to disable validation + * @throws UnsupportedOperationException could be thrown if this method is + * invoked on a Marshaller created from a JAXBContext referencing + * JAXB 1.0 mapped classes + * @since 1.6, JAXB 2.0 + */ + void setSchema(Schema schema); + + /** + * Get the JAXP {@link javax.xml.validation.Schema Schema} object + * being used to perform marshal-time validation. If there is no + * Schema set on the marshaller, then this method will return null + * indicating that marshal-time validation will not be performed. + * + * @return the Schema object being used to perform marshal-time + * validation or null if not present. + * @throws UnsupportedOperationException could be thrown if this method is + * invoked on a Marshaller created from a JAXBContext referencing + * JAXB 1.0 mapped classes + * @since 1.6, JAXB 2.0 + */ + Schema getSchema(); + + /** + * <p> + * Register an instance of an implementation of this class with a {@link Marshaller} to externally listen + * for marshal events. + * </p> + * <p> + * This class enables pre and post processing of each marshalled object. + * The event callbacks are called when marshalling from an instance that maps to an xml element or + * complex type definition. The event callbacks are not called when marshalling from an instance of a + * Java datatype that represents a simple type definition. + * </p> + * <p> + * External listener is one of two different mechanisms for defining marshal event callbacks. + * See <a href="Marshaller.html#marshalEventCallback">Marshal Event Callbacks</a> for an overview. + * + * @see Marshaller#setListener(Listener) + * @see Marshaller#getListener() + * @since 1.6, JAXB 2.0 + */ + abstract class Listener { + + /** + * Do-nothing constructor for the derived classes. + */ + protected Listener() { + } + + /** + * <p> + * Callback method invoked before marshalling from {@code source} to XML. + * </p> + * <p> + * This method is invoked just before marshalling process starts to marshal {@code source}. + * Note that if the class of {@code source} defines its own {@code beforeMarshal} method, + * the class specific callback method is invoked just before this method is invoked. + * + * @param source instance of Jakarta XML Binding mapped class prior to marshalling from it. + */ + public void beforeMarshal(Object source) { + } + + /** + * <p> + * Callback method invoked after marshalling {@code source} to XML. + * </p> + * <p> + * This method is invoked after {@code source} and all its descendants have been marshalled. + * Note that if the class of {@code source} defines its own {@code afterMarshal} method, + * the class specific callback method is invoked just before this method is invoked. + * + * @param source instance of Jakarta XML Binding mapped class after marshalling it. + */ + public void afterMarshal(Object source) { + } + } + + /** + * <p> + * Register marshal event callback {@link Listener} with this {@link Marshaller}. + * + * <p> + * There is only one Listener per Marshaller. Setting a Listener replaces the previous set Listener. + * One can unregister current Listener by setting listener to {@code null}. + * + * @param listener an instance of a class that implements {@link Listener} + * @since 1.6, JAXB 2.0 + */ + void setListener(Listener listener); + + /** + * <p>Return {@link Listener} registered with this {@link Marshaller}. + * + * @return registered {@link Listener} or {@code null} + * if no Listener is registered with this Marshaller. + * @since 1.6, JAXB 2.0 + */ + Listener getListener(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/Messages.java b/api/src/main/java/jakarta/xml/bind/Messages.java new file mode 100644 index 0000000..2d04b09 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/Messages.java
@@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +/** + * Formats error messages. + */ +class Messages +{ + static String format( String property ) { + return format( property, null ); + } + + static String format( String property, Object arg1 ) { + return format( property, new Object[]{arg1} ); + } + + static String format( String property, Object arg1, Object arg2 ) { + return format( property, new Object[]{arg1,arg2} ); + } + + static String format( String property, Object arg1, Object arg2, Object arg3 ) { + return format( property, new Object[]{arg1,arg2,arg3} ); + } + + // add more if necessary. + + /** Loads a string resource and formats it with specified arguments. */ + static String format( String property, Object[] args ) { + String text = ResourceBundle.getBundle(Messages.class.getName()).getString(property); + return MessageFormat.format(text,args); + } + +// +// +// Message resources +// +// + static final String PROVIDER_NOT_FOUND = // 1 arg + "ContextFinder.ProviderNotFound"; + + static final String DEFAULT_PROVIDER_NOT_FOUND = // 0 args + "ContextFinder.DefaultProviderNotFound"; + + static final String COULD_NOT_INSTANTIATE = // 2 args + "ContextFinder.CouldNotInstantiate"; + + static final String CANT_FIND_PROPERTIES_FILE = // 1 arg + "ContextFinder.CantFindPropertiesFile"; + + static final String CANT_MIX_PROVIDERS = // 0 args + "ContextFinder.CantMixProviders"; + + static final String MISSING_PROPERTY = // 2 args + "ContextFinder.MissingProperty"; + + static final String NO_PACKAGE_IN_CONTEXTPATH = // 0 args + "ContextFinder.NoPackageInContextPath"; + + static final String NAME_VALUE = // 2 args + "PropertyException.NameValue"; + + static final String CONVERTER_MUST_NOT_BE_NULL = // 0 args + "DatatypeConverter.ConverterMustNotBeNull"; + + static final String ILLEGAL_CAST = // 2 args + "JAXBContext.IllegalCast"; + + static final String ERROR_LOAD_CLASS = // 2 args + "ContextFinder.ErrorLoadClass"; + + static final String JAXB_CLASSES_NOT_OPEN = // 1 arg + "JAXBClasses.notOpen"; +}
diff --git a/api/src/main/java/jakarta/xml/bind/ModuleUtil.java b/api/src/main/java/jakarta/xml/bind/ModuleUtil.java new file mode 100644 index 0000000..e8b2d04 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ModuleUtil.java
@@ -0,0 +1,169 @@ +/* + * Copyright (c) 2017, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Propagates openness of Jakarta XML Binding annotated classes packages to Jakarta XML Binding impl module. + * + * @author Roman Grigoriadi + */ +class ModuleUtil { + + private static final Logger LOGGER = Logger.getLogger("jakarta.xml.bind"); + + //Android does not contain JPMS related methods added in SE 9+ + private static final boolean JPMS_SUPPORTED; + + static { + boolean b = false; + try { + JAXBContext.class.getModule(); + b = true; + } catch (NoSuchMethodError nsme) { + //android + b = false; + } + JPMS_SUPPORTED = b; + } + + /** + * Resolves classes from context path. + * Only one class per package is needed to access its {@link java.lang.Module} + */ + static Class<?>[] getClassesFromContextPath(String contextPath, ClassLoader classLoader) throws JAXBException { + List<Class<?>> classes = new ArrayList<>(); + if (contextPath == null || contextPath.isEmpty()){ + return classes.toArray(new Class<?>[]{}); + } + + String [] tokens = contextPath.split(":"); + for (String pkg : tokens){ + + // look for ObjectFactory and load it + try { + final Class<?> o = classLoader.loadClass(pkg+".ObjectFactory"); + classes.add(o); + continue; + } catch (ClassNotFoundException e) { + // not necessarily an error + } + + // look for jaxb.index and load the list of classes + try { + final Class<?> firstByJaxbIndex = findFirstByJaxbIndex(pkg, classLoader); + if (firstByJaxbIndex != null) { + classes.add(firstByJaxbIndex); + } + } catch (IOException e) { + throw new JAXBException(e); + } + } + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Resolved classes from context path: {0}", classes); + } + return classes.toArray(new Class<?>[]{}); + } + + /** + * Find first class in package by {@code jaxb.index} file. + */ + static Class<?> findFirstByJaxbIndex(String pkg, ClassLoader classLoader) throws IOException, JAXBException { + final String resource = pkg.replace('.', '/') + "/jaxb.index"; + final InputStream resourceAsStream = classLoader.getResourceAsStream(resource); + + if (resourceAsStream == null) { + return null; + } + + try (BufferedReader in = new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8))) { + String className = in.readLine(); + while (className != null) { + className = className.trim(); + if (className.startsWith("#") || (className.isEmpty())) { + className = in.readLine(); + continue; + } + + try { + return classLoader.loadClass(pkg + '.' + className); + } catch (ClassNotFoundException e) { + throw new JAXBException(Messages.format(Messages.ERROR_LOAD_CLASS, className, pkg), e); + } + + } + } + return null; + } + + /** + * Implementation may be defined in other module than {@code jakarta.xml.bind}. In that case openness + * {@linkplain Module#isOpen open} of classes should be delegated to implementation module. + * + * @param classes used to resolve module for {@linkplain Module#addOpens(String, Module)} + * @param factorySPI used to resolve {@link Module} of the implementation. + * + * @throws JAXBException if ony of a classes package is not open to {@code jakarta.xml.bind} module. + */ + public static void delegateAddOpensToImplModule(Class<?>[] classes, Class<?> factorySPI) throws JAXBException { + if (JPMS_SUPPORTED) { + final Module implModule = factorySPI.getModule(); + + Module jaxbModule = JAXBContext.class.getModule(); + + if (!jaxbModule.isNamed()) { + //we are not on the module path, so assume class-path mode + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Using jakarta.xml.bind-api on the class path."); + } + return; + } + + for (Class<?> cls : classes) { + Class<?> jaxbClass = cls.isArray() ? + cls.getComponentType() : cls; + + final Module classModule = jaxbClass.getModule(); + final String packageName = jaxbClass.getPackageName(); + //no need for unnamed and java.base types + if (!classModule.isNamed() || classModule.getName().equals("java.base")) { + continue; + } + //report error if they are not open to jakarta.xml.bind + if (!classModule.isOpen(packageName, jaxbModule)) { + throw new JAXBException(Messages.format(Messages.JAXB_CLASSES_NOT_OPEN, + packageName, jaxbClass.getName(), classModule.getName())); + } + //propagate openness to impl module + classModule.addOpens(packageName, implModule); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Propagating openness of package {0} in {1} to {2}.", + new String[]{ packageName, classModule.getName(), implModule.getName() }); + } + } + } else { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Using jakarta.xml.bind-api with no JPMS related APIs, such as Class::getModule."); + } + } + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/NotIdentifiableEvent.java b/api/src/main/java/jakarta/xml/bind/NotIdentifiableEvent.java new file mode 100644 index 0000000..dde711c --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/NotIdentifiableEvent.java
@@ -0,0 +1,23 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This event indicates that a problem was encountered resolving an ID/IDREF. + * + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEventHandler + * @since 1.6, JAXB 1.0 + */ +public interface NotIdentifiableEvent extends ValidationEvent { + +}
diff --git a/api/src/main/java/jakarta/xml/bind/ParseConversionEvent.java b/api/src/main/java/jakarta/xml/bind/ParseConversionEvent.java new file mode 100644 index 0000000..c0394b6 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ParseConversionEvent.java
@@ -0,0 +1,25 @@ +/* + * Copyright (c) 2004, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This event indicates that a problem was encountered while converting a + * string from the XML data into a value of the target Java data type. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEvent + * @see ValidationEventHandler + * @see Unmarshaller + * @since 1.6, JAXB 1.0 + */ +public interface ParseConversionEvent extends ValidationEvent { + +}
diff --git a/api/src/main/java/jakarta/xml/bind/PrintConversionEvent.java b/api/src/main/java/jakarta/xml/bind/PrintConversionEvent.java new file mode 100644 index 0000000..0373dd4 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/PrintConversionEvent.java
@@ -0,0 +1,25 @@ +/* + * Copyright (c) 2004, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This event indicates that a problem was encountered while converting data + * from the Java content tree into its lexical representation. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEvent + * @see ValidationEventHandler + * @see Marshaller + * @since 1.6, JAXB 1.0 + */ +public interface PrintConversionEvent extends ValidationEvent { + +}
diff --git a/api/src/main/java/jakarta/xml/bind/PropertyException.java b/api/src/main/java/jakarta/xml/bind/PropertyException.java new file mode 100644 index 0000000..524524b --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/PropertyException.java
@@ -0,0 +1,98 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + + + +/** + * This exception indicates that an error was encountered while getting or + * setting a property. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see JAXBContext + * @see Unmarshaller + * @since 1.6, JAXB 1.0 + */ +public class PropertyException extends JAXBException { + + private static final long serialVersionUID = 3159963351607157477L; + + /** + * Construct a PropertyException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public PropertyException(String message) { + super(message); + } + + /** + * Construct a PropertyException with the specified detail message and + * vendor specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public PropertyException(String message, String errorCode) { + super(message, errorCode); + } + + /** + * Construct a PropertyException with a linkedException. The detail + * message and vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public PropertyException(Throwable exception) { + super(exception); + } + + /** + * Construct a PropertyException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public PropertyException(String message, Throwable exception) { + super(message, exception); + } + + /** + * Construct a PropertyException with the specified detail message, vendor + * specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public PropertyException(String message, + String errorCode, + Throwable exception) { + super(message, errorCode, exception); + } + + /** + * Construct a PropertyException whose message field is set based on the + * name of the property and value.toString(). + * + * @param name the name of the property related to this exception + * @param value the value of the property related to this exception + */ + public PropertyException(String name, Object value) { + super( Messages.format( Messages.NAME_VALUE, + name, + value.toString() ) ); + } + + +}
diff --git a/api/src/main/java/jakarta/xml/bind/SchemaOutputResolver.java b/api/src/main/java/jakarta/xml/bind/SchemaOutputResolver.java new file mode 100644 index 0000000..eb16273 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/SchemaOutputResolver.java
@@ -0,0 +1,74 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import javax.xml.transform.Result; +import java.io.IOException; + +/** + * Controls where a Jakarta XML Binding implementation puts the generates + * schema files. + * + * <p> + * An implementation of this abstract class has to be provided by the calling + * application to generate schemas. + * + * <p> + * This is a class, not an interface to allow future versions to evolve + * without breaking the compatibility. + * + * @author + * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * @since 1.6 + */ +public abstract class SchemaOutputResolver { + + /** + * Do-nothing constructor for the derived classes. + */ + protected SchemaOutputResolver() {} + + /** + * Decides where the schema file (of the given namespace URI) + * will be written, and return it as a {@link Result} object. + * + * <p> + * This method is called only once for any given namespace. + * IOW, all the components in one namespace is always written + * into the same schema document. + * + * @param namespaceUri + * The namespace URI that the schema declares. + * Can be the empty string, but never be null. + * @param suggestedFileName + * A Jakarta XML Binding implementation generates a unique file name (like "schema1.xsd") + * for the convenience of the callee. This name can be + * used for the file name of the schema, or the callee can just + * ignore this name and come up with its own name. + * This is just a hint. + * + * @return + * a {@link Result} object that encapsulates the actual destination + * of the schema. + * <p> + * If the {@link Result} object has a system ID, it must be an + * absolute system ID. Those system IDs are relativized by the caller and used + * for {@literal <xs:import>} statements. + * <p> + * If the {@link Result} object does not have a system ID, a schema + * for the namespace URI is generated but it won't be explicitly + * {@literal <xs:import>}ed from other schemas. + * <p> + * If {@code null} is returned, the schema generation for this + * namespace URI will be skipped. + */ + public abstract Result createOutput( String namespaceUri, String suggestedFileName ) throws IOException; +}
diff --git a/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java b/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java new file mode 100644 index 0000000..63b4ebc --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ServiceLoaderUtil.java
@@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.ServiceLoader; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Shared ServiceLoader/FactoryFinder Utils shared among Jakarta SOAP with Attachments, Jakarta XML Binding + * and Jakarta XML Web Services. + * Class duplicated to all those projects. + * + * @author Miroslav.Kos@oracle.com + */ +class ServiceLoaderUtil { + + private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "org.glassfish.hk2.osgiresourcelocator.ServiceLoader"; + private static final String OSGI_SERVICE_LOADER_METHOD_NAME = "lookupProviderClasses"; + + static <P, T extends Exception> P firstByServiceLoader(Class<P> spiClass, + Logger logger, + ExceptionHandler<T> handler) throws T { + // service discovery + try { + ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass); + + for (P impl : serviceLoader) { + logger.log(Level.FINE, "ServiceProvider loading Facility used; returning object [{0}]", + impl.getClass().getName()); + + return impl; + } + } catch (Throwable t) { + throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]"); + } + return null; + } + + static <T> T lookupUsingOSGiServiceLoader(String factoryId, Logger logger) { + + try { + // Use reflection to avoid having any dependency on ServiceLoader class + @SuppressWarnings("unchecked") + Class<? extends T> serviceClass = (Class<? extends T>) Class.forName(factoryId); + Class<?> target = Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME); + Method m = target.getMethod(OSGI_SERVICE_LOADER_METHOD_NAME, Class.class); + @SuppressWarnings("unchecked") + Iterator<? extends T> iter = ((Iterable<? extends T>) m.invoke(null, serviceClass)).iterator(); + if (iter.hasNext()) { + T next = iter.next(); + logger.log(Level.FINE, "Found implementation using OSGi facility; returning object [{0}].", + next.getClass().getName()); + return next; + } else { + return null; + } + } catch (IllegalAccessException | + InvocationTargetException | + ClassNotFoundException | + NoSuchMethodException ex) { + + logger.log(Level.FINE, "Unable to find from OSGi: [" + factoryId + "]", ex); + return null; + } + } + + @SuppressWarnings("unchecked") + static <T> Iterable<T> lookupsUsingOSGiServiceLoader(String factoryId, Logger logger) { + try { + // Use reflection to avoid having any dependency on ServiceLoader class + return (Iterable<T>) + Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME) + .getMethod(OSGI_SERVICE_LOADER_METHOD_NAME, Class.class) + .invoke(null, Class.forName(factoryId)); + + } catch (IllegalAccessException | + InvocationTargetException | + ClassNotFoundException | + NoSuchMethodException ex) { + + logger.log(Level.FINE, ex, () -> "Unable to find from OSGi: [" + factoryId + "]"); + return null; + } + } + + static void checkPackageAccess(String className) { + // make sure that the current thread has the access to the package of the given name. + SecurityManager s = System.getSecurityManager(); + if (s != null) { + int i = className.lastIndexOf('.'); + if (i != -1) { + s.checkPackageAccess(className.substring(0, i)); + } + } + } + + static Class<?> nullSafeLoadClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + if (classLoader == null) { + return Class.forName(className); + } else { + return classLoader.loadClass(className); + } + } + + // Returns instance of required class. It checks package access (security) + // unless it is defaultClassname. It means if you are trying to instantiate + // default implementation (fallback), pass the class name to both first and second parameter. + static <T extends Exception> Object newInstance(String className, + String defaultImplClassName, + final ExceptionHandler<T> handler) throws T { + try { + return safeLoadClass(className, defaultImplClassName, contextClassLoader(handler)).getConstructor().newInstance(); + } catch (ClassNotFoundException x) { + throw handler.createException(x, "Provider " + className + " not found"); + } catch (Exception x) { + throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x); + } + } + + static Class<?> safeLoadClass(String className, + String defaultImplClassName, + ClassLoader classLoader) throws ClassNotFoundException { + + try { + checkPackageAccess(className); + } catch (SecurityException se) { + // anyone can access the platform default factory class without permission + if (defaultImplClassName != null && defaultImplClassName.equals(className)) { + return Class.forName(className); + } + // not platform default implementation ... + throw se; + } + return nullSafeLoadClass(className, classLoader); + } + + static <T extends Exception> ClassLoader contextClassLoader(ExceptionHandler<T> exceptionHandler) throws T { + try { + return Thread.currentThread().getContextClassLoader(); + } catch (Exception x) { + throw exceptionHandler.createException(x, x.toString()); + } + } + + static abstract class ExceptionHandler<T extends Exception> { + + public abstract T createException(Throwable throwable, String message); + + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/TypeConstraintException.java b/api/src/main/java/jakarta/xml/bind/TypeConstraintException.java new file mode 100644 index 0000000..e3fa8cd --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/TypeConstraintException.java
@@ -0,0 +1,172 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This exception indicates that a violation of a dynamically checked type + * constraint was detected. + * + * <p> + * This exception can be thrown by the generated setter methods of the schema + * derived Java content classes. However, since fail-fast validation is + * an optional feature for Jakarta XML Binding Providers to support, not all setter methods + * will throw this exception when a type constraint is violated. + * + * <p> + * If this exception is throw while invoking a fail-fast setter, the value of + * the property is guaranteed to remain unchanged, as if the setter were never + * called. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEvent + * @since 1.6, JAXB 1.0 + */ + +public class TypeConstraintException extends java.lang.RuntimeException { + + /** + * Vendor specific error code + * + */ + private String errorCode; + + /** + * Exception reference + * + */ + private volatile Throwable linkedException; + + static final long serialVersionUID = -3059799699420143848L; + + /** + * Construct a TypeConstraintException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public TypeConstraintException(String message) { + this( message, null, null ); + } + + /** + * Construct a TypeConstraintException with the specified detail message and vendor + * specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public TypeConstraintException(String message, String errorCode) { + this( message, errorCode, null ); + } + + /** + * Construct a TypeConstraintException with a linkedException. The detail message and + * vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public TypeConstraintException(Throwable exception) { + this( null, null, exception ); + } + + /** + * Construct a TypeConstraintException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public TypeConstraintException(String message, Throwable exception) { + this( message, null, exception ); + } + + /** + * Construct a TypeConstraintException with the specified detail message, + * vendor specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public TypeConstraintException(String message, String errorCode, Throwable exception) { + super( message ); + this.errorCode = errorCode; + this.linkedException = exception; + } + + /** + * Get the vendor specific error code + * + * @return a string specifying the vendor specific error code + */ + public String getErrorCode() { + return this.errorCode; + } + + /** + * Get the linked exception + * + * @return the linked Exception, null if none exists + */ + public Throwable getLinkedException() { + return linkedException; + } + + /** + * Add a linked Exception. + * + * @param exception the linked Exception (A null value is permitted and + * indicates that the linked exception does not exist or + * is unknown). + */ + public void setLinkedException( Throwable exception ) { + this.linkedException = exception; + } + + /** + * Returns a short description of this TypeConstraintException. + * + */ + @Override + public String toString() { + return linkedException == null ? + super.toString() : + super.toString() + "\n - with linked exception:\n[" + + linkedException.toString()+ "]"; + } + + /** + * Prints this TypeConstraintException and its stack trace (including the stack trace + * of the linkedException if it is non-null) to the PrintStream. + * + * @param s PrintStream to use for output + */ + @Override + public void printStackTrace( java.io.PrintStream s ) { + if( linkedException != null ) { + linkedException.printStackTrace(s); + s.println("--------------- linked to ------------------"); + } + + super.printStackTrace(s); + } + + /** + * Prints this TypeConstraintException and its stack trace (including the stack trace + * of the linkedException if it is non-null) to {@code System.err}. + * + */ + @Override + public void printStackTrace() { + printStackTrace(System.err); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/UnmarshalException.java b/api/src/main/java/jakarta/xml/bind/UnmarshalException.java new file mode 100644 index 0000000..458a36f --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/UnmarshalException.java
@@ -0,0 +1,90 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This exception indicates that an error has occurred while performing + * an unmarshal operation that prevents the Jakarta XML Binding Provider from completing + * the operation. + * + * <p> + * The {@code ValidationEventHandler} can cause this exception to be thrown + * during the unmarshal operations. See + * {@link ValidationEventHandler#handleEvent(ValidationEvent) + * ValidationEventHandler.handleEvent(ValidationEvent)}. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see JAXBException + * @see Unmarshaller + * @see ValidationEventHandler + * @since 1.6, JAXB 1.0 + */ +public class UnmarshalException extends JAXBException { + + private static final long serialVersionUID = 6121932693435295453L; + + /** + * Construct an UnmarshalException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public UnmarshalException( String message ) { + this( message, null, null ); + } + + /** + * Construct an UnmarshalException with the specified detail message and vendor + * specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public UnmarshalException( String message, String errorCode ) { + this( message, errorCode, null ); + } + + /** + * Construct an UnmarshalException with a linkedException. The detail message and + * vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public UnmarshalException( Throwable exception ) { + this( null, null, exception ); + } + + /** + * Construct an UnmarshalException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public UnmarshalException( String message, Throwable exception ) { + this( message, null, exception ); + } + + /** + * Construct an UnmarshalException with the specified detail message, vendor + * specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public UnmarshalException( String message, String errorCode, Throwable exception ) { + super( message, errorCode, exception ); + } + +} + +
diff --git a/api/src/main/java/jakarta/xml/bind/Unmarshaller.java b/api/src/main/java/jakarta/xml/bind/Unmarshaller.java new file mode 100644 index 0000000..43c0e94 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/Unmarshaller.java
@@ -0,0 +1,1072 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.attachment.AttachmentUnmarshaller; +import javax.xml.validation.Schema; +import java.io.Reader; + +/** + * The {@code Unmarshaller} class governs the process of deserializing XML + * data into newly created Java content trees, optionally validating the XML + * data as it is unmarshalled. It provides an overloading of unmarshal methods + * for many different input kinds. + * + * <p> + * Unmarshalling from a File: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * Object o = u.unmarshal( new File( "nosferatu.xml" ) ); + * } + * + * + * <p> + * Unmarshalling from an InputStream: + * {@snippet : + * InputStream is = new FileInputStream( "nosferatu.xml" ); + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * Object o = u.unmarshal( is ); + * } + * + * <p> + * Unmarshalling from a URL: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * URL url = new URL( "http://beaker.east/nosferatu.xml" ); + * Object o = u.unmarshal( url ); + * } + * + * <p> + * Unmarshalling from a StringBuffer using a + * {@code javax.xml.transform.stream.StreamSource}: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * StringBuffer xmlStr = new StringBuffer( "<?xml version="1.0"?>..." ); + * Object o = u.unmarshal( new StreamSource( new StringReader( xmlStr.toString() ) ) ); + * } + * + * <p> + * Unmarshalling from a {@code org.w3c.dom.Node}: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * + * DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + * dbf.setNamespaceAware(true); + * DocumentBuilder db = dbf.newDocumentBuilder(); + * Document doc = db.parse(new File( "nosferatu.xml")); + + * Object o = u.unmarshal( doc ); + * } + * + * <p> + * Unmarshalling from a {@code javax.xml.transform.sax.SAXSource} using a + * client specified validating SAX2.0 parser: + * {@snippet : + * // configure a validating SAX2.0 parser (Xerces2) + * static final String JAXP_SCHEMA_LANGUAGE = + * "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + * static final String JAXP_SCHEMA_LOCATION = + * "http://java.sun.com/xml/jaxp/properties/schemaSource"; + * static final String W3C_XML_SCHEMA = + * "http://www.w3.org/2001/XMLSchema"; + * + * System.setProperty( "javax.xml.parsers.SAXParserFactory", + * "org.apache.xerces.jaxp.SAXParserFactoryImpl" ); + * + * SAXParserFactory spf = SAXParserFactory.newInstance(); + * spf.setNamespaceAware(true); + * spf.setValidating(true); + * SAXParser saxParser = spf.newSAXParser(); + * + * try { + * saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); + * saxParser.setProperty(JAXP_SCHEMA_LOCATION, "http://...."); + * } catch (SAXNotRecognizedException x) { + * // exception handling omitted + * } + * + * XMLReader xmlReader = saxParser.getXMLReader(); + * SAXSource source = + * new SAXSource( xmlReader, new InputSource( "http://..." ) ); + * + * // Setup Jakarta XML Binding to unmarshal + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * ValidationEventCollector vec = new ValidationEventCollector(); + * u.setEventHandler( vec ); + * + * // turn off the Jakarta XML Binding provider's default validation mechanism to + * // avoid duplicate validation + * u.setValidating( false ) + * + * // unmarshal + * Object o = u.unmarshal( source ); + * + * // check for events + * if( vec.hasEvents() ) { + * // iterate over events + * } + * } + * + * <p> + * Unmarshalling from a StAX XMLStreamReader: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * + * javax.xml.stream.XMLStreamReader xmlStreamReader = + * javax.xml.stream.XMLInputFactory().newInstance().createXMLStreamReader( ... ); + * + * Object o = u.unmarshal( xmlStreamReader ); + * } + * + * <p> + * Unmarshalling from a StAX XMLEventReader: + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * + * javax.xml.stream.XMLEventReader xmlEventReader = + * javax.xml.stream.XMLInputFactory().newInstance().createXMLEventReader( ... ); + * + * Object o = u.unmarshal( xmlEventReader ); + * } + * + * <p> + * <a id="unmarshalEx"></a> + * <b>Unmarshalling XML Data</b><br> + * <blockquote> + * Unmarshalling can deserialize XML data that represents either an entire XML document + * or a subtree of an XML document. Typically, it is sufficient to use the + * unmarshalling methods described by + * <a href="#unmarshalGlobal">Unmarshal root element that is declared globally</a>. + * These unmarshal methods utilize {@link JAXBContext}'s mapping of global XML element + * declarations and type definitions to Jakarta XML Binding mapped classes to initiate the + * unmarshalling of the root element of XML data. When the {@link JAXBContext}'s + * mappings are not sufficient to unmarshal the root element of XML data, + * the application can assist the unmarshalling process by using the + * <a href="#unmarshalByDeclaredType">unmarshal by declaredType methods</a>. + * These methods are useful for unmarshalling XML data where + * the root element corresponds to a local element declaration in the schema. + * </blockquote> + * + * <blockquote> + * An unmarshal method never returns null. If the unmarshal process is unable to unmarshal + * the root of XML content to a Jakarta XML Binding mapped object, a fatal error is reported that + * terminates processing by throwing JAXBException. + * </blockquote> + * + * <p> + * <a id="unmarshalGlobal"></a> + * <b>Unmarshal a root element that is globally declared</b><br> + * <blockquote> + * The unmarshal methods that do not have an {@code declaredType} parameter use + * {@link JAXBContext} to unmarshal the root element of an XML data. The {@link JAXBContext} + * instance is the one that was used to create this {@code Unmarshaller}. The {@link JAXBContext} + * instance maintains a mapping of globally declared XML element and type definition names to + * Jakarta XML Binding mapped classes. The unmarshal method checks if {@link JAXBContext} has a mapping + * from the root element's XML name and/or {@code @xsi:type} to a Jakarta XML Binding mapped class. If it does, it unmarshalls the + * XML data using the appropriate Jakarta XML Binding mapped class. Note that when the root element name is unknown and the root + * element has an {@code @xsi:type}, the XML data is unmarshalled + * using that Jakarta XML Binding mapped class as the value of a {@link JAXBElement}. + * When the {@link JAXBContext} object does not have a mapping for the root element's name + * nor its {@code @xsi:type}, if it exists, + * then the unmarshal operation will abort immediately by throwing a {@link UnmarshalException + * UnmarshalException}. This exception scenario can be worked around by using the unmarshal by + * declaredType methods described in the next subsection. + * </blockquote> + * + * <p> + * <a id="unmarshalByDeclaredType"></a> + * <b>Unmarshal by Declared Type</b><br> + * <blockquote> + * The unmarshal methods with a {@code declaredType} parameter enable an + * application to deserialize a root element of XML data, even when + * there is no mapping in {@link JAXBContext} of the root element's XML name. + * The unmarshaller unmarshalls the root element using the application provided + * mapping specified as the {@code declaredType} parameter. + * Note that even when the root element's element name is mapped by {@link JAXBContext}, + * the {@code declaredType} parameter overrides that mapping for + * deserializing the root element when using these unmarshal methods. + * Additionally, when the root element of XML data has an {@code xsi:type} attribute and + * that attribute's value references a type definition that is mapped + * to a Jakarta XML Binding mapped class by {@link JAXBContext}, that the root + * element's {@code xsi:type} attribute takes + * precedence over the unmarshal methods {@code declaredType} parameter. + * These methods always return a {@code JAXBElement<declaredType>} + * instance. The table below shows how the properties of the returned JAXBElement + * instance are set. + * + * <a id="unmarshalDeclaredTypeReturn"></a> + * <table class="striped"> + * <caption>Unmarshal By Declared Type returned JAXBElement</caption> + * <thead> + * <tr> + * <th scope="col">JAXBElement Property</th> + * <th scope="col">Value</th> + * </tr> + * <tr> + * <th scope="col">name</th> + * <th scope="col">{@code xml element name}</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <th scope="row">value</th> + * <td>{@code instanceof declaredType}</td> + * </tr> + * <tr> + * <th scope="row">declaredType</th> + * <td>unmarshal method {@code declaredType} parameter</td> + * </tr> + * <tr> + * <th scope="row">scope</th> + * <td>{@code null} <i>(actual scope is unknown)</i></td> + * </tr> + * </tbody> + * </table> + * </blockquote> + * + * <p> + * The following is an example of + * <a href="#unmarshalByDeclaredType">unmarshal by declaredType method</a>. + * <p> + * Unmarshal by declaredType from a {@code org.w3c.dom.Node}: + * {@snippet lang="XML" : + * <!-- Schema fragment for example --> + * <xs:schema> + * <xs:complexType name="FooType">...</xs:complexType> + * <!-- global element declaration "PurchaseOrder" --> + * <xs:element name="PurchaseOrder"> + * <xs:complexType> + * <xs:sequence> + * <!-- local element declaration "foo" --> + * <xs:element name="foo" type="FooType"/> + * ... + * </xs:sequence> + * </xs:complexType> + * </xs:element> + * </xs:schema> + * } + * {@snippet : + * JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); + * Unmarshaller u = jc.createUnmarshaller(); + * + * DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + * dbf.setNamespaceAware(true); + * DocumentBuilder db = dbf.newDocumentBuilder(); + * Document doc = db.parse(new File( "nosferatu.xml")); + * Element fooSubtree = ...; // traverse DOM till reach xml element foo, constrained by a + * // local element declaration in schema. + * + * // FooType is the Jakarta XML Binding mapping of the type of local element declaration foo. + * JAXBElement<FooType> foo = u.unmarshal( fooSubtree, FooType.class); + * } + * + * <p> + * <b>Support for SAX2.0 Compliant Parsers</b><br> + * <blockquote> + * A client application has the ability to select the SAX2.0 compliant parser + * of their choice. If a SAX parser is not selected, then the Jakarta XML Binding Provider's + * default parser will be used. Even though the Jakarta XML Binding Provider's default parser + * is not required to be SAX2.0 compliant, all providers are required to allow + * a client application to specify their own SAX2.0 parser. Some providers may + * require the client application to specify the SAX2.0 parser at schema compile + * time. See {@link #unmarshal(javax.xml.transform.Source) unmarshal(Source)} + * for more detail. + * </blockquote> + * + * <p> + * <b>Validation and Well-Formedness</b><br> + * <blockquote> + * <p> + * A client application can enable or disable JAXP validation + * mechanism via the {@code setSchema(javax.xml.validation.Schema)} API. + * Sophisticated clients can specify their own validating SAX 2.0 compliant + * parser and bypass the JAXP validation mechanism using the + * {@link #unmarshal(javax.xml.transform.Source) unmarshal(Source)} API. + * + * <p> + * Since unmarshalling invalid XML content is defined in Jakarta XML Binding, + * the Unmarshaller default validation event handler was made more lenient + * than in JAXB 1.0. When schema-derived code generated + * by JAXB 1.0 binding compiler is registered with {@link JAXBContext}, + * the default unmarshal validation handler is + * {@link jakarta.xml.bind.helpers.DefaultValidationEventHandler} and it + * terminates the marshal operation after encountering either a fatal error or an error. + * For a Jakarta XML Binding client application, there is no explicitly defined default + * validation handler and the default event handling only + * terminates the unmarshal operation after encountering a fatal error. + * </blockquote> + * + * <p> + * <a id="supportedProps"></a> + * <b>Supported Properties</b><br> + * <blockquote> + * <p> + * There currently are not any properties required to be supported by all + * Jakarta XML Binding Providers on Unmarshaller. However, some providers may support + * their own set of provider specific properties. + * </blockquote> + * + * <p> + * <a id="unmarshalEventCallback"></a> + * <b>Unmarshal Event Callbacks</b><br> + * <blockquote> + * The {@link Unmarshaller} provides two styles of callback mechanisms + * that allow application specific processing during key points in the + * unmarshalling process. In 'class defined' event callbacks, application + * specific code placed in Jakarta XML Binding mapped classes is triggered during + * unmarshalling. 'External listeners' allow for centralized processing + * of unmarshal events in one callback method rather than by type event callbacks. + * <p> + * 'Class defined' event callback methods allow any Jakarta XML Binding mapped class to specify + * its own specific callback methods by defining methods with the following method signature: + * {@snippet : + * // This method is called immediately after the object is created and before the unmarshalling of this + * // object begins. The callback provides an opportunity to initialize JavaBean properties prior to unmarshalling. + * void beforeUnmarshal(Unmarshaller, Object parent); + * + * //This method is called after all the properties (except IDREF) are unmarshalled for this object, + * //but before this object is set to the parent object. + * void afterUnmarshal(Unmarshaller, Object parent); + * } + * The class defined callback methods should be used when the callback method requires + * access to non-public methods and/or fields of the class. + * <p> + * The external listener callback mechanism enables the registration of a {@link Listener} + * instance with an {@link Unmarshaller#setListener(Listener)}. The external listener receives all callback events, + * allowing for more centralized processing than per class defined callback methods. The external listener + * receives events when unmarshalling process is marshalling to a Jakarta XML Binding element or to Jakarta XML Binding mapped class. + * <p> + * The 'class defined' and external listener event callback methods are independent of each other, + * both can be called for one event. The invocation ordering when both listener callback methods exist is + * defined in {@link Listener#beforeUnmarshal(Object, Object)} and {@link Listener#afterUnmarshal(Object, Object)}. +* <p> + * An event callback method throwing an exception terminates the current unmarshal process. + * </blockquote> + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see JAXBContext + * @see Marshaller + * @since 1.6, JAXB 1.0 + */ +public interface Unmarshaller { + + /** + * Unmarshal XML data from the specified file and return the resulting + * content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param f the file to unmarshal XML data from + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the file parameter is null + */ + Object unmarshal(java.io.File f) throws JAXBException; + + /** + * Unmarshal XML data from the specified InputStream and return the + * resulting content tree. Validation event location information may + * be incomplete when using this form of the unmarshal API. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param is the InputStream to unmarshal XML data from + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the InputStream parameter is null + */ + Object unmarshal(java.io.InputStream is) throws JAXBException; + + /** + * Unmarshal XML data from the specified Reader and return the + * resulting content tree. Validation event location information may + * be incomplete when using this form of the unmarshal API, + * because a Reader does not provide the system ID. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param reader the Reader to unmarshal XML data from + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the InputStream parameter is null + * @since 1.6, JAXB 2.0 + */ + Object unmarshal(Reader reader) throws JAXBException; + + /** + * Unmarshal XML data from the specified URL and return the resulting + * content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param url the url to unmarshal XML data from + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the URL parameter is null + */ + Object unmarshal(java.net.URL url) throws JAXBException; + + /** + * Unmarshal XML data from the specified SAX InputSource and return the + * resulting content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param source the input source to unmarshal XML data from + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the InputSource parameter is null + */ + Object unmarshal(org.xml.sax.InputSource source) throws JAXBException; + + /** + * Unmarshal global XML data from the specified DOM tree and return the resulting + * content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * @param node + * the document/element to unmarshal XML data from. + * The caller must support at least Document and Element. + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the Node parameter is null + * @see #unmarshal(org.w3c.dom.Node, Class) + */ + Object unmarshal(org.w3c.dom.Node node) throws JAXBException; + + /** + * Unmarshal XML data by Jakarta XML Binding mapped {@code declaredType} + * and return the resulting content tree. + * + * <p> + * Implements <a href="#unmarshalByDeclaredType">Unmarshal by Declared Type</a> + * + * @param node + * the document/element to unmarshal XML data from. + * The caller must support at least Document and Element. + * @param declaredType + * appropriate Jakarta XML Binding mapped class to hold {@code node}'s XML data. + * + * @param <T> the XML Binding mapped class + * + * @return <a href="#unmarshalDeclaredTypeReturn">JAXBElement</a> representation of {@code node} + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If any parameter is null + * @since 1.6, JAXB 2.0 + */ + <T> JAXBElement<T> unmarshal(org.w3c.dom.Node node, Class<T> declaredType) throws JAXBException; + + /** + * Unmarshal XML data from the specified XML Source and return the + * resulting content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * <p> + * <a id="saxParserPlugable"></a> + * <b>SAX 2.0 Parser Pluggability</b> + * <p> + * A client application can choose not to use the default parser mechanism + * supplied with their Jakarta XML Binding provider. Any SAX 2.0 compliant parser can be + * substituted for the Jakarta XML Binding provider's default mechanism. To do so, the + * client application must properly configure a {@code SAXSource} containing + * an {@code XMLReader} implemented by the SAX 2.0 parser provider. If the + * {@code XMLReader} has an {@code org.xml.sax.ErrorHandler} registered + * on it, it will be replaced by the Jakarta XML Binding Provider so that validation errors + * can be reported via the {@code ValidationEventHandler} mechanism of + * Jakarta XML Binding. If the {@code SAXSource} does not contain an {@code XMLReader}, + * then the Jakarta XML Binding provider's default parser mechanism will be used. + * <p> + * This parser replacement mechanism can also be used to replace the Jakarta XML Binding + * provider's unmarshal-time validation engine. The client application + * must properly configure their SAX 2.0 compliant parser to perform + * validation (as shown in the example above). Any {@code SAXParserExceptions} + * encountered by the parser during the unmarshal operation will be + * processed by the Jakarta XML Binding provider and converted into Jakarta XML Binding + * {@code ValidationEvent} objects which will be reported back to the + * client via the {@code ValidationEventHandler} registered with the + * {@code Unmarshaller}. <i>Note:</i> specifying a substitute validating + * SAX 2.0 parser for unmarshalling does not necessarily replace the + * validation engine used by the Jakarta XML Binding provider for performing on-demand + * validation. + * <p> + * The only way for a client application to specify an alternate parser + * mechanism to be used during unmarshal is via the + * {@code unmarshal(SAXSource)} API. All other forms of the unmarshal + * method (File, URL, Node, etc.) will use the Jakarta XML Binding provider's default + * parser and validator mechanisms. + * + * @param source the XML Source to unmarshal XML data from (providers are + * only required to support SAXSource, DOMSource, and StreamSource) + * @return the newly created root object of the java content tree + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the Source parameter is null + * @see #unmarshal(javax.xml.transform.Source, Class) + */ + Object unmarshal(javax.xml.transform.Source source) + throws JAXBException; + + + /** + * Unmarshal XML data from the specified XML Source by {@code declaredType} and return the + * resulting content tree. + * + * <p> + * Implements <a href="#unmarshalByDeclaredType">Unmarshal by Declared Type</a> + * + * <p> + * See <a href="#saxParserPlugable">SAX 2.0 Parser Pluggability</a> + * + * @param source the XML Source to unmarshal XML data from (providers are + * only required to support SAXSource, DOMSource, and StreamSource) + * @param declaredType + * appropriate Jakarta XML Binding mapped class to hold {@code source}'s xml root element + * + * @param <T> the XML Binding mapped class + * + * @return Java content rooted by <a href="#unmarshalDeclaredTypeReturn">JAXBElement</a> + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If any parameter is null + * @since 1.6, JAXB 2.0 + */ + <T> JAXBElement<T> unmarshal(javax.xml.transform.Source source, Class<T> declaredType) + throws JAXBException; + + /** + * Unmarshal XML data from the specified pull parser and return the + * resulting content tree. + * + * <p> + * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>. + * + * <p> + * This method assumes that the parser is on a START_DOCUMENT or + * START_ELEMENT event. Unmarshalling will be done from this + * start event to the corresponding end event. If this method + * returns successfully, the {@code reader} will be pointing at + * the token right after the end event. + * + * @param reader + * The parser to be read. + * @return + * the newly created root object of the java content tree. + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the {@code reader} parameter is null + * @throws IllegalStateException + * If {@code reader} is not pointing to a START_DOCUMENT or + * START_ELEMENT event. + * @since 1.6, JAXB 2.0 + * @see #unmarshal(javax.xml.stream.XMLStreamReader, Class) + */ + Object unmarshal(javax.xml.stream.XMLStreamReader reader) + throws JAXBException; + + /** + * Unmarshal root element to Jakarta XML Binding mapped {@code declaredType} + * and return the resulting content tree. + * + * <p> + * This method implements <a href="#unmarshalByDeclaredType">unmarshal by declaredType</a>. + * <p> + * This method assumes that the parser is on a START_DOCUMENT or + * START_ELEMENT event. Unmarshalling will be done from this + * start event to the corresponding end event. If this method + * returns successfully, the {@code reader} will be pointing at + * the token right after the end event. + * + * @param reader + * The parser to be read. + * @param declaredType + * appropriate Jakarta XML Binding mapped class to hold {@code reader}'s START_ELEMENT XML data. + * + * @param <T> the XML Binding mapped class + * + * @return content tree rooted by <a href="#unmarshalDeclaredTypeReturn">JAXBElement</a> representation + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If any parameter is null + * @since 1.6, JAXB 2.0 + */ + <T> JAXBElement<T> unmarshal(javax.xml.stream.XMLStreamReader reader, Class<T> declaredType) throws JAXBException; + + /** + * Unmarshal XML data from the specified pull parser and return the + * resulting content tree. + * + * <p> + * This method is an <a href="#unmarshalGlobal">Unmarshal Global Root method</a>. + * + * <p> + * This method assumes that the parser is on a START_DOCUMENT or + * START_ELEMENT event. Unmarshalling will be done from this + * start event to the corresponding end event. If this method + * returns successfully, the {@code reader} will be pointing at + * the token right after the end event. + * + * @param reader + * The parser to be read. + * @return + * the newly created root object of the java content tree. + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If the {@code reader} parameter is null + * @throws IllegalStateException + * If {@code reader} is not pointing to a START_DOCUMENT or + * START_ELEMENT event. + * @since 1.6, JAXB 2.0 + * @see #unmarshal(javax.xml.stream.XMLEventReader, Class) + */ + Object unmarshal(javax.xml.stream.XMLEventReader reader) + throws JAXBException; + + /** + * Unmarshal root element to Jakarta XML Binding mapped {@code declaredType} + * and return the resulting content tree. + * + * <p> + * This method implements <a href="#unmarshalByDeclaredType">unmarshal by declaredType</a>. + * + * <p> + * This method assumes that the parser is on a START_DOCUMENT or + * START_ELEMENT event. Unmarshalling will be done from this + * start event to the corresponding end event. If this method + * returns successfully, the {@code reader} will be pointing at + * the token right after the end event. + * + * @param reader + * The parser to be read. + * @param declaredType + * appropriate Jakarta XML Binding mapped class to hold {@code reader}'s START_ELEMENT XML data. + * + * @param <T> the XML Binding mapped class + * + * @return content tree rooted by <a href="#unmarshalDeclaredTypeReturn">JAXBElement</a> representation + * + * @throws JAXBException + * If any unexpected errors occur while unmarshalling + * @throws UnmarshalException + * If the {@link ValidationEventHandler ValidationEventHandler} + * returns false from its {@code handleEvent} method or the + * {@code Unmarshaller} is unable to perform the XML to Java + * binding. See <a href="#unmarshalEx">Unmarshalling XML Data</a> + * @throws IllegalArgumentException + * If any parameter is null + * @since 1.6, JAXB 2.0 + */ + <T> JAXBElement<T> unmarshal(javax.xml.stream.XMLEventReader reader, Class<T> declaredType) throws JAXBException; + + /** + * Get an unmarshaller handler object that can be used as a component in + * an XML pipeline. + * + * <p> + * The Jakarta XML Binding Provider can return the same handler object for multiple + * invocations of this method. In other words, this method does not + * necessarily create a new instance of {@code UnmarshallerHandler}. If the + * application needs to use more than one {@code UnmarshallerHandler}, it + * should create more than one {@code Unmarshaller}. + * + * @return the unmarshaller handler object + * @see UnmarshallerHandler + */ + UnmarshallerHandler getUnmarshallerHandler(); + + /** + * Allow an application to register a {@code ValidationEventHandler}. + * <p> + * The {@code ValidationEventHandler} will be called by the Jakarta XML Binding Provider + * if any validation errors are encountered during calls to any of the + * unmarshal methods. If the client application does not register a + * {@code ValidationEventHandler} before invoking the unmarshal methods, + * then {@code ValidationEvents} will be handled by the default event + * handler which will terminate the unmarshal operation after the first + * error or fatal error is encountered. + * <p> + * Calling this method with a null parameter will cause the Unmarshaller + * to revert back to the default event handler. + * + * @param handler the validation event handler + * @throws JAXBException if an error was encountered while setting the + * event handler + */ + void setEventHandler(ValidationEventHandler handler) + throws JAXBException; + + /** + * Return the current event handler or the default event handler if one + * hasn't been set. + * + * @return the current ValidationEventHandler or the default event handler + * if it hasn't been set + * @throws JAXBException if an error was encountered while getting the + * current event handler + */ + ValidationEventHandler getEventHandler() + throws JAXBException; + + /** + * Set the particular property in the underlying implementation of + * {@code Unmarshaller}. This method can only be used to set one of + * the standard Jakarta XML Binding defined properties above or a provider specific + * property. Attempting to set an undefined property will result in + * a PropertyException being thrown. See <a href="#supportedProps"> + * Supported Properties</a>. + * + * @param name the name of the property to be set. This value can either + * be specified using one of the constant fields or a user + * supplied string. + * @param value the value of the property to be set + * + * @throws PropertyException when there is an error processing the given + * property or value + * @throws IllegalArgumentException + * If the name parameter is null + */ + void setProperty(String name, Object value) + throws PropertyException; + + /** + * Get the particular property in the underlying implementation of + * {@code Unmarshaller}. This method can only be used to get one of + * the standard Jakarta XML Binding defined properties above or a provider specific + * property. Attempting to get an undefined property will result in + * a PropertyException being thrown. See <a href="#supportedProps"> + * Supported Properties</a>. + * + * @param name the name of the property to retrieve + * @return the value of the requested property + * + * @throws PropertyException + * when there is an error retrieving the given property or value + * property name + * @throws IllegalArgumentException + * If the name parameter is null + */ + Object getProperty(String name) throws PropertyException; + + /** + * Specify the JAXP {@link javax.xml.validation.Schema Schema} + * object that should be used to validate subsequent unmarshal operations + * against. Passing null into this method will disable validation. + * + * <p> + * Initially this property is set to {@code null}. + * + * @param schema Schema object to validate unmarshal operations against or null to disable validation + * @throws UnsupportedOperationException could be thrown if this method is + * invoked on an Unmarshaller created from a JAXBContext referencing + * JAXB 1.0 mapped classes + * @since 1.6, JAXB 2.0 + */ + void setSchema(Schema schema); + + /** + * Get the JAXP {@link javax.xml.validation.Schema Schema} object + * being used to perform unmarshal-time validation. If there is no + * Schema set on the unmarshaller, then this method will return null + * indicating that unmarshal-time validation will not be performed. + * + * @return the Schema object being used to perform unmarshal-time + * validation or null if not present + * @throws UnsupportedOperationException could be thrown if this method is + * invoked on an Unmarshaller created from a JAXBContext referencing + * JAXB 1.0 mapped classes + * @since 1.6, JAXB 2.0 + */ + Schema getSchema(); + + /** + * Associates a configured instance of {@link XmlAdapter} with this unmarshaller. + * + * <p> + * This is a convenience method that invokes {@code setAdapter(adapter.getClass(),adapter);}. + * + * @param adapter the configured instance of {@link XmlAdapter} + * + * @param <A> the type of {@link XmlAdapter} + * + * @see #setAdapter(Class,XmlAdapter) + * @throws IllegalArgumentException + * if the adapter parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> void setAdapter(A adapter); + + /** + * Associates a configured instance of {@link XmlAdapter} with this unmarshaller. + * + * <p> + * Every unmarshaller internally maintains a + * {@link java.util.Map}<{@link Class},{@link XmlAdapter}>, + * which it uses for unmarshalling classes whose fields/methods are annotated + * with {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter}. + * + * <p> + * This method allows applications to use a configured instance of {@link XmlAdapter}. + * When an instance of an adapter is not given, an unmarshaller will create + * one by invoking its default constructor. + * + * @param type + * The type of the adapter. The specified instance will be used when + * {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()} + * refers to this type. + * @param adapter + * The instance of the adapter to be used. If null, it will un-register + * the current adapter set for this type. + * + * @param <A> the type of the adapter + * + * @throws IllegalArgumentException + * if the type parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter); + + /** + * Gets the adapter associated with the specified type. + * This is the reverse operation of the {@link #setAdapter} method. + * + * + * @param type + * The type of the adapter. The specified instance will be used when + * {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()} + * refers to this type. + * + * @param <A> the type of the adapter + * + * @return + * The adapter associated with the specified type. + * + * @throws IllegalArgumentException + * if the type parameter is null. + * @throws UnsupportedOperationException + * if invoked against a JAXB 1.0 implementation. + * @since 1.6, JAXB 2.0 + */ + <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type); + + /** + * Associate a context that resolves cid's, content-id URIs, to + * binary data passed as attachments. + * Unmarshal time validation, enabled via {@link #setSchema(Schema)}, + * must be supported even when unmarshaller is performing XOP processing. + * + * @param au the attachment unmarshaller to be set + * + * @throws IllegalStateException if attempt to concurrently call this + * method during an unmarshal operation. + */ + void setAttachmentUnmarshaller(AttachmentUnmarshaller au); + + AttachmentUnmarshaller getAttachmentUnmarshaller(); + + /** + * <p> + * Register an instance of an implementation of this class with {@link Unmarshaller} to externally listen + * for unmarshal events. + * </p> + * <p> + * This class enables pre and post processing of an instance of a Jakarta XML Binding mapped class + * as XML data is unmarshalled into it. The event callbacks are called when unmarshalling + * XML content into a JAXBElement instance or a Jakarta XML Binding mapped class that represents a complex type definition. + * The event callbacks are not called when unmarshalling to an instance of a + * Java datatype that represents a simple type definition. + * </p> + * <p> + * External listener is one of two different mechanisms for defining unmarshal event callbacks. + * See <a href="Unmarshaller.html#unmarshalEventCallback">Unmarshal Event Callbacks</a> for an overview. + * </p> + * (@link #setListener(Listener)} + * (@link #getListener()} + * + * @since 1.6, JAXB 2.0 + */ + abstract class Listener { + + /** + * Do-nothing constructor for the derived classes. + */ + protected Listener() { + } + + /** + * <p> + * Callback method invoked before unmarshalling into {@code target}. + * </p> + * <p> + * This method is invoked immediately after {@code target} was created and + * before the unmarshalling of this object begins. Note that + * if the class of {@code target} defines its own {@code beforeUnmarshal} method, + * the class specific callback method is invoked before this method is invoked. + * + * @param target non-null instance of Jakarta XML Binding mapped class prior to unmarshalling into it. + * @param parent instance of Jakarta XML Binding mapped class that will eventually reference {@code target}. + * {@code null} when {@code target} is root element. + */ + public void beforeUnmarshal(Object target, Object parent) { + } + + /** + * <p> + * Callback method invoked after unmarshalling XML data into {@code target}. + * </p> + * <p> + * This method is invoked after all the properties (except IDREF) + * are unmarshalled into {@code target}, + * but before {@code target} is set into its {@code parent} object. + * Note that if the class of {@code target} defines its own {@code afterUnmarshal} method, + * the class specific callback method is invoked before this method is invoked. + * + * @param target non-null instance of Jakarta XML Binding mapped class prior to unmarshalling into it. + * @param parent instance of Jakarta XML Binding mapped class that will reference {@code target}. + * {@code null} when {@code target} is root element. + */ + public void afterUnmarshal(Object target, Object parent) { + } + } + + /** + * <p> + * Register unmarshal event callback {@link Listener} with this {@link Unmarshaller}. + * + * <p> + * There is only one Listener per Unmarshaller. Setting a Listener replaces the previous set Listener. + * One can unregister current Listener by setting listener to {@code null}. + * + * @param listener provides unmarshal event callbacks for this {@link Unmarshaller} + * @since 1.6, JAXB 2.0 + */ + void setListener(Listener listener); + + /** + * <p>Return {@link Listener} registered with this {@link Unmarshaller}. + * + * @return registered {@link Listener} or {@code null} + * if no Listener is registered with this Unmarshaller. + * @since 1.6, JAXB 2.0 + */ + Listener getListener(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/UnmarshallerHandler.java b/api/src/main/java/jakarta/xml/bind/UnmarshallerHandler.java new file mode 100644 index 0000000..ea9aa51 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/UnmarshallerHandler.java
@@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +import org.xml.sax.ContentHandler; + +/** + * Unmarshaller implemented as SAX ContentHandler. + * + * <p> + * Applications can use this interface to use their Jakarta XML Binding provider as a component + * in an XML pipeline. For example: + * + * {@snippet : + * JAXBContext context = JAXBContext.newInstance( "org.acme.foo" ); + * + * Unmarshaller unmarshaller = context.createUnmarshaller(); + * + * UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler(); + * + * SAXParserFactory spf = SAXParserFactory.newInstance(); + * spf.setNamespaceAware( true ); + * + * XMLReader xmlReader = spf.newSAXParser().getXMLReader(); + * xmlReader.setContentHandler( unmarshallerHandler ); + * xmlReader.parse(new InputSource( new FileInputStream( XML_FILE ) ) ); + * + * MyObject myObject= (MyObject)unmarshallerHandler.getResult(); + * } + * + * <p> + * This interface is reusable: even if the user fails to unmarshal + * an object, s/he can still start a new round of unmarshalling. + * + * @author <ul><li>Kohsuke KAWAGUCHI, Sun Microsystems, Inc.</li></ul> + * @see Unmarshaller#getUnmarshallerHandler() + * @since 1.6, JAXB 1.0 + */ +public interface UnmarshallerHandler extends ContentHandler +{ + /** + * Obtains the unmarshalled result. + * <p> + * This method can be called only after this handler + * receives the endDocument SAX event. + * + * @exception IllegalStateException + * if this method is called before this handler + * receives the endDocument event. + * + * @exception JAXBException + * if there is any unmarshalling error. + * Note that the implementation is allowed to throw SAXException + * during the parsing when it finds an error. + * + * @return + * always return a non-null valid object which was unmarshalled. + */ + Object getResult() throws JAXBException, IllegalStateException; +}
diff --git a/api/src/main/java/jakarta/xml/bind/ValidationEvent.java b/api/src/main/java/jakarta/xml/bind/ValidationEvent.java new file mode 100644 index 0000000..6a231f9 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ValidationEvent.java
@@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This event indicates that a problem was encountered while validating the + * incoming XML data during an unmarshal operation, while performing + * on-demand validation of the Java content tree, or while marshalling the + * Java content tree back to XML data. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEventHandler + * @since 1.6, JAXB 1.0 + */ +public interface ValidationEvent { + + /** + * Conditions that are not errors or fatal errors as defined by the + * XML 1.0 recommendation + */ + int WARNING = 0; + + /** + * Conditions that correspond to the definition of "error" in section + * 1.2 of the W3C XML 1.0 Recommendation + */ + int ERROR = 1; + + /** + * Conditions that correspond to the definition of "fatal error" in section + * 1.2 of the W3C XML 1.0 Recommendation + */ + int FATAL_ERROR = 2; + + /** + * Retrieve the severity code for this warning/error. + * + * <p> + * Must be one of {@code ValidationEvent.WARNING}, + * {@code ValidationEvent.ERROR}, or {@code ValidationEvent.FATAL_ERROR}. + * + * @return the severity code for this warning/error + */ + int getSeverity(); + + /** + * Retrieve the text message for this warning/error. + * + * @return the text message for this warning/error or null if one wasn't set + */ + String getMessage(); + + /** + * Retrieve the linked exception for this warning/error. + * + * @return the linked exception for this warning/error or null if one + * wasn't set + */ + Throwable getLinkedException(); + + /** + * Retrieve the locator for this warning/error. + * + * @return the locator that indicates where the warning/error occurred + */ + ValidationEventLocator getLocator(); + +}
diff --git a/api/src/main/java/jakarta/xml/bind/ValidationEventHandler.java b/api/src/main/java/jakarta/xml/bind/ValidationEventHandler.java new file mode 100644 index 0000000..10d8ba6 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ValidationEventHandler.java
@@ -0,0 +1,86 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * A basic event handler interface for validation errors. + * + * <p> + * If an application needs to implement customized event handling, it must + * implement this interface and then register it with either the + * {@link Unmarshaller#setEventHandler(ValidationEventHandler) Unmarshaller}, or + * the {@link Marshaller#setEventHandler(ValidationEventHandler) Marshaller}. + * The Jakarta XML Binding Provider will then report validation errors and warnings encountered + * during the unmarshal, marshal, and validate operations to these event + * handlers. + * + * <p> + * If the {@code handleEvent} method throws an unchecked runtime exception, + * the Jakarta XML Binding Provider must treat that as if the method returned false, effectively + * terminating whatever operation was in progress at the time (unmarshal, + * validate, or marshal). + * + * <p> + * Modifying the Java content tree within your event handler is undefined + * by the specification and may result in unexpected behaviour. + * + * <p> + * Failing to return false from the {@code handleEvent} method after + * encountering a fatal error is undefined by the specification and may result + * in unexpected behavior. + * + * <p> + * <b>Default Event Handler</b> + * <blockquote> + * If the client application does not set an event handler on their + * {@code Unmarshaller}, or {@code Marshaller} prior to + * calling the validate, unmarshal, or marshal methods, then a default event + * handler will receive notification of any errors or warnings encountered. + * The default event handler will cause the current operation to halt after + * encountering the first error or fatal error (but will attempt to continue + * after receiving warnings). + * </blockquote> + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li> + * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li> + * <li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see Unmarshaller + * @see Marshaller + * @see ValidationEvent + * @see jakarta.xml.bind.util.ValidationEventCollector + * @since 1.6, JAXB 1.0 + */ +public interface ValidationEventHandler { + /** + * Receive notification of a validation warning or error. + * <p> + * The ValidationEvent will have a + * {@link ValidationEventLocator ValidationEventLocator} embedded in it that + * indicates where the error or warning occurred. + * + * <p> + * If an unchecked runtime exception is thrown from this method, the Jakarta XML Binding + * provider will treat it as if the method returned false and interrupt + * the current unmarshal, validate, or marshal operation. + * + * @param event the encapsulated validation event information. It is a + * provider error if this parameter is null. + * @return true if the Jakarta XML Binding Provider should attempt to continue the current + * unmarshal, validate, or marshal operation after handling this + * warning/error, false if the provider should terminate the current + * operation with the appropriate {@code UnmarshalException}, + * {@code ValidationException}, or {@code MarshalException}. + * @throws IllegalArgumentException if the event object is null. + */ + boolean handleEvent(ValidationEvent event); + +} +
diff --git a/api/src/main/java/jakarta/xml/bind/ValidationEventLocator.java b/api/src/main/java/jakarta/xml/bind/ValidationEventLocator.java new file mode 100644 index 0000000..b327780 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ValidationEventLocator.java
@@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * Encapsulate the location of a ValidationEvent. + * + * <p> + * The {@code ValidationEventLocator} indicates where the {@code ValidationEvent} + * occurred. Different fields will be set depending on the type of + * validation that was being performed when the error or warning was detected. + * For example, on-demand validation would produce locators that contained + * references to objects in the Java content tree while unmarshal-time + * validation would produce locators containing information appropriate to the + * source of the XML data (file, url, Node, etc.). + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li> + * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li> + * <li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see ValidationEvent + * @since 1.6, JAXB 1.0 + */ +public interface ValidationEventLocator { + + /** + * Return the name of the XML source as a URL if available + * + * @return the name of the XML source as a URL or null if unavailable + */ + java.net.URL getURL(); + + /** + * Return the byte offset if available + * + * @return the byte offset into the input source or -1 if unavailable + */ + int getOffset(); + + /** + * Return the line number if available + * + * @return the line number or -1 if unavailable + */ + int getLineNumber(); + + /** + * Return the column number if available + * + * @return the column number or -1 if unavailable + */ + int getColumnNumber(); + + /** + * Return a reference to the object in the Java content tree if available + * + * @return a reference to the object in the Java content tree or null if + * unavailable + */ + java.lang.Object getObject(); + + /** + * Return a reference to the DOM Node if available + * + * @return a reference to the DOM Node or null if unavailable + */ + org.w3c.dom.Node getNode(); + +}
diff --git a/api/src/main/java/jakarta/xml/bind/ValidationException.java b/api/src/main/java/jakarta/xml/bind/ValidationException.java new file mode 100644 index 0000000..043f714 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/ValidationException.java
@@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * This exception indicates that an error has occurred while performing + * a validate operation. + * + * <p> + * The {@code ValidationEventHandler} can cause this exception to be thrown + * during the validate operations. See + * {@link ValidationEventHandler#handleEvent(ValidationEvent) + * ValidationEventHandler.handleEvent(ValidationEvent)}. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see JAXBException + * @since 1.6, JAXB 1.0 + */ +public class ValidationException extends JAXBException { + + private static final long serialVersionUID = 2206436657505193108L; + + /** + * Construct an ValidationException with the specified detail message. The + * errorCode and linkedException will default to null. + * + * @param message a description of the exception + */ + public ValidationException(String message) { + this( message, null, null ); + } + + /** + * Construct an ValidationException with the specified detail message and vendor + * specific errorCode. The linkedException will default to null. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + */ + public ValidationException(String message, String errorCode) { + this( message, errorCode, null ); + } + + /** + * Construct an ValidationException with a linkedException. The detail message and + * vendor specific errorCode will default to null. + * + * @param exception the linked exception + */ + public ValidationException(Throwable exception) { + this( null, null, exception ); + } + + /** + * Construct an ValidationException with the specified detail message and + * linkedException. The errorCode will default to null. + * + * @param message a description of the exception + * @param exception the linked exception + */ + public ValidationException(String message, Throwable exception) { + this( message, null, exception ); + } + + /** + * Construct an ValidationException with the specified detail message, vendor + * specific errorCode, and linkedException. + * + * @param message a description of the exception + * @param errorCode a string specifying the vendor specific error code + * @param exception the linked exception + */ + public ValidationException(String message, String errorCode, Throwable exception) { + super( message, errorCode, exception ); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/WhiteSpaceProcessor.java b/api/src/main/java/jakarta/xml/bind/WhiteSpaceProcessor.java new file mode 100644 index 0000000..6119fd8 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/WhiteSpaceProcessor.java
@@ -0,0 +1,183 @@ +/* + * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind; + +/** + * Processes white space normalization. + * + * @since 1.0 + */ +abstract class WhiteSpaceProcessor { + +// benchmarking (see test/src/ReplaceTest.java in the CVS Attic) +// showed that this code is slower than the current code. +// +// public static String replace(String text) { +// final int len = text.length(); +// StringBuffer result = new StringBuffer(len); +// +// for (int i = 0; i < len; i++) { +// char ch = text.charAt(i); +// if (isWhiteSpace(ch)) +// result.append(' '); +// else +// result.append(ch); +// } +// +// return result.toString(); +// } + + public static String replace(String text) { + return replace( (CharSequence)text ).toString(); + } + + /** + * @since 2.0 + */ + public static CharSequence replace(CharSequence text) { + int i=text.length()-1; + + // look for the first whitespace char. + while( i>=0 && !isWhiteSpaceExceptSpace(text.charAt(i)) ) + i--; + + if( i<0 ) + // no such whitespace. replace(text)==text. + return text; + + // we now know that we need to modify the text. + // allocate a char array to do it. + StringBuilder buf = new StringBuilder(text); + + buf.setCharAt(i--,' '); + for( ; i>=0; i-- ) + if( isWhiteSpaceExceptSpace(buf.charAt(i))) + buf.setCharAt(i,' '); + + return new String(buf); + } + + /** + * Equivalent of {@link String#trim()}. + * @since 2.0 + */ + public static CharSequence trim(CharSequence text) { + int len = text.length(); + int start = 0; + + while( start<len && isWhiteSpace(text.charAt(start)) ) + start++; + + int end = len-1; + + while( end>start && isWhiteSpace(text.charAt(end)) ) + end--; + + if(start==0 && end==len-1) + return text; // no change + else + return text.subSequence(start,end+1); + } + + public static String collapse(String text) { + return collapse( (CharSequence)text ).toString(); + } + + /** + * This is usually the biggest processing bottleneck. + * + * @since 2.0 + */ + public static CharSequence collapse(CharSequence text) { + int len = text.length(); + + // most of the texts are already in the collapsed form. + // so look for the first whitespace in the hope that we will + // never see it. + int s=0; + while(s<len) { + if(isWhiteSpace(text.charAt(s))) + break; + s++; + } + if(s==len) + // the input happens to be already collapsed. + return text; + + // we now know that the input contains spaces. + // let's sit down and do the collapsing normally. + + StringBuilder result = new StringBuilder(len /*allocate enough size to avoid re-allocation*/ ); + + if(s!=0) { + for( int i=0; i<s; i++ ) + result.append(text.charAt(i)); + result.append(' '); + } + + boolean inStripMode = true; + for (int i = s+1; i < len; i++) { + char ch = text.charAt(i); + boolean b = isWhiteSpace(ch); + if (inStripMode && b) + continue; // skip this character + + inStripMode = b; + if (inStripMode) + result.append(' '); + else + result.append(ch); + } + + // remove trailing whitespaces + len = result.length(); + if (len > 0 && result.charAt(len - 1) == ' ') + result.setLength(len - 1); + // whitespaces are already collapsed, + // so all we have to do is to remove the last one character + // if it's a whitespace. + + return result; + } + + /** + * Returns true if the specified string is all whitespace. + */ + public static final boolean isWhiteSpace(CharSequence s) { + for( int i=s.length()-1; i>=0; i-- ) + if(!isWhiteSpace(s.charAt(i))) + return false; + return true; + } + + /** returns true if the specified char is a white space character. */ + public static final boolean isWhiteSpace(char ch) { + // most of the characters are non-control characters. + // so check that first to quickly return false for most of the cases. + if( ch>0x20 ) return false; + + // other than we have to do four comparisons. + return ch == 0x9 || ch == 0xA || ch == 0xD || ch == 0x20; + } + + /** + * Returns true if the specified char is a white space character + * but not 0x20. + */ + protected static final boolean isWhiteSpaceExceptSpace(char ch) { + // most of the characters are non-control characters. + // so check that first to quickly return false for most of the cases. + if( ch>=0x20 ) return false; + + // other than we have to do four comparisons. + return ch == 0x9 || ch == 0xA || ch == 0xD; + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/DomHandler.java b/api/src/main/java/jakarta/xml/bind/annotation/DomHandler.java new file mode 100644 index 0000000..fddf876 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/DomHandler.java
@@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.ValidationEventHandler; +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +/** + * Converts an element (and its descendants) + * from/to DOM (or similar) representation. + * + * <p> + * Implementations of this interface will be used in conjunction with + * {@link XmlAnyElement} annotation to map an element of XML into a representation + * of infoset such as W3C DOM. + * + * <p> + * Implementations hide how a portion of XML is converted into/from such + * DOM-like representation, allowing Jakarta XML Binding providers to work with arbitrary + * such library. + * + * <P> + * This interface is intended to be implemented by library writers + * and consumed by Jakarta XML Binding providers. None of those methods are intended to + * be called from applications. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +public interface DomHandler<ElementT,ResultT extends Result> { + /** + * When a Jakarta XML Binding provider needs to unmarshal a part of a document into an + * infoset representation, it first calls this method to create a + * {@link Result} object. + * + * <p> + * A Jakarta XML Binding provider will then send a portion of the XML + * into the given result. Such a portion always form a subtree + * of the whole XML document rooted at an element. + * + * @param errorHandler + * if any error happens between the invocation of this method + * and the invocation of {@link #getElement(Result)}, they + * must be reported to this handler. + * <p> + * The caller must provide a non-null error handler. + * <p> + * The {@link Result} object created from this method + * may hold a reference to this error handler. + * + * @return + * null if the operation fails. The error must have been reported + * to the error handler. + */ + ResultT createUnmarshaller( ValidationEventHandler errorHandler ); + + /** + * Once the portion is sent to the {@link Result}. This method is called + * by a Jakarta XML Binding provider to obtain the unmarshalled element representation. + * + * <p> + * Multiple invocations of this method may return different objects. + * This method can be invoked only when the whole subtree are fed + * to the {@link Result} object. + * + * @param rt + * The {@link Result} object created by {@link #createUnmarshaller(ValidationEventHandler)}. + * + * @return + * null if the operation fails. The error must have been reported + * to the error handler. + */ + ElementT getElement(ResultT rt); + + /** + * This method is called when a Jakarta XML Binding provider needs to marshal an element + * to XML. + * + * <p> + * If non-null, the returned {@link Source} must contain a whole document + * rooted at one element, which will then be woven into a bigger document + * that the Jakarta XML Binding provider is marshalling. + * + * @param errorHandler + * Receives any errors happened during the process of converting + * an element into a {@link Source}. + * <p> + * The caller must provide a non-null error handler. + * + * @return + * null if there was an error. The error should have been reported + * to the handler. + */ + Source marshal( ElementT n, ValidationEventHandler errorHandler ); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/W3CDomHandler.java b/api/src/main/java/jakarta/xml/bind/annotation/W3CDomHandler.java new file mode 100644 index 0000000..26eff6f --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/W3CDomHandler.java
@@ -0,0 +1,97 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import jakarta.xml.bind.ValidationEventHandler; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; + +/** + * {@link DomHandler} implementation for W3C DOM (<code>org.w3c.dom</code> package.) + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +public class W3CDomHandler implements DomHandler<Element,DOMResult> { + + private DocumentBuilder builder; + + /** + * Default constructor. + * <p> + * It is up to a Jakarta XML Binding provider to decide which DOM implementation + * to use or how that is configured. + */ + public W3CDomHandler() { + this.builder = null; + } + + /** + * Constructor that allows applications to specify which DOM implementation + * to be used. + * + * @param builder + * must not be null. Jakarta XML Binding uses this {@link DocumentBuilder} to create + * a new element. + */ + public W3CDomHandler(DocumentBuilder builder) { + if(builder==null) + throw new IllegalArgumentException(); + this.builder = builder; + } + + public DocumentBuilder getBuilder() { + return builder; + } + + public void setBuilder(DocumentBuilder builder) { + this.builder = builder; + } + + @Override + public DOMResult createUnmarshaller(ValidationEventHandler errorHandler) { + if(builder==null) + return new DOMResult(); + else + return new DOMResult(builder.newDocument()); + } + + @Override + public Element getElement(DOMResult r) { + // JAXP spec is ambiguous about what really happens in this case, + // so work defensively + Node n = r.getNode(); + if( n instanceof Document ) { + return ((Document)n).getDocumentElement(); + } + if( n instanceof Element ) + return (Element)n; + if( n instanceof DocumentFragment ) + return (Element)n.getChildNodes().item(0); + + // if the result object contains something strange, + // it is not a user problem, but it is a Jakarta XML Binding provider's problem. + // That's why we throw a runtime exception. + throw new IllegalStateException(n.toString()); + } + + @Override + public Source marshal(Element element, ValidationEventHandler errorHandler) { + return new DOMSource(element); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessOrder.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessOrder.java new file mode 100644 index 0000000..f40eadb --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessOrder.java
@@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +/** + * Used by XmlAccessorOrder to control the ordering of properties and + * fields in a Jakarta XML Binding bound class. + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + * @see XmlAccessorOrder + */ + +public enum XmlAccessOrder { + /** + * The ordering of fields and properties in a class is undefined. + */ + UNDEFINED, + /** + * The ordering of fields and properties in a class is in + * alphabetical order as determined by the + * method java.lang.String.compareTo(String anotherString). + */ + ALPHABETICAL +} +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessType.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessType.java new file mode 100644 index 0000000..e80a4bd --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessType.java
@@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + + + +/** + * Used by XmlAccessorType to control serialization of fields or + * properties. + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + * @see XmlAccessorType + */ + +public enum XmlAccessType { + /** + * Every getter/setter pair in a Jakarta XML Binding-bound class will be automatically + * bound to XML, unless annotated by {@link XmlTransient}. + * <p> + * Fields are bound to XML only when they are explicitly annotated + * by some of the Jakarta XML Binding annotations. + */ + PROPERTY, + /** + * Every non-static, non-transient field in a Jakarta XML Binding-bound class will be automatically + * bound to XML, unless annotated by {@link XmlTransient}. + * <p> + * Getter/setter pairs are bound to XML only when they are explicitly annotated + * by some of the Jakarta XML Binding annotations. + */ + FIELD, + /** + * Every public getter/setter pair and every public field will be + * automatically bound to XML, unless annotated by {@link XmlTransient}. + * <p> + * Fields or getter/setter pairs that are private, protected, or + * defaulted to package-only access are bound to XML only when they are + * explicitly annotated by the appropriate Jakarta XML Binding annotations. + */ + PUBLIC_MEMBER, + /** + * None of the fields or properties is bound to XML unless they + * are specifically annotated with some of the Jakarta XML Binding annotations. + */ + NONE +} +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorOrder.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorOrder.java new file mode 100644 index 0000000..5027f45 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorOrder.java
@@ -0,0 +1,65 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.Inherited; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> Controls the ordering of fields and properties in a class. </p> + * + * <h2>Usage </h2> + * + * <p> {@code @XmlAccessorOrder} annotation can be used with the following + * program elements:</p> + * + * <ul> + * <li> package</li> + * <li> a top level class </li> + * </ul> + * + * <p> See "Package Specification" in {@code jakarta.xml.bind} package javadoc for + * additional common information.</p> + * + * <p>The effective {@link XmlAccessOrder} on a class is determined + * as follows: + * + * <ul> + * <li> If there is a {@code @XmlAccessorOrder} on a class, then + * it is used. </li> + * <li> Otherwise, if a {@code @XmlAccessorOrder} exists on one of + * its super classes, then it is inherited (by the virtue of + * {@link Inherited}) + * <li> Otherwise, the {@code @XmlAccessorOrder} on the package + * of the class is used, if it's there. + * <li> Otherwise {@link XmlAccessOrder#UNDEFINED}. + * </ul> + * + * <p>This annotation can be used with the following annotations: + * {@link XmlType}, {@link XmlRootElement}, {@link XmlAccessorType}, + * {@link XmlSchema}, {@link XmlSchemaType}, {@link XmlSchemaTypes}, + * {@link XmlJavaTypeAdapter}. It can also be used with the + * following annotations at the package level: {@link XmlJavaTypeAdapter}. + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + * @see XmlAccessOrder + */ + +@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE}) +public @interface XmlAccessorOrder { + XmlAccessOrder value() default XmlAccessOrder.UNDEFINED; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorType.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorType.java new file mode 100644 index 0000000..bc62aa8 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAccessorType.java
@@ -0,0 +1,84 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import java.lang.annotation.Inherited; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> Controls whether fields or Javabean properties are serialized by default. </p> + * + * <p> <b> Usage </b> </p> + * + * <p> {@code @XmlAccessorType} annotation can be used with the following program elements:</p> + * + * <ul> + * <li> package</li> + * <li> a top level class </li> + * </ul> + * + * <p> See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p>This annotation provides control over the default serialization + * of properties and fields in a class. + * + * <p>The annotation {@code @XmlAccessorType} on a package applies to + * all classes in the package. The following inheritance + * semantics apply: + * + * <ul> + * <li> If there is a {@code @XmlAccessorType} on a class, then it + * is used. </li> + * <li> Otherwise, if a {@code @XmlAccessorType} exists on one of + * its super classes, then it is inherited. + * <li> Otherwise, the {@code @XmlAccessorType} on a package is + * inherited. + * </ul> + * <p> <b> Defaulting Rules: </b> </p> + * + * <p>By default, if {@code @XmlAccessorType} on a package is absent, + * then the following package level annotation is assumed.</p> + * {@snippet : + * @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) + * } + * <p> By default, if {@code @XmlAccessorType} on a class is absent, + * and none of its super classes is annotated with + * {@code @XmlAccessorType}, then the following default on the class + * is assumed: </p> + * {@snippet : + * @XmlAccessorType(XmlAccessType.PUBLIC_MEMBER) + * } + * <p>This annotation can be used with the following annotations: + * {@link XmlType}, {@link XmlRootElement}, {@link XmlAccessorOrder}, + * {@link XmlSchema}, {@link XmlSchemaType}, {@link XmlSchemaTypes}, + * , {@link XmlJavaTypeAdapter}. It can also be used with the + * following annotations at the package level: {@link XmlJavaTypeAdapter}. + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + * @see XmlAccessType + */ +@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE}) +public @interface XmlAccessorType { + + /** + * Specifies whether fields or properties are serialized. + * + * @see XmlAccessType + */ + XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyAttribute.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyAttribute.java new file mode 100644 index 0000000..23fa7bc --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyAttribute.java
@@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import javax.xml.namespace.QName; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.Map; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; + +/** + * <p> + * Maps a JavaBean property to a map of wildcard attributes. + * + * <p> <b>Usage</b> </p> + * <p> + * The {@code @XmlAnyAttribute} annotation can be used with the + * following program elements: + * <ul> + * <li> JavaBean property </li> + * <li> non-static, non transient field </li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * The usage is subject to the following constraints: + * <ul> + * <li> At most one field or property in a class can be annotated + * with {@code @XmlAnyAttribute}. </li> + * <li> The type of the property or the field must {@code java.util.Map} </li> + * </ul> + * + * <p> + * While processing attributes to be unmarshalled into a value class, + * each attribute that is not statically associated with another + * JavaBean property, via {@link XmlAttribute}, is entered into the + * wildcard attribute map represented by + * {@link Map}<{@link QName},{@link Object}>. The attribute QName is the + * map's key. The key's value is the String value of the attribute. + * + * @author Kohsuke Kawaguchi, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD}) +public @interface XmlAnyAttribute { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyElement.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyElement.java new file mode 100644 index 0000000..056e66c --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAnyElement.java
@@ -0,0 +1,277 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Maps a JavaBean property to XML infoset representation and/or JAXBElement. + * + * <p> + * This annotation serves as a "catch-all" property while unmarshalling + * xml content into an instance of a Jakarta XML Binding annotated class. It typically + * annotates a multivalued JavaBean property, but it can occur on + * single value JavaBean property. During unmarshalling, each xml element + * that does not match a static @XmlElement or @XmlElementRef + * annotation for the other JavaBean properties on the class, is added to this + * "catch-all" property. + * + * <h2>Usages:</h2> + * {@snippet : + * @XmlAnyElement + * public Element[] others; + * + * // Collection of Element or JAXBElements. + * @XmlAnyElement(lax="true") + * public Object[] others; + * + * @XmlAnyElement + * private List<Element> nodes; + * + * @XmlAnyElement + * private Element node; + * } + * + * <h2>Restriction usage constraints</h2> + * <p> + * This annotation is mutually exclusive with + * {@link XmlElement}, {@link XmlAttribute}, {@link XmlValue}, + * {@link XmlElements}, {@link XmlID}, and {@link XmlIDREF}. + * + * <p> + * There can be only one {@link XmlAnyElement} annotated JavaBean property + * in a class and its super classes. + * + * <h2>Relationship to other annotations</h2> + * <p> + * This annotation can be used with {@link XmlJavaTypeAdapter}, so that users + * can map their own data structure to DOM, which in turn can be composed + * into XML. + * + * <p> + * This annotation can be used with {@link XmlMixed} like this: + * {@snippet : + * // List of java.lang.String or DOM nodes. + * @XmlAnyElement + * @XmlMixed + * List<Object> others; + * } + * + * + * <h2>Schema To Java example</h2> + * + * The following schema would produce the following Java class: + * {@snippet lang="XML" : + * <xs:complexType name="foo"> + * <xs:sequence> + * <xs:element name="a" type="xs:int" /> + * <xs:element name="b" type="xs:int" /> + * <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" /> + * </xs:sequence> + * </xs:complexType> + * } + * + * {@snippet : + * class Foo { + * int a; + * int b; + * @XmlAnyElement + * List<Element> any; + * } + * } + * + * It can unmarshal instances like + * + * {@snippet lang="XML" : + * <foo xmlns:e="extra"> + * <a>1</a> + * <e:other /> <!-- this will be bound to DOM, because unmarshalling is orderless --> + * <b>3</b> + * <e:other /> + * <c>5</c> <!-- this will be bound to DOM, because the annotation doesn't remember namespaces --> + * </foo> + * } + * + * + * + * The following schema would produce the following Java class: + * {@snippet lang="XML" : + * <xs:complexType name="bar"> + * <xs:complexContent> + * <xs:extension base="foo"> + * <xs:sequence> + * <xs:element name="c" type="xs:int" /> + * <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" /> + * </xs:sequence> + * </xs:extension> + * </xs:complexContent> + * </xs:complexType> + * } + * + * {@snippet : + * class Bar extends Foo { + * int c; + * // Foo.getAny() also represents wildcard content for type definition bar. + * } + * } + * + * + * It can unmarshal instances like + * + * {@snippet lang="XML" : + * <bar xmlns:e="extra"> + * <a>1</a> + * <e:other /> <!-- this will be bound to DOM, because unmarshalling is orderless --> + * <b>3</b> + * <e:other /> + * <c>5</c> <!-- this now goes to Bar.c --> + * <e:other /> <!-- this will go to Foo.any --> + * </bar> + * } + * + * + * + * + * <h2>Using {@link XmlAnyElement} with {@link XmlElementRef}</h2> + * <p> + * The {@link XmlAnyElement} annotation can be used with {@link XmlElementRef}s to + * designate additional elements that can participate in the content tree. + * + * <p> + * The following schema would produce the following Java class: + * {@snippet lang="XML" : + * <xs:complexType name="foo"> + * <xs:choice maxOccurs="unbounded" minOccurs="0"> + * <xs:element name="a" type="xs:int" /> + * <xs:element name="b" type="xs:int" /> + * <xs:any namespace="##other" processContents="lax" /> + * </xs:choice> + * </xs:complexType> + * } + * + * {@snippet : + * class Foo { + * @XmlAnyElement(lax="true") + * @XmlElementRefs({ + * @XmlElementRef(name="a", type="JAXBElement.class"), + * @XmlElementRef(name="b", type="JAXBElement.class") + * }) + * List<Object> others; + * } + * + * @XmlRegistry + * class ObjectFactory { + * ... + * @XmlElementDecl(name = "a", namespace = "", scope = Foo.class) + * JAXBElement<Integer> createFooA( Integer i ) { ... } + * + * @XmlElementDecl(name = "b", namespace = "", scope = Foo.class) + * JAXBElement<Integer> createFooB( Integer i ) { ... } + * } + * } + * + * It can unmarshal instances like + * + * {@snippet lang="XML" : + * <foo xmlns:e="extra"> + * <a>1</a> <!-- this will unmarshal to a JAXBElement instance whose value is 1. --> + * <e:other /> <!-- this will unmarshal to a DOM Element. --> + * <b>3</b> <!-- this will unmarshal to a JAXBElement instance whose value is 1. --> + * </foo> + * } + * + * + * + * + * <h2>W3C XML Schema "lax" wildcard emulation</h2> + * The lax element of the annotation enables the emulation of the "lax" wildcard semantics. + * For example, when the Java source code is annotated like this: + * {@snippet : + * @XmlRootElement + * class Foo { + * @XmlAnyElement(lax=true) + * public Object[] others; + * } + * } + * then the following document will unmarshal like this: + * {@snippet lang="XML" : + * <foo> + * <unknown /> + * <foo /> + * </foo> + * } + * {@snippet : + * Foo foo = unmarshal(); + * // 1 for 'unknown', another for 'foo' + * assert foo.others.length==2; + * // 'unknown' unmarshalls to a DOM element + * assert foo.others[0] instanceof Element; + * // because of lax=true, the 'foo' element eagerly + * // unmarshalls to a Foo object. + * assert foo.others[1] instanceof Foo; + * } + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD}) +public @interface XmlAnyElement { + + /** + * Controls the unmarshaller behavior when it sees elements + * known to the current {@link JAXBContext}. + * + * <dl> + * <dt>When false</dt> + * <dd> + * If false, all the elements that match the property will be unmarshalled + * to DOM, and the property will only contain DOM elements. + * </dd> + * + * <dt>When true</dt> + * <dd> + * If true, when an element matches a property marked with {@link XmlAnyElement} + * is known to {@link JAXBContext} (for example, there's a class with + * {@link XmlRootElement} that has the same tag name, or there's + * {@link XmlElementDecl} that has the same tag name), + * the unmarshaller will eagerly unmarshal this element to the Jakarta XML Binding object, + * instead of unmarshalling it to DOM. Additionally, if the element is + * unknown but it has a known xsi:type, the unmarshaller eagerly unmarshalls + * the element to a {@link JAXBElement}, with the unknown element name and + * the JAXBElement value is set to an instance of the Jakarta XML Binding mapping of the + * known xsi:type. + * </dd> + * </dl> + * + * <p> + * As a result, after the unmarshalling, the property can become heterogeneous; + * it can have both DOM nodes and some Jakarta XML Binding objects at the same time. + * + * <p> + * This can be used to emulate the "lax" wildcard semantics of the W3C XML Schema. + */ + boolean lax() default false; + + /** + * Specifies the {@link DomHandler} which is responsible for actually + * converting XML from/to a DOM-like data structure. + */ + Class<? extends DomHandler<?, ?>> value() default W3CDomHandler.class; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAttachmentRef.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAttachmentRef.java new file mode 100644 index 0000000..5215809 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAttachmentRef.java
@@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import jakarta.activation.DataHandler; + +/** + * Marks a field/property that its XML form is a URI reference to mime content. + * The mime content is optimally stored out-of-line as an attachment. + * <p> + * A field/property must always map to the {@link DataHandler} class. + * + * <h2>Usage</h2> + * {@snippet : + * @XmlRootElement + * class Foo { + * @XmlAttachmentRef + * @XmlAttribute + * DataHandler data; + * + * @XmlAttachmentRef + * @XmlElement + * DataHandler body; + * } + * } + * The above code maps to the following XML: + * {@snippet lang="XML" : + * <xs:element name="foo" xmlns:ref="http://ws-i.org/profiles/basic/1.1/xsd"> + * <xs:complexType> + * <xs:sequence> + * <xs:element name="body" type="ref:swaRef" minOccurs="0" /> + * </xs:sequence> + * <xs:attribute name="data" type="ref:swaRef" use="optional" /> + * </xs:complexType> + * </xs:element> + * } + * + * <p> + * The above binding supports WS-I AP 1.0 <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html#Referencing_Attachments_from_the_SOAP_Envelope">WS-I Attachments Profile Version 1.0.</a> + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD,PARAMETER}) +public @interface XmlAttachmentRef { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlAttribute.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlAttribute.java new file mode 100644 index 0000000..000547a --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlAttribute.java
@@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> + * Maps a JavaBean property to an XML attribute. + * + * <p> <b>Usage</b> </p> + * <p> + * The {@code @XmlAttribute} annotation can be used with the + * following program elements: + * <ul> + * <li> JavaBean property </li> + * <li> field </li> + * </ul> + * + * <p> A static final field is mapped to an XML fixed attribute. + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * The usage is subject to the following constraints: + * <ul> + * <li> If type of the field or the property is a collection + * type, then the collection item type must be mapped to schema + * simple type. + * {@snippet : + * // Examples + * @XmlAttribute List<Integer> items; //legal + * @XmlAttribute List<Bar> foo; // illegal if Bar does not map to a schema simple type + * } + * </li> + * <li> If the type of the field or the property is a non + * collection type, then the type of the property or field + * must map to a simple schema type. + * {@snippet : + * // Examples + * @XmlAttribute int foo; // legal + * @XmlAttribute Foo foo; // illegal if Foo does not map to a schema simple type + * } + * </li> + * <li> This annotation can be used with the following annotations: + * {@link XmlID}, + * {@link XmlIDREF}, + * {@link XmlList}, + * {@link XmlSchemaType}, + * {@link XmlValue}, + * {@link XmlAttachmentRef}, + * {@link XmlMimeType}, + * {@link XmlInlineBinaryData}, + * {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter}.</li> + * </ul> + * + * <p> <b>Example 1: </b>Map a JavaBean property to an XML attribute.</p> + * {@snippet : + * //Example: Code fragment + * public class USPrice { + * @XmlAttribute + * public java.math.BigDecimal getPrice() {...} ; + * public void setPrice(java.math.BigDecimal ) {...}; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * </xs:sequence> + * <xs:attribute name="price" type="xs:decimal"/> + * </xs:complexType> + * } + * + * <p> <b>Example 2: </b>Map a JavaBean property to an XML attribute with anonymous type.</p> + * See Example 7 in @{@link XmlType}. + * + * <p> <b>Example 3: </b>Map a JavaBean collection property to an XML attribute.</p> + * {@snippet : + * // Example: Code fragment + * class Foo { + * ... + * @XmlAttribute + * List<Integer> items; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="foo"> + * ... + * <xs:attribute name="items"> + * <xs:simpleType> + * <xs:list itemType="xs:int"/> + * </xs:simpleType> + </xs:attribute> + * </xs:complexType> + * } + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @see XmlType + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlAttribute { + /** + * Name of the XML Schema attribute. By default, the XML Schema + * attribute name is derived from the JavaBean property name. + * + */ + String name() default "##default"; + + /** + * Specifies if the XML Schema attribute is optional or + * required. If true, then the JavaBean property is mapped to + * an XML Schema attribute that is required. Otherwise, it is mapped + * to an XML Schema attribute that is optional. + * + */ + boolean required() default false; + + /** + * Specifies the XML target namespace of the XML Schema + * attribute. + * + */ + String namespace() default "##default" ; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElement.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElement.java new file mode 100644 index 0000000..ea2bc9a --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElement.java
@@ -0,0 +1,194 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Maps a JavaBean property to an XML element derived from property name. + * + * <p> <b>Usage</b> + * <p> + * {@code @XmlElement} annotation can be used with the following program + * elements: + * <ul> + * <li> a JavaBean property </li> + * <li> non-static, non transient field </li> + * <li> within {@link XmlElements} + * </ul> + * + * The usage is subject to the following constraints: + * <ul> + * <li> This annotation can be used with following annotations: + * {@link XmlID}, + * {@link XmlIDREF}, + * {@link XmlList}, + * {@link XmlSchemaType}, + * {@link XmlValue}, + * {@link XmlAttachmentRef}, + * {@link XmlMimeType}, + * {@link XmlInlineBinaryData}, + * {@link XmlElementWrapper}, + * {@link XmlJavaTypeAdapter}</li> + * <li> if the type of JavaBean property is a collection type of + * array, an indexed property, or a parameterized list, and + * this annotation is used with {@link XmlElements} then, + * {@code @XmlElement.type()} must be DEFAULT.class since the + * collection item type is already known. </li> + * </ul> + * + * <p> + * A JavaBean property, when annotated with @XmlElement annotation + * is mapped to a local element in the XML Schema complex type to + * which the containing class is mapped. + * + * <p> + * <b>Example 1: </b> Map a public non-static non-final field to local + * element + * {@snippet : + * //Example: Code fragment + * public class USPrice { + * @XmlElement(name="itemprice") + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: Local XML Schema element --> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * <xs:element name="itemprice" type="xs:decimal" minOccurs="0"/> + * </sequence> + * </xs:complexType> + * } + * <p> + * + * <b> Example 2: </b> Map a field to a nillable element. + * {@snippet : + * //Example: Code fragment + * public class USPrice { + * @XmlElement(nillable=true) + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: Local XML Schema element --> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * <xs:element name="price" type="xs:decimal" nillable="true" minOccurs="0"/> + * </xs:sequence> + * </xs:complexType> + * } + * <p> + * <b> Example 3: </b> Map a field to a nillable, required element. + * {@snippet : + * //Example: Code fragment + * public class USPrice { + * @XmlElement(nillable=true, required=true) + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: Local XML Schema element --> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * <xs:element name="price" type="xs:decimal" nillable="true" minOccurs="1"/> + * </xs:sequence> + * </xs:complexType> + * } + * + * <p> <b>Example 4: </b>Map a JavaBean property to an XML element + * with anonymous type.</p> + * <p> + * See Example 6 in @{@link XmlType}. + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD, PARAMETER}) +public @interface XmlElement { + /** + * Name of the XML Schema element. + * <p> If the value is "##default", then element name is derived from the + * JavaBean property name. + */ + String name() default "##default"; + + /** + * Customize the element declaration to be nillable. + * <p>If nillable() is true, then the JavaBean property is + * mapped to an XML Schema nillable element declaration. + */ + boolean nillable() default false; + + /** + * Customize the element declaration to be required. + * <p>If required() is true, then Javabean property is mapped to + * an XML schema element declaration with minOccurs="1". + * maxOccurs is "1" for a single valued property and "unbounded" + * for a multivalued property. + * <p>If required() is false, then the Javabean property is mapped + * to XML Schema element declaration with minOccurs="0". + * maxOccurs is "1" for a single valued property and "unbounded" + * for a multivalued property. + */ + + boolean required() default false; + + /** + * XML target namespace of the XML Schema element. + * <p> + * If the value is "##default", then the namespace is determined + * as follows: + * <ol> + * <li> + * If the enclosing package has {@link XmlSchema} annotation, + * and its {@link XmlSchema#elementFormDefault() elementFormDefault} + * is {@link XmlNsForm#QUALIFIED QUALIFIED}, then the namespace of + * the enclosing class. + * + * <li> + * Otherwise {@literal ''} (which produces unqualified element in the default + * namespace. + * </ol> + */ + String namespace() default "##default"; + + /** + * Default value of this element. + * + * <p> + * The <pre>'\u0000'</pre> value specified as a default of this annotation element + * is used as a poor-man's substitute for null to allow implementations + * to recognize the 'no default value' state. + */ + String defaultValue() default "\u0000"; + + /** + * The Java class being referenced. + */ + Class<?> type() default DEFAULT.class; + + /** + * Used in {@link XmlElement#type()} to + * signal that the type be inferred from the signature + * of the property. + */ + final class DEFAULT { + private DEFAULT() {} + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElementDecl.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementDecl.java new file mode 100644 index 0000000..e5b215e --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementDecl.java
@@ -0,0 +1,204 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.METHOD; + +/** + * Maps a factory method to an XML element. + * + * <p> <b>Usage</b> </p> + * + * The annotation creates a mapping between an XML schema element + * declaration and a <i> element factory method </i> that returns a + * JAXBElement instance representing the element + * declaration. Typically, the element factory method is generated + * (and annotated) from a schema into the ObjectFactory class in a + * Java package that represents the binding of the element + * declaration's target namespace. Thus, while the annotation syntax + * allows @XmlElementDecl to be used on any method, semantically + * its use is restricted to annotation of element factory method. + * <p> + * The usage is subject to the following constraints: + * + * <ul> + * <li> The class containing the element factory method annotated + * with @XmlElementDecl must be marked with {@link + * XmlRegistry}. </li> + * <li> The element factory method must take one parameter + * assignable to {@link Object}.</li> + * </ul> + * + * <p><b>Example 1: </b>Annotation on a factory method + * {@snippet : + * // Example: code fragment + * @XmlRegistry + * class ObjectFactory { + * @XmlElementDecl(name="foo") + * JAXBElement<String> createFoo(String s) { ... } + * } + * } + * {@snippet lang="XML" : + * <!-- XML input --> + * <foo>string</foo> + *} + * {@snippet : + * // Example: code fragment corresponding to XML input + * JAXBElement<String> o = + * (JAXBElement<String>)unmarshaller.unmarshal(aboveDocument); + * // print JAXBElement instance to show values + * System.out.println(o.getName()); // prints "{}foo" + * System.out.println(o.getValue()); // prints "string" + * System.out.println(o.getValue().getClass()); // prints "java.lang.String" + * } + * {@snippet lang="XML" : + * <!-- Example: XML schema definition --> + * <xs:element name="foo" type="xs:string"/> + * } + * + * <p><b>Example 2: </b> Element declaration with non-local scope + * <p> + * The following example illustrates the use of scope annotation + * parameter in binding of element declaration in schema derived + * code. + * <p> + * The following example may be replaced in a future revision of + * this javadoc. + * + * {@snippet lang="XML" : + * <!-- Example: XML schema definition --> + * <xs:schema> + * <xs:complexType name="pea"> + * <xs:choice maxOccurs="unbounded"> + * <xs:element name="foo" type="xs:string"/> + * <xs:element name="bar" type="xs:string"/> + * </xs:choice> + * </xs:complexType> + * <xs:element name="foo" type="xs:int"/> + * </xs:schema> + * } + * {@snippet : + * // Example: expected default binding + * class Pea { + * @XmlElementRefs({ + * @XmlElementRef(name="foo",type=JAXBElement.class) + * @XmlElementRef(name="bar",type=JAXBElement.class) + * }) + * List<JAXBElement<String>> fooOrBar; + * } + * + * @XmlRegistry + * class ObjectFactory { + * @XmlElementDecl(scope=Pea.class,name="foo") + * JAXBElement<String> createPeaFoo(String s); + * + * @XmlElementDecl(scope=Pea.class,name="bar") + * JAXBElement<String> createPeaBar(String s); + * + * @XmlElementDecl(name="foo") + * JAXBElement<Integer> createFoo(Integer i); + * } + * } + * Without scope createFoo and createPeaFoo would become ambiguous + * since both of them map to an XML schema element with the same local + * name "foo". + * + * @see XmlRegistry + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({METHOD}) +public @interface XmlElementDecl { + /** + * scope of the mapping. + * + * <p> + * If this is not {@link XmlElementDecl.GLOBAL}, then this element + * declaration mapping is only active within the specified class. + */ + Class<?> scope() default GLOBAL.class; + + /** + * namespace name of the XML element. + * <p> + * If the value is "##default", then the value is the namespace + * name for the package of the class containing this factory method. + * + * @see #name() + */ + String namespace() default "##default"; + + /** + * local name of the XML element. + * + * <p> + * <b> Note to reviewers: </b> There is no default name; since + * the annotation is on a factory method, it is not clear that the + * method name can be derived from the factory method name. + * @see #namespace() + */ + String name(); + + /** + * namespace name of a substitution group's head XML element. + * <p> + * This specifies the namespace name of the XML element whose local + * name is specified by {@code substitutionHeadName()}. + * <p> + * If {@code substitutionHeadName()} is "", then this + * value can only be "##default". But the value is ignored + * since this element is not part of substitution group when the + * value of {@code substitutionHeadName()} is "". + * <p> + * If {@code substitutionHeadName()} is not "" and the value is + * "##default", then the namespace name is the namespace name to + * which the package of the containing class, marked with {@link + * XmlRegistry }, is mapped. + * <p> + * If {@code substitutionHeadName()} is not "" and the value is + * not "##default", then the value is the namespace name. + * + * @see #substitutionHeadName() + */ + String substitutionHeadNamespace() default "##default"; + + /** + * XML local name of a substitution group's head element. + * <p> + * If the value is "", then this element is not part of any + * substitution group. + * + * @see #substitutionHeadNamespace() + */ + String substitutionHeadName() default ""; + + /** + * Default value of this element. + * + * <p> + * The <pre>'\u0000'</pre> value specified as a default of this annotation element + * is used as a poor-man's substitute for null to allow implementations + * to recognize the 'no default value' state. + */ + String defaultValue() default "\u0000"; + + /** + * Used in {@link XmlElementDecl#scope()} to + * signal that the declaration is in the global scope. + */ + final class GLOBAL { + private GLOBAL() {} + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRef.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRef.java new file mode 100644 index 0000000..34247d0 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRef.java
@@ -0,0 +1,278 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; + +/** + * <p> + * Maps a JavaBean property to an XML element derived from property's type. + * <p> + * <b>Usage</b> + * <p> + * {@code @XmlElementRef} annotation can be used with a + * JavaBean property or from within {@link XmlElementRefs} + * <p> + * This annotation dynamically associates an XML element name with the JavaBean + * property. When a JavaBean property is annotated with {@link + * XmlElement}, the XML element name is statically derived from the + * JavaBean property name. However, when this annotation is used, the + * XML element name is derived from the instance of the type of the + * JavaBean property at runtime. + * + * <h2> XML Schema substitution group support </h2> + * XML Schema allows an XML document author to use XML element names + * that were not statically specified in the content model of a + * schema using substitution groups. Schema derived code provides + * support for substitution groups using an <i>element property</i>, + * (section 5.5.5, "Element Property" of Jakarta XML Binding specification). An + * element property method signature is of the form: + * {@snippet : + * public void setTerm(JAXBElement<? extends Operator>); + * public JAXBElement<? extends Operator> getTerm(); + * } + * <p> + * An element factory method annotated with {@link XmlElementDecl} is + * used to create a {@code JAXBElement} instance, containing an XML + * element name. The presence of {@code @XmlElementRef} annotation on an + * element property indicates that the element name from {@code JAXBElement} + * instance be used instead of deriving an XML element name from the + * JavaBean property name. + * + * <p> + * The usage is subject to the following constraints: + * <ul> + * <li> If the collection item type (for collection property) or + * property type (for single valued property) is + * {@link jakarta.xml.bind.JAXBElement}, then + * {@code @XmlElementRef.name()} and {@code @XmlElementRef.namespace()} must + * point an element factory method with an @XmlElementDecl + * annotation in a class annotated with @XmlRegistry (usually + * ObjectFactory class generated by the schema compiler) : + * <ul> + * <li> @XmlElementDecl.name() must equal @XmlElementRef.name() </li> + * <li> @XmlElementDecl.namespace() must equal @XmlElementRef.namespace(). </li> + * </ul> + * </li> + * <li> If the collection item type (for collection property) or + * property type (for single valued property) is not + * {@link jakarta.xml.bind.JAXBElement}, then the type referenced by the + * property or field must be annotated with {@link XmlRootElement}. </li> + * <li> This annotation can be used with the following annotations: + * {@link XmlElementWrapper}, {@link XmlJavaTypeAdapter}. + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p><b>Example 1: Ant Task Example</b></p> + * The following Java class hierarchy models an Ant build + * script. An Ant task corresponds to a class in the class + * hierarchy. The XML element name of an Ant task is indicated by the + * XmlRootElement annotation on its corresponding class. + * {@snippet : + * @XmlRootElement(name="target") + * class Target { + * // The presence of @XmlElementRef indicates that the XML + * // element name will be derived from the @XmlRootElement + * // annotation on the type (for e.g. "jar" for JarTask). + * @XmlElementRef + * List<Task> tasks; + * } + * + * abstract class Task { + * } + * + * @XmlRootElement(name="jar") + * class JarTask extends Task { + * ... + * } + * + * @XmlRootElement(name="javac") + * class JavacTask extends Task { + * ... + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <xs:element name="target" type="Target"> + * <xs:complexType name="Target"> + * <xs:sequence> + * <xs:choice maxOccurs="unbounded"> + * <xs:element ref="jar"/> + * <xs:element ref="javac"/> + * </xs:choice> + * </xs:sequence> + * </xs:complexType> + * </xs:element> + * } + * <p> + * Thus the following code fragment: + * {@snippet : + * Target target = new Target(); + * target.tasks.add(new JarTask()); + * target.tasks.add(new JavacTask()); + * marshal(target); + * } + * will produce the following XML output: + * {@snippet lang="XML" : + * <target> + * <jar> + * .... + * </jar> + * <javac> + * .... + * </javac> + * </target> + * } + * <p> + * It is not an error to have a class that extends {@code Task} + * that doesn't have {@link XmlRootElement}. But they can't show up in an + * XML instance (because they don't have XML element names). + * + * <p><b>Example 2: XML Schema Substitution group support</b> + * <p> The following example shows the annotations for XML Schema + * substitution groups. The annotations and the ObjectFactory are + * derived from the schema. + * + * {@snippet : + * @XmlElement + * class Math { + * // The value of type() is // @link substring="type()" target="#type()" + * // JAXBElement.class , which indicates the XML + * // element name ObjectFactory - in general a class marked + * // with @XmlRegistry. (See ObjectFactory below) + * // + * // The name() is "operator", a pointer to a // @link substring="name()" target="#name()" + * // factory method annotated with a + * // XmlElementDecl with the name "operator". Since //@link substring="XmlElementDecl" target="XmlElementDecl" + * // "operator" is the head of a substitution group that + * // contains elements "add" and "sub" elements, "operator" + * // element can be substituted in an instance document by + * // elements "add" or "sub". At runtime, JAXBElement + * // instance contains the element name that has been + * // substituted in the XML document. + * // + * @XmlElementRef(type=JAXBElement.class,name="operator") + * JAXBElement<? extends Operator> term; + * } + * + * @XmlRegistry + * class ObjectFactory { + * @XmlElementDecl(name="operator") + * JAXBElement<Operator> createOperator(Operator o) {...} + * @XmlElementDecl(name="add",substitutionHeadName="operator") + * JAXBElement<Operator> createAdd(Operator o) {...} + * @XmlElementDecl(name="sub",substitutionHeadName="operator") + * JAXBElement<Operator> createSub(Operator o) {...} + * } + * + * class Operator { + * ... + * } + * } + * <p> + * Thus, the following code fragment + * {@snippet : + * Math m = new Math(); + * m.term = new ObjectFactory().createAdd(new Operator()); + * marshal(m); + * } + * will produce the following XML output: + * {@snippet lang="XML" : + * <math> + * <add>...</add> + * </math> + * } + * + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems,Inc. </li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @see XmlElementRefs + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD}) +public @interface XmlElementRef { + /** + * The Java type being referenced. + * <p> + * If the value is DEFAULT.class, the type is inferred from + * the type of the JavaBean property. + */ + Class<?> type() default DEFAULT.class; + + /** + * This parameter and {@link #name()} are used to determine the + * XML element for the JavaBean property. + * + * <p> If {@code type()} is {@code JAXBElement.class} , then + * {@code namespace()} and {@code name()} + * point to a factory method with {@link XmlElementDecl}. The XML + * element name is the element name from the factory method's + * {@link XmlElementDecl} annotation or if an element from its + * substitution group (of which it is a head element) has been + * substituted in the XML document, then the element name is from the + * {@link XmlElementDecl} on the substituted element. + * + * <p> If {@link #type()} is not {@code JAXBElement.class}, then + * the XML element name is the XML element name statically + * associated with the type using the annotation {@link + * XmlRootElement} on the type. If the type is not annotated with + * an {@link XmlElementDecl}, then it is an error. + * + * <p> If {@code type()} is not {@code JAXBElement.class}, then + * this value must be "". + * + */ + String namespace() default ""; + /** + * + * @see #namespace() + */ + String name() default "##default"; + + /** + * Used in {@link XmlElementRef#type()} to + * signal that the type be inferred from the signature + * of the property. + */ + final class DEFAULT { + private DEFAULT() {} + } + + /** + * Customize the element declaration to be required. + * <p> + * If required() is true, then Javabean property is mapped to + * an XML schema element declaration with minOccurs="1". + * maxOccurs is "1" for a single valued property and "unbounded" + * for a multivalued property. + * + * <p> + * If required() is false, then the Javabean property is mapped + * to XML Schema element declaration with minOccurs="0". + * maxOccurs is "1" for a single valued property and "unbounded" + * for a multivalued property. + * + * <p> + * For compatibility with Jakarta XML Binding, this property defaults to {@code true}, + * despite the fact that {@link XmlElement#required()} defaults to false. + * + * @since 1.7, JAXB 2.2 + */ + boolean required() default true; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRefs.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRefs.java new file mode 100644 index 0000000..a4a4b76 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementRefs.java
@@ -0,0 +1,44 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Marks a property that refers to classes with {@link XmlElement} + * or JAXBElement. + * + * <p> + * Compared to an element property (property with {@link XmlElement} + * annotation), a reference property has a different substitution semantics. + * When a subclass is assigned to a property, an element property produces + * the same tag name with @xsi:type, whereas a reference property produces + * a different tag name (the tag name that's on the subclass.) + * + * <p> This annotation can be used with the following annotations: + * {@link XmlJavaTypeAdapter}, {@link XmlElementWrapper}. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * + * @see XmlElementWrapper + * @see XmlElementRef + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD}) +public @interface XmlElementRefs { + XmlElementRef[] value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElementWrapper.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementWrapper.java new file mode 100644 index 0000000..043754e --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElementWrapper.java
@@ -0,0 +1,130 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Generates a wrapper element around XML representation. + * + * This is primarily intended to be used to produce a wrapper + * XML element around collections. The annotation therefore supports + * two forms of serialization shown below. + * + * {@snippet : + * //Example: code fragment + * int[] names; + * } + * {@snippet lang="XML" : + * <!-- XML Serialization Form 1 (Unwrapped collection) --> + * <names> ... </names> + * <names> ... </names> + * + * <!-- XML Serialization Form 2 ( Wrapped collection ) --> + * <wrapperElement> + * <names> value-of-item </names> + * <names> value-of-item </names> + * .... + * </wrapperElement> + * } + * + * <p> The two serialized XML forms allow a null collection to be + * represented either by absence or presence of an element with a + * nillable attribute. + * + * <p> <b>Usage</b> </p> + * <p> + * The {@code @XmlElementWrapper} annotation can be used with the + * following program elements: + * <ul> + * <li> JavaBean property </li> + * <li> non-static, non transient field </li> + * </ul> + * + * <p>The usage is subject to the following constraints: + * <ul> + * <li> The property must be a collection property </li> + * <li> This annotation can be used with the following annotations: + * {@link XmlElement}, + * {@link XmlElements}, + * {@link XmlElementRef}, + * {@link XmlElementRefs}, + * {@link XmlJavaTypeAdapter}.</li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @see XmlElement + * @see XmlElements + * @see XmlElementRef + * @see XmlElementRefs + * @since 1.6, JAXB 2.0 + * + */ +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlElementWrapper { + /** + * Name of the XML wrapper element. By default, the XML wrapper + * element name is derived from the JavaBean property name. + */ + String name() default "##default"; + + /** + * XML target namespace of the XML wrapper element. + * <p> + * If the value is "##default", then the namespace is determined + * as follows: + * <ol> + * <li> + * If the enclosing package has {@link XmlSchema} annotation, + * and its {@link XmlSchema#elementFormDefault() elementFormDefault} + * is {@link XmlNsForm#QUALIFIED QUALIFIED}, then the namespace of + * the enclosing class. + * + * <li> + * Otherwise "" (which produces unqualified element in the default + * namespace. + * </ol> + */ + String namespace() default "##default"; + + /** + * If true, the absence of the collection is represented by + * using {@code xsi:nil='true'}. Otherwise, it is represented by + * the absence of the element. + */ + boolean nillable() default false; + + /** + * Customize the wrapper element declaration to be required. + * + * <p> + * If required() is true, then the corresponding generated + * XML schema element declaration will have {@code minOccurs="1"}, + * to indicate that the wrapper element is always expected. + * + * <p> + * Note that this only affects the schema generation, and + * not the unmarshalling or marshalling capability. This is + * simply a mechanism to let users express their application constraints + * better. + * + * @since 1.6, JAXB 2.1 + */ + boolean required() default false; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlElements.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlElements.java new file mode 100644 index 0000000..3ad1280 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlElements.java
@@ -0,0 +1,162 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * <p> + * A container for multiple @{@link XmlElement} annotations. + * <p> + * Multiple annotations of the same type are not allowed on a program + * element. This annotation therefore serves as a container annotation + * for multiple {@code @XmlElements} as follows: + * + * {@snippet : + * @XmlElements({ @XmlElement(...), @XmlElement(...) }) + * } + * + * <p>The {@code @XmlElements} annotation can be used with the + * following program elements: </p> + * <ul> + * <li> a JavaBean property </li> + * <li> non-static, non transient field </li> + * </ul> + * + * This annotation is intended for annotation a JavaBean collection + * property (e.g. List). + * + * <p><b>Usage</b></p> + * + * <p>The usage is subject to the following constraints: + * <ul> + * <li> This annotation can be used with the following + * annotations: @{@link XmlIDREF}, @{@link XmlElementWrapper}. </li> + * <li> If @XmlIDREF is also specified on the JavaBean property, + * then each @XmlElement.type() must contain a JavaBean + * property annotated with {@code @XmlID}.</li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <hr> + * + * <p><b>Example 1:</b> Map to a list of elements</p> + * {@snippet : + * // Mapped code fragment + * public class Foo { + * @XmlElements({ + * @XmlElement(name="A", type=Integer.class), + * @XmlElement(name="B", type=Float.class) + * }) + * public List items; + * } + * } + * {@snippet lang="XML" : + * <!-- XML Representation for a List of {1,2.5} + * XML output is not wrapped using another element --> + * ... + * <A> 1 </A> + * <B> 2.5 </B> + * ... + * + * <!-- XML Schema fragment --> + * <xs:complexType name="Foo"> + * <xs:sequence> + * <xs:choice minOccurs="0" maxOccurs="unbounded"> + * <xs:element name="A" type="xs:int"/> + * <xs:element name="B" type="xs:float"/> + * </xs:choice> + * </xs:sequence> + * </xs:complexType> + * } + * + * <p><b>Example 2:</b> Map to a list of elements wrapped with another element + * </p> + * {@snippet : + * // Mapped code fragment + * public class Foo { + * @XmlElementWrapper(name="bar") + * @XmlElements({ + * @XmlElement(name="A", type=Integer.class), + * @XmlElement(name="B", type=Float.class) + * }) + * public List items; + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <xs:complexType name="Foo"> + * <xs:sequence> + * <xs:element name="bar"> + * <xs:complexType> + * <xs:choice minOccurs="0" maxOccurs="unbounded"> + * <xs:element name="A" type="xs:int"/> + * <xs:element name="B" type="xs:float"/> + * </xs:choice> + * </xs:complexType> + * </xs:element> + * </xs:sequence> + * </xs:complexType> + * } + * + * <p><b>Example 3:</b> Change element name based on type using an adapter. + * </p> + * {@snippet : + * class Foo { + * @XmlJavaTypeAdapter(QtoPAdapter.class) + * @XmlElements({ + * @XmlElement(name="A",type=PX.class), + * @XmlElement(name="B",type=PY.class) + * }) + * Q bar; + * } + * + * @XmlType abstract class P {...} + * @XmlType(name="PX") class PX extends P {...} + * @XmlType(name="PY") class PY extends P {...} + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <xs:complexType name="Foo"> + * <xs:sequence> + * <xs:element name="bar"> + * <xs:complexType> + * <xs:choice minOccurs="0" maxOccurs="unbounded"> + * <xs:element name="A" type="PX"/> + * <xs:element name="B" type="PY"/> + * </xs:choice> + * </xs:complexType> + * </xs:element> + * </xs:sequence> + * </xs:complexType> + * } + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @see XmlElement + * @see XmlElementRef + * @see XmlElementRefs + * @see XmlJavaTypeAdapter + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD,METHOD}) +public @interface XmlElements { + /** + * Collection of @{@link XmlElement} annotations + */ + XmlElement[] value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlEnum.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlEnum.java new file mode 100644 index 0000000..f235295 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlEnum.java
@@ -0,0 +1,59 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * <p> + * Maps an enum type {@link Enum} to XML representation. + * + * <p>This annotation, together with {@link XmlEnumValue} provides a + * mapping of enum type to XML representation. + * + * <p> <b>Usage</b> </p> + * <p> + * The {@code @XmlEnum} annotation can be used with the + * following program elements: + * <ul> + * <li>enum type</li> + * </ul> + * + * <p> The usage is subject to the following constraints: + * <ul> + * <li> This annotation can be used the following other annotations: + * {@link XmlType}, + * {@link XmlRootElement} </li> + * </ul> + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information </p> + * + * <p>An enum type is mapped to a schema simple type with enumeration + * facets. The schema type is derived from the Java type to which + * {@code @XmlEnum.value()}. Each enum constant {@code @XmlEnumValue} + * must have a valid lexical representation for the type + * {@code @XmlEnum.value()}. + * + * <p><b>Examples:</b> See examples in {@link XmlEnumValue} + * + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({TYPE}) +public @interface XmlEnum { + /** + * Java type that is mapped to an XML simple type. + * + */ + Class<?> value() default String.class; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlEnumValue.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlEnumValue.java new file mode 100644 index 0000000..e0a3ff1 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlEnumValue.java
@@ -0,0 +1,113 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; + +/** + * Maps an enum constant in {@link Enum} type to XML representation. + * + * <p> <b>Usage</b> </p> + * + * <p> The {@code @XmlEnumValue} annotation can be used with the + * following program elements: + * <ul> + * <li>enum constant</li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p>This annotation, together with {@link XmlEnum} provides a + * mapping of enum type to XML representation. + * + * <p>An enum type is mapped to a schema simple type with enumeration + * facets. The schema type is derived from the Java type specified in + * {@code @XmlEnum.value()}. Each enum constant {@code @XmlEnumValue} + * must have a valid lexical representation for the type + * {@code @XmlEnum.value()} + * + * <p> In the absence of this annotation, {@link Enum#name()} is used + * as the XML representation. + * + * <p> <b>Example 1: </b>Map enum constant name {@literal ->} enumeration facet</p> + * {@snippet : + * //Example: Code fragment + * @XmlEnum(String.class) + * public enum Card { CLUBS, DIAMONDS, HEARTS, SPADES } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:simpleType name="Card"> + * <xs:restriction base="xs:string"> + * <xs:enumeration value="CLUBS"/> + * <xs:enumeration value="DIAMONDS"/> + * <xs:enumeration value="HEARTS"/> + * <xs:enumeration value="SPADES"/> + </xs:restriction> + * </xs:simpleType> + * } + * + * <p><b>Example 2: </b>Map enum constant name(value) {@literal ->} enumeration facet </p> + * {@snippet : + * //Example: code fragment + * @XmlType + * @XmlEnum(Integer.class) + * public enum Coin { + * @XmlEnumValue("1") PENNY(1), + * @XmlEnumValue("5") NICKEL(5), + * @XmlEnumValue("10") DIME(10), + * @XmlEnumValue("25") QUARTER(25) + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:simpleType name="Coin"> + * <xs:restriction base="xs:int"> + * <xs:enumeration value="1"/> + * <xs:enumeration value="5"/> + * <xs:enumeration value="10"/> + * <xs:enumeration value="25"/> + * </xs:restriction> + * </xs:simpleType> + * } + * + * <p><b>Example 3: </b>Map enum constant name {@literal ->} enumeration facet </p> + * + * {@snippet : + * //Code fragment + * @XmlType + * @XmlEnum(Integer.class) + * public enum Code { + * @XmlEnumValue("1") ONE, + * @XmlEnumValue("2") TWO + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:simpleType name="Code"> + * <xs:restriction base="xs:int"> + * <xs:enumeration value="1"/> + * <xs:enumeration value="2"/> + * </xs:restriction> + * </xs:simpleType> + * } + * + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD}) +public @interface XmlEnumValue { + String value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlID.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlID.java new file mode 100644 index 0000000..6436488 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlID.java
@@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> + * Maps a JavaBean property to XML ID. + * + * <p> + * To preserve referential integrity of an object graph across XML + * serialization followed by an XML deserialization, requires an object + * reference to be marshalled by reference or containment + * appropriately. Annotations {@code @XmlID} and {@code @XmlIDREF} + * together allow a customized mapping of a JavaBean property's + * type by containment or reference. + * + * <p><b>Usage</b> </p> + * The {@code @XmlID} annotation can be used with the following + * program elements: + * <ul> + * <li> a JavaBean property </li> + * <li> non-static, non transient field </li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * The usage is subject to the following constraints: + * <ul> + * <li> At most one field or property in a class can be annotated + * with {@code @XmlID}. </li> + * <li> The JavaBean property's type must be {@code java.lang.String}.</li> + * <li> The only other mapping annotations that can be used + * with {@code @XmlID} + * are: {@code @XmlElement} and {@code @XmlAttribute}.</li> + * </ul> + * + * <p><b>Example</b>: Map a JavaBean property's type to {@code xs:ID}</p> + * {@snippet : + * // Example: code fragment + * public class Customer { + * @XmlAttribute + * @XmlID + * public String getCustomerID(); + * public void setCustomerID(String id); + * .... other properties not shown + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="Customer"> + * <xs:complexContent> + * <xs:sequence> + * .... + * </xs:sequence> + * <xs:attribute name="customerID" type="xs:ID"/> + * </xs:complexContent> + * </xs:complexType> + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @see XmlIDREF + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlID { } + + +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlIDREF.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlIDREF.java new file mode 100644 index 0000000..7fbbb0b --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlIDREF.java
@@ -0,0 +1,233 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> + * Maps a JavaBean property to XML IDREF. + * + * <p> + * To preserve referential integrity of an object graph across XML + * serialization followed by an XML deserialization, requires an object + * reference to be marshaled by reference or containment + * appropriately. Annotations {@code @XmlID} and {@code @XmlIDREF} + * together allow a customized mapping of a JavaBean property's + * type by containment or reference. + * + * <p><b>Usage</b> </p> + * The {@code @XmlIDREF} annotation can be used with the following + * program elements: + * <ul> + * <li> a JavaBean property </li> + * <li> non-static, non transient field </li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p> The usage is subject to the following constraints: + * <ul> + * + * <li> If the type of the field or property is a collection type, + * then the collection item type must contain a property or + * field annotated with {@code @XmlID}. </li> + * <li> If the field or property is single valued, then the type of + * the property or field must contain a property or field + * annotated with {@code @XmlID}. + * <p>Note: If the collection item type or the type of the + * property (for non collection type) is java.lang.Object, then + * the instance must contain a property/field annotated with + * {@code @XmlID} attribute. + * </li> + * <li> This annotation can be used with the following annotations: + * {@link XmlElement}, {@link XmlAttribute}, {@link XmlList}, + * and {@link XmlElements}.</li> + * + * </ul> + * <p><b>Example:</b> Map a JavaBean property to {@code xs:IDREF} + * (i.e. by reference rather than by containment)</p> + * {@snippet : + * //EXAMPLE: Code fragment + * public class Shipping { + * @XmlIDREF public Customer getCustomer(); + * public void setCustomer(Customer customer); + * .... + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="Shipping"> + * <xs:complexContent> + * <xs:sequence> + * <xs:element name="customer" type="xs:IDREF"/> + * .... + * </xs:sequence> + * </xs:complexContent> + * </xs:complexType> + * } + * + * + * <p><b>Example 2: </b> The following is a complete example of + * containment versus reference. + * + * {@snippet : + * // By default, Customer maps to complex type {@code xs:Customer} + * public class Customer { + * + * // map JavaBean property type to {@code xs:ID} + * @XmlID public String getCustomerID(); + * public void setCustomerID(String id); + * + * // .... other properties not shown + * } + * + * // By default, Invoice maps to a complex type {@code xs:Invoice} + * public class Invoice { + * + * // map by reference + * @XmlIDREF public Customer getCustomer(); + * public void setCustomer(Customer customer); + * + * // .... other properties not shown here + * } + * + * // By default, Shipping maps to complex type {@code xs:Shipping} + * public class Shipping { + * + * // map by reference + * @XmlIDREF public Customer getCustomer(); + * public void setCustomer(Customer customer); + * } + * + * // at least one class must reference Customer by containment; + * // Customer instances won't be marshalled. + * @XmlElement(name="CustomerData") + * public class CustomerData { + * // map reference to Customer by containment by default. + * public Customer getCustomer(); + * + * // maps reference to Shipping by containment by default. + * public Shipping getShipping(); + * + * // maps reference to Invoice by containment by default. + * public Invoice getInvoice(); + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema mapping for above code fragment --> + * + * <xs:complexType name="Invoice"> + * <xs:complexContent> + * <xs:sequence> + * <xs:element name="customer" type="xs:IDREF"/> + * .... + * </xs:sequence> + * </xs:complexContent> + * </xs:complexType> + * + * <xs:complexType name="Shipping"> + * <xs:complexContent> + * <xs:sequence> + * <xs:element name="customer" type="xs:IDREF"/> + * .... + * </xs:sequence> + * </xs:complexContent> + * </xs:complexType> + * + * <xs:complexType name="Customer"> + * <xs:complexContent> + * <xs:sequence> + * .... + * </xs:sequence> + * <xs:attribute name="CustomerID" type="xs:ID"/> + * </xs:complexContent> + * </xs:complexType> + * + * <xs:complexType name="CustomerData"> + * <xs:complexContent> + * <xs:sequence> + * <xs:element name="customer" type="xs:Customer"/> + * <xs:element name="shipping" type="xs:Shipping"/> + * <xs:element name="invoice" type="xs:Invoice"/> + * </xs:sequence> + * </xs:complexContent> + * </xs:complexType> + * + * <xs:element name="customerData" type="xs:CustomerData"/> + * + * <!-- Instance document conforming to the above XML Schema --> + * <customerData> + * <customer customerID="Alice"> + * .... + * </customer> + * + * <shipping customer="Alice"> + * .... + * </shipping> + * + * <invoice customer="Alice"> + * .... + * </invoice> + * </customerData> + * } + * + * <p><b>Example 3: </b> Mapping List to repeating element of type IDREF + * {@snippet : + * // Code fragment + * public class Shipping { + * @XmlIDREF + * @XmlElement(name="Alice") + * public List customers; + * } + * } + * {@snippet lang="XML" : + * <!-- XML schema fragment --> + * <xs:complexType name="Shipping"> + * <xs:sequence> + * <xs:choice minOccurs="0" maxOccurs="unbounded"> + * <xs:element name="Alice" type="xs:IDREF"/> + * </xs:choice> + * </xs:sequence> + * </xs:complexType> + * } + * + * <p><b>Example 4: </b> Mapping a List to a list of elements of type IDREF. + * {@snippet : + * //Code fragment + * public class Shipping { + * @XmlIDREF + * @XmlElement(name="Alice", type="Customer.class") + * @XmlElement(name="John", type="InternationalCustomer.class") + * public List customers; + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <xs:complexType name="Shipping"> + * <xs:sequence> + * <xs:choice minOccurs="0" maxOccurs="unbounded"> + * <xs:element name="Alice" type="xs:IDREF"/> + * <xs:element name="John" type="xs:IDREF"/> + * </xs:choice> + * </xs:sequence> + * </xs:complexType> + * } + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @see XmlID + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlIDREF {}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlInlineBinaryData.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlInlineBinaryData.java new file mode 100644 index 0000000..363d46c --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlInlineBinaryData.java
@@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +import javax.xml.transform.Source; +import jakarta.xml.bind.attachment.AttachmentMarshaller; +import jakarta.activation.DataHandler; + +/** + * Disable consideration of XOP encoding for datatypes that are bound to + * base64-encoded binary data in XML. + * + * <p> + * When XOP encoding is enabled as described in {@link AttachmentMarshaller#isXOPPackage()}, + * this annotation disables datatypes such as {@code java.awt.Image} or {@link Source} + * or {@code byte[]} that are bound to base64-encoded binary from being considered for + * XOP encoding. If a Jakarta XML Binding property is annotated with this annotation or if + * the Jakarta XML Binding property's base type is annotated with this annotation, + * neither + * {@link AttachmentMarshaller#addMtomAttachment(DataHandler, String, String)} + * nor + * {@link AttachmentMarshaller#addMtomAttachment(byte[], int, int, String, String, String)} is + * ever called for the property. The binary data will always be inlined. + * + * @author Joseph Fialli + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD,TYPE}) +public @interface XmlInlineBinaryData { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlList.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlList.java new file mode 100644 index 0000000..6d3fde1 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlList.java
@@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; + +/** + * Used to map a property to a list simple type. + * + * <p><b>Usage</b> </p> + * <p> + * The {@code @XmlList} annotation can be used with the + * following program elements: + * <ul> + * <li> JavaBean property </li> + * <li> field </li> + * </ul> + * + * <p> + * When a collection property is annotated just with @XmlElement, + * each item in the collection will be wrapped by an element. + * For example, + * + * {@snippet : + * @XmlRootElement + * class Foo { + * @XmlElement + * List<String> data; + * } + * } + * + * would produce XML like this: + * + * {@snippet lang="XML" : + * <foo> + * <data>abc</data> + * <data>def</data> + * </foo> + * } + * + * XmlList annotation, on the other hand, allows multiple values to be + * represented as whitespace-separated tokens in a single element. For example, + * + * {@snippet : + * @XmlRootElement + * class Foo { + * @XmlElement + * @XmlList + * List<String> data; + * } + * } + * + * the above code will produce XML like this: + * + * {@snippet lang="XML" : + * <foo> + * <data>abc def</data> + * </foo> + * } + * + * <p>This annotation can be used with the following annotations: + * {@link XmlElement}, + * {@link XmlAttribute}, + * {@link XmlValue}, + * {@link XmlIDREF}. + * <ul> + * <li> The use of {@code @XmlList} with {@link XmlValue} while + * allowed, is redundant since {@link XmlList} maps a + * collection type to a simple schema type that derives by + * list just as {@link XmlValue} would. </li> + * + * <li> The use of {@code @XmlList} with {@link XmlAttribute} while + * allowed, is redundant since {@link XmlList} maps a + * collection type to a simple schema type that derives by + * list just as {@link XmlAttribute} would. </li> + * </ul> + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD,METHOD,PARAMETER}) +public @interface XmlList { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlMimeType.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlMimeType.java new file mode 100644 index 0000000..7f52629 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlMimeType.java
@@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; + +import javax.xml.transform.Source; + +/** + * Associates the MIME type that controls the XML representation of the property. + * + * <p> + * This annotation is used in conjunction with datatypes such as + * {@code java.awt.Image} or {@link Source} that are bound to base64-encoded binary in XML. + * + * <p> + * If a property that has this annotation has a sibling property bound to + * the xmime:contentType attribute, and if in the instance the property has a value, + * the value of the attribute takes precedence and that will control the marshalling. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD,PARAMETER}) +public @interface XmlMimeType { + /** + * The textual representation of the MIME type, + * such as "image/jpeg" "image/*", "text/xml; charset=iso-8859-1" and so on. + */ + String value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlMixed.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlMixed.java new file mode 100644 index 0000000..5a7f7ea --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlMixed.java
@@ -0,0 +1,118 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; + +import org.w3c.dom.Element; +import jakarta.xml.bind.JAXBElement; + +/** + * <p> + * Annotate a JavaBean multi-valued property to support mixed content. + * + * <p> + * The usage is subject to the following constraints: + * <ul> + * <li> can be used with @XmlElementRef, @XmlElementRefs or @XmlAnyElement</li> + * </ul> + * <p> + * The following can be inserted into @XmlMixed annotated multi-valued property + * <ul> + * <li>XML text information items are added as values of java.lang.String.</li> + * <li>Children element information items are added as instances of + * {@link JAXBElement} or instances with a class that is annotated with + * @XmlRootElement.</li> + * <li>Unknown content that is not be bound to a Jakarta XML Binding mapped class is inserted + * as {@link Element}. (Assumes property annotated with @XmlAnyElement)</li> + * </ul> + * + * Below is an example of binding and creation of mixed content. + * {@snippet lang="XML" : + * <!-- schema fragment having mixed content --> + * <xs:complexType name="letterBody" mixed="true"> + * <xs:sequence> + * <xs:element name="name" type="xs:string"/> + * <xs:element name="quantity" type="xs:positiveInteger"/> + * <xs:element name="productName" type="xs:string"/> + * <!-- etc. --> + * </xs:sequence> + * </xs:complexType> + * <xs:element name="letterBody" type="letterBody"/> + * } + * {@snippet : + * // Schema-derived Java code: + * // (Only annotations relevant to mixed content are shown below, + * // others are omitted.) + * import java.math.BigInteger; + * public class ObjectFactory { + * // element instance factories + * JAXBElement<LetterBody> createLetterBody(LetterBody value); + * JAXBElement<String> createLetterBodyName(String value); + * JAXBElement<BigInteger> createLetterBodyQuantity(BigInteger value); + * JAXBElement<String> createLetterBodyProductName(String value); + * // type instance factory + * LetterBody createLetterBody(); + * } + * } + * {@snippet : + * public class LetterBody { + * // Mixed content can contain instances of Element classes + * // Name, Quantity and ProductName. Text data is represented as + * // java.util.String for text. + * @XmlMixed + * @XmlElementRefs({ + * @XmlElementRef(name="productName", type=JAXBElement.class) + * @XmlElementRef(name="quantity", type=JAXBElement.class) + * @XmlElementRef(name="name", type=JAXBElement.class) + * }) + * List getContent() {...} + * } + * } + * The following is an XML instance document with mixed content + * {@snippet lang="XML" : + * <letterBody> + * Dear Mr.<name>Robert Smith</name> + * Your order of <quantity>1</quantity> <productName>Baby + * Monitor</productName> shipped from our warehouse. .... + * </letterBody> + * } + * that can be constructed using following Jakarta XML Binding API calls. + * {@snippet : + * LetterBody lb = ObjectFactory.createLetterBody(); + * JAXBElement<LetterBody> lbe = ObjectFactory.createLetterBody(lb); + * List gcl = lb.getContent(); //add mixed content to general content property. + * gcl.add("Dear Mr."); // add text information item as a String. + * + * // add child element information item + * gcl.add(ObjectFactory.createLetterBodyName("Robert Smith")); + * gcl.add("Your order of "); // add text information item as a String + * + * // add children element information items + * gcl.add(ObjectFactory.createLetterBodyQuantity(new BigInteger("1"))); + * gcl.add(ObjectFactory.createLetterBodyProductName("Baby Monitor")); + * gcl.add("shipped from our warehouse"); // add text information item + * } + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({FIELD,METHOD}) +public @interface XmlMixed { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlNs.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlNs.java new file mode 100644 index 0000000..1bdbbaf --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlNs.java
@@ -0,0 +1,45 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * <p> + * Associates a namespace prefix with an XML namespace URI. + * + * <p><b>Usage</b></p> + * <p>{@code @XmlNs} annotation is intended for use from other + * program annotations. + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p><b>Example:</b>See {@code XmlSchema} annotation type for an example. + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({}) +public @interface XmlNs { + /** + * Namespace prefix + */ + String prefix(); + + /** + * Namespace URI + */ + String namespaceURI(); +} + +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlNsForm.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlNsForm.java new file mode 100644 index 0000000..b232891 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlNsForm.java
@@ -0,0 +1,56 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +/** + * Enumeration of XML Schema namespace qualifications. + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p><b>Usage</b> + * <p> + * The namespace qualification values are used in the annotations + * defined in this package. The enumeration values are mapped as follows: + * + * <table class="striped"> + * <caption style="display:none">Mapping of enumeration values</caption> + * <thead> + * <tr> + * <th scope="col">Enum Value</th> + * <th scope="col">XML Schema Value</th> + * </tr> + * </thead> + * + * <tbody> + * <tr> + * <th scope="row">UNQUALIFIED</th> + * <td>unqualified</td> + * </tr> + * <tr> + * <th scope="row">QUALIFIED</th> + * <td>qualified</td> + * </tr> + * <tr> + * <th scope="row">UNSET</th> + * <td>namespace qualification attribute is absent from the + * XML Schema fragment</td> + * </tr> + * </tbody> + * </table> + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +public enum XmlNsForm {UNQUALIFIED, QUALIFIED, UNSET} + + +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlRegistry.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlRegistry.java new file mode 100644 index 0000000..4301867 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlRegistry.java
@@ -0,0 +1,28 @@ +/* + * Copyright (c) 2004, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Marks a class that has {@link XmlElementDecl}s. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @since 1.6, JAXB 2.0 + * @see XmlElementDecl + */ +@Retention(RUNTIME) +@Target({TYPE}) +public @interface XmlRegistry { +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlRootElement.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlRootElement.java new file mode 100644 index 0000000..9da29ed --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlRootElement.java
@@ -0,0 +1,171 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.TYPE; + +/** + * Maps a class or an enum type to an XML element. + * + * <p> <b>Usage</b> </p> + * <p> + * The XmlRootElement annotation can be used with the following program + * elements: + * <ul> + * <li> a top level class </li> + * <li> an enum type </li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p> + * When a top level class or an enum type is annotated with the + * XmlRootElement annotation, then its value is represented + * as XML element in an XML document. + * + * <p> This annotation can be used with the following annotations: + * {@link XmlType}, {@link XmlEnum}, {@link XmlAccessorType}, + * {@link XmlAccessorOrder}. + * </p> + + * <p> + * <b>Example 1: </b> Associate an element with XML Schema type + * {@snippet : + * // Example: Code fragment + * @XmlRootElement + * class Point { + * int x; + * int y; + * Point(int _x,int _y) {x=_x;y=_y;} + * } + * } + * + * {@snippet : + * //Example: Code fragment corresponding to XML output + * marshal( new Point(3,5), System.out); + * } + * + * {@snippet lang="XML" : + * <!-- Example: XML output --> + * <point> + * <x> 3 </x> + * <y> 5 </y> + * </point> + * } + * + * The annotation causes a global element declaration to be produced + * in the schema. The global element declaration is associated with + * the XML schema type to which the class is mapped. + * + * {@snippet lang="XML" : + * <!-- Example: XML schema definition --> + * <xs:element name="point" type="point"> + * <xs:complexType name="point"> + * <xs:sequence> + * <xs:element name="x" type="xs:int"/> + * <xs:element name="y" type="xs:int"/> + * </xs:sequence> + * </xs:complexType> + * </xs:element> + * } + * + * <p> + * + * <b>Example 2: Orthogonality to type inheritance </b> + * + * <p> + * An element declaration annotated on a type is not inherited by its + * derived types. The following example shows this. + * {@snippet : + * // Example: Code fragment + * @XmlRootElement + * class Point3D extends Point { + * int z; + * Point3D(int _x,int _y,int _z) {super(_x,_y);z=_z;} + * } + * + * //Example: Code fragment corresponding to XML output * + * marshal( new Point3D(3,5,0), System.out ); + * } + * {@snippet lang="XML" : + * <!-- Example: XML output --> + * <!-- The element name is point3D not point --> + * <point3D> + * <x>3</x> + * <y>5</y> + * <z>0</z> + * </point3D> + * + * <!-- Example: XML schema definition --> + * <xs:element name="point3D" type="point3D"/> + * <xs:complexType name="point3D"> + * <xs:complexContent> + * <xs:extension base="point"> + * <xs:sequence> + * <xs:element name="z" type="xs:int"/> + * </xs:sequence> + * </xs:extension> + * </xs:complexContent> + * </xs:complexType> + * } + * + * <b>Example 3: </b> Associate a global element with XML Schema type + * to which the class is mapped. + * {@snippet : + * //Example: Code fragment + * @XmlRootElement(name="PriceElement") + * public class USPrice { + * @XmlElement + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML schema definition --> + * <xs:element name="PriceElement" type="USPrice"> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * <xs:element name="price" type="xs:decimal"/> + * </sequence> + * </xs:complexType> + </xs:element> + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) +@Target({TYPE}) +public @interface XmlRootElement { + /** + * namespace name of the XML element. + * <p> + * If the value is "##default", then the XML namespace name is derived + * from the package of the class ( {@link XmlSchema} ). If the + * package is unnamed, then the XML namespace is the default empty + * namespace. + */ + String namespace() default "##default"; + + /** + * local name of the XML element. + * <p> + * If the value is "##default", then the name is derived from the + * class name. + * + */ + String name() default "##default"; + +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlSchema.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchema.java new file mode 100644 index 0000000..b8b6073 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchema.java
@@ -0,0 +1,190 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> Maps a package name to an XML namespace. </p> + * + * <h2>Usage</h2> + * <p> + * The XmlSchema annotation can be used with the following program + * elements: + * <ul> + * <li>package</li> + * </ul> + * + * <p> + * This is a package level annotation and follows the recommendations + * and restrictions contained in JSR 175, section III, "Annotations". + * Thus the usage is subject to the following constraints and + * recommendations. + * <ul> + * <li> There can only be one package declaration as noted in JSR + * 175, section III, "Annotations". </li> + * <li> JSR 175 recommends package-info.java for package level + * annotations. Jakarta XML Binding Providers that follow this recommendation + * will allow the package level annotations to be defined in + * package-info.java. + * </ul> + * + * <p><b>Example 1:</b> Customize name of XML namespace to which + * package is mapped.</p> + * + * {@snippet : + * @jakarta.xml.bind.annotation.XmlSchema ( + * namespace = "http://www.example.com/MYPO1" + * ) + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <schema + * xmlns=... + * xmlns:po=.... + * targetNamespace="http://www.example.com/MYPO1"> + * <!-- prefixes generated by default are implementation dependent --> + * } + * + * <p><b>Example 2:</b> Customize namespace prefix, namespace URI + * mapping</p> + * + * {@snippet : + * // Package level annotation + * @jakarta.xml.bind.annotation.XmlSchema ( + * xmlns = { + * @jakarta.xml.bind.annotation.XmlNs(prefix = "po", + * namespaceURI="http://www.example.com/myPO1"), + * @jakarta.xml.bind.annotation.XmlNs(prefix="xs", + * namespaceURI="http://www.w3.org/2001/XMLSchema") + * } + * ) + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <schema + * xmlns:xs="http://www.w3.org/2001/XMLSchema" + * xmlns:po="http://www.example.com/PO1" + * targetNamespace="http://www.example.com/PO1"> + * ... + * } + * + * <p><b>Example 3:</b> Customize elementFormDefault</p> + * {@snippet : + * @jakarta.xml.bind.annotation.XmlSchema ( + * elementFormDefault=XmlNsForm.UNQUALIFIED + * ... + * ) + * } + * {@snippet lang="XML" : + * <!-- XML Schema fragment --> + * <schema + * xmlns="http://www.w3.org/2001/XMLSchema" + * xmlns:po="http://www.example.com/PO1" + * elementFormDefault="unqualified"> + * ... + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target(PACKAGE) +public @interface XmlSchema { + + /** + * Customize the namespace URI, prefix associations. By default, + * the namespace prefixes for an XML namespace are generated by a + * Jakarta XML Binding Provider in an implementation dependent way. + */ + XmlNs[] xmlns() default {}; + + /** + * Name of the XML namespace. + */ + String namespace() default ""; + + /** + * Namespace qualification for elements. By default, element + * default attribute will be absent from the XML Schema fragment. + */ + XmlNsForm elementFormDefault() default XmlNsForm.UNSET; + + /** + * Namespace qualification for attributes. By default, + * attributesFormDefault will be absent from the XML Schema fragment. + */ + XmlNsForm attributeFormDefault() default XmlNsForm.UNSET; + + /** + * Indicates that this namespace (specified by {@link #namespace()}) + * has a schema already available externally, available at this location. + * + * <p> + * This instructs the Jakarta XML Binding schema generators to simply refer to + * the pointed schema, as opposed to generating components into the schema. + * This schema is assumed to match what would be otherwise produced + * by the schema generator (same element names, same type names...) + * + * <p> + * This feature is intended to be used when a set of the Java classes + * is originally generated from an existing schema, handwritten to + * match externally defined schema, or the generated schema is modified + * manually. + * + * <p> + * Value could be any absolute URI, like {@code http://example.org/some.xsd}. + * It is also possible to specify the empty string, to indicate + * that the schema is externally available but the location is + * unspecified (and thus it's the responsibility of the reader of the generate + * schema to locate it.) Finally, the default value of this property + * {@code "##generate"} indicates that the schema generator is going + * to generate components for this namespace (as it did in Jakarta XML Binding.) + * + * <p> + * Multiple {@link XmlSchema} annotations on multiple packages are allowed + * to govern the same {@link #namespace()}. In such case, all of them + * must have the same {@link #location()} values. + * + * + * <p> + * <strong>Note to implementor</strong> + * <p> + * More precisely, the value must be either {@code ""}, {@code "##generate"}, or + * <a href="http://www.w3.org/TR/xmlschema-2/#anyURI"> + * a valid lexical representation of {@code xs:anyURI}</a> that begins + * with {@code <scheme>:}. + * + * <p> + * A schema generator is expected to generate a corresponding + * {@code <xs:import namespace="..." schemaLocation="..."/>} (or + * no {@code schemaLocation} attribute at all if the empty string is specified.) + * However, the schema generator is allowed to use a different value in + * the {@code schemaLocation} attribute (including not generating + * such attribute), for example so that the user can specify a local + * copy of the resource through the command line interface. + * + * @since 1.6, JAXB 2.1 + */ + String location() default NO_LOCATION; + + /** + * The default value of the {@link #location()} attribute, + * which indicates that the schema generator will generate + * components in this namespace. + */ + // the actual value is chosen because ## is not a valid + // sequence in xs:anyURI. + String NO_LOCATION = "##generate"; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaType.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaType.java new file mode 100644 index 0000000..12159a3 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaType.java
@@ -0,0 +1,97 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Maps a Java type to a simple schema built-in type. + * + * <p> <b>Usage</b> </p> + * <p> + * {@code @XmlSchemaType} annotation can be used with the following program + * elements: + * <ul> + * <li> a JavaBean property </li> + * <li> field </li> + * <li> package</li> + * </ul> + * + * <p> {@code @XmlSchemaType} annotation defined for Java type + * applies to all references to the Java type from a property/field. + * A {@code @XmlSchemaType} annotation specified on the + * property/field overrides the {@code @XmlSchemaType} annotation + * specified at the package level. + * + * <p> This annotation can be used with the following annotations: + * {@link XmlElement}, {@link XmlAttribute}. + * <p> + * <b>Example 1: </b> Customize mapping of XMLGregorianCalendar on the + * field. + * + * {@snippet : + * //Example: Code fragment + * public class USPrice { + * @XmlElement + * @XmlSchemaType(name="date") + * public XMLGregorianCalendar date; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: Local XML Schema element --> + * <xs:complexType name="USPrice"> + * <xs:sequence> + * <xs:element name="date" type="xs:date"/> + * </sequence> + * </xs:complexType> + * } + * + * <p> <b> Example 2: </b> Customize mapping of XMLGregorianCalendar at package + * level </p> + * {@snippet : + * @jakarta.xml.bind.annotation.XmlSchemaType( + * name="date", type=javax.xml.datatype.XMLGregorianCalendar.class) + * package foo; + * } + * + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD,METHOD,PACKAGE}) +public @interface XmlSchemaType { + String name(); + String namespace() default "http://www.w3.org/2001/XMLSchema"; + /** + * If this annotation is used at the package level, then value of + * the type() must be specified. + */ + + Class<?> type() default DEFAULT.class; + + /** + * Used in {@link XmlSchemaType#type()} to + * signal that the type be inferred from the signature + * of the property. + */ + + final class DEFAULT { + private DEFAULT() {} + } + +} + + +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaTypes.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaTypes.java new file mode 100644 index 0000000..eb21795 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlSchemaTypes.java
@@ -0,0 +1,46 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.PACKAGE; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * <p> + * A container for multiple {@link XmlSchemaType} annotations. + * + * <p> Multiple annotations of the same type are not allowed on a program + * element. This annotation therefore serves as a container annotation + * for multiple {@link XmlSchemaType} annotations as follows: + * + * {@snippet : + * @XmlSchemaTypes({ @XmlSchemaType(...), @XmlSchemaType(...) }) + * } + * <p>The {@code @XmlSchemaTypes} annotation can be used to + * define {@link XmlSchemaType} for different types at the + * package level. + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * @author <ul><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @see XmlSchemaType + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({PACKAGE}) +public @interface XmlSchemaTypes { + /** + * Collection of @{@link XmlSchemaType} annotations + */ + XmlSchemaType[] value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlSeeAlso.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlSeeAlso.java new file mode 100644 index 0000000..6c2ec83 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlSeeAlso.java
@@ -0,0 +1,64 @@ +/* + * Copyright (c) 2006, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import jakarta.xml.bind.JAXBContext; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * Instructs Jakarta XML Binding to also bind other classes when binding this class. + * + * <p> + * Java makes it impractical/impossible to list all subclasses of + * a given class. This often gets in a way of Jakarta XML Binding users, as it Jakarta XML Binding + * cannot automatically list up the classes that need to be known + * to {@link JAXBContext}. + * + * <p> + * For example, with the following class definitions: + * + * {@snippet : + * class Animal {} + * class Dog extends Animal {} + * class Cat extends Animal {} + * } + * + * <p> + * The user would be required to create {@link JAXBContext} as + * {@code JAXBContext.newInstance(Dog.class,Cat.class)} + * ({@code Animal} will be automatically picked up since {@code Dog} + * and {@code Cat} refers to it.) + * + * <p> + * {@link XmlSeeAlso} annotation would allow you to write: + * {@snippet : + * @XmlSeeAlso({Dog.class,Cat.class}) + * class Animal {} + * class Dog extends Animal {} + * class Cat extends Animal {} + * } + * + * <p> + * This would allow you to do {@code JAXBContext.newInstance(Animal.class)}. + * By the help of this annotation, Jakarta XML Binding implementations will be able to + * correctly bind {@code Dog} and {@code Cat}. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.1 + */ +@Target({ElementType.TYPE}) +@Retention(RUNTIME) +public @interface XmlSeeAlso { + Class<?>[] value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlTransient.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlTransient.java new file mode 100644 index 0000000..ab479ba --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlTransient.java
@@ -0,0 +1,80 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> + * Prevents the mapping of a JavaBean property/type to XML representation. + * <p> + * The {@code @XmlTransient} annotation is useful for resolving name + * collisions between a JavaBean property name and a field name or + * preventing the mapping of a field/property. A name collision can + * occur when the decapitalized JavaBean property name and a field + * name are the same. If the JavaBean property refers to the field, + * then the name collision can be resolved by preventing the + * mapping of either the field or the JavaBean property using the + * {@code @XmlTransient} annotation. + * + * <p> + * When placed on a class, it indicates that the class shouldn't be mapped + * to XML by itself. Properties on such class will be mapped to XML along + * with its derived classes, as if the class is inlined. + * + * <p><b>Usage</b></p> + * <p> The {@code @XmlTransient} annotation can be used with the following + * program elements: + * <ul> + * <li> a JavaBean property </li> + * <li> field </li> + * <li> class </li> + * </ul> + * + * <p>{@code @XmlTransient} is mutually exclusive with all other + * Jakarta XML Binding defined annotations. </p> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <p><b>Example:</b> Resolve name collision between JavaBean property and + * field name </p> + * + * {@snippet : + * // Example: Code fragment + * public class USAddress { + * + * // The field name "name" collides with the property name + * // obtained by bean decapitalization of getName() below + * @XmlTransient public String name; + * + * String getName() {..}; + * String setName() {..}; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="USAddress"> + * <xs:sequence> + * <xs:element name="name" type="xs:string"/> + * </xs:sequence> + * </xs:complexType> + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD, TYPE}) +public @interface XmlTransient {} +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlType.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlType.java new file mode 100644 index 0000000..1854401 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlType.java
@@ -0,0 +1,446 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import static java.lang.annotation.ElementType.TYPE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * <p> + * Maps a class or an enum type to an XML Schema type. + * + * <p><b>Usage</b></p> + * <p> The {@code @XmlType} annotation can be used with the following program + * elements: + * <ul> + * <li> a top level class </li> + * <li> an enum type </li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * <h2> Mapping a Class </h2> + * <p> + * A class maps to an XML Schema type. A class is a data container for + * values represented by properties and fields. A schema type is a + * data container for values represented by schema components within a + * schema type's content model (e.g. model groups, attributes etc). + * <p> To be mapped, a class must either have a public no-arg + * constructor or a static no-arg factory method. The static factory + * method can be specified in {@code factoryMethod()} and + * {@code factoryClass()} annotation elements. The static factory + * method or the no-arg constructor is used during unmarshalling to + * create an instance of this class. If both are present, the static + * factory method overrides the no-arg constructor. + * <p> + * A class maps to either an XML Schema complex type or an XML Schema simple + * type. The XML Schema type is derived based on the + * mapping of JavaBean properties and fields contained within the + * class. The schema type to which the class is mapped can either be + * named or anonymous. A class can be mapped to an anonymous schema + * type by annotating the class with {@code @XmlType(name="")}. + * <p> + * Either a global element, local element or a local attribute can be + * associated with an anonymous type as follows: + * <ul> + * <li><b>global element: </b> A global element of an anonymous + * type can be derived by annotating the class with @{@link + * XmlRootElement}. See Example 3 below. </li> + * + * <li><b>local element: </b> A JavaBean property that references + * a class annotated with @XmlType(name="") and is mapped to the + * element associated with the anonymous type. See Example 4 + * below.</li> + * + * <li><b>attribute: </b> A JavaBean property that references + * a class annotated with @XmlType(name="") and is mapped to the + * attribute associated with the anonymous type. See Example 5 below. </li> + * </ul> + * <b> Mapping to XML Schema Complex Type </b> + * <ul> + * <li>If class is annotated with {@code @XmlType(name="") }, it + * is mapped to an anonymous type otherwise, the class name maps + * to a complex type name. The {@code XmlName()} annotation element + * can be used to customize the name.</li> + * + * <li> Properties and fields that are mapped to elements are mapped to a + * content model within a complex type. The annotation element + * {@code propOrder()} can be used to customize the content model to be + * {@code xs:all} or {@code xs:sequence}. It is used for specifying + * the order of XML elements in {@code xs:sequence}. </li> + * + * <li> Properties and fields can be mapped to attributes within the + * complex type. </li> + * + * <li> The targetnamespace of the XML Schema type can be customized + * using the annotation element {@code namespace()}. </li> + * </ul> + * + * <p> + * <b> Mapping class to XML Schema simple type </b> + * <p> + * A class can be mapped to an XML Schema simple type using the + * {@code @XmlValue} annotation. For additional details and examples, + * see @{@link XmlValue} annotation type. + * <p> + * The following table shows the mapping of the class to an XML Schema + * complex type or simple type. The notational symbols used in the table are: + * <ul> + * <li> {@literal ->} : represents a mapping </li> + * <li> [x]+ : one or more occurrences of x </li> + * <li> [ {@code @XmlValue} property ]: JavaBean property annotated with + * {@code @XmlValue}</li> + * <li> X : don't care + * </ul> + * <blockquote> + * <table class="striped"> + * <caption>Mapping class to XML Schema simple type</caption> + * <thead> + * <tr> + * <th scope="col">Target</th> + * <th scope="col">propOrder</th> + * <th scope="col">ClassBody</th> + * <th scope="col">ComplexType</th> + * <th scope="col">SimpleType</th> + * </tr> + * </thead> + * + * <tbody> + * <tr> + * <td>Class</td> + * <td>{}</td> + * <th scope="row">[property]+ {@literal ->} elements</th> + * <td>complexcontent<br>xs:all</td> + * <td> </td> + * </tr> + * + * <tr> + * <td>Class</td> + * <td>non empty</td> + * <th scope="row">[property]+ {@literal ->} elements</th> + * <td>complexcontent<br>xs:sequence</td> + * <td> </td> + * </tr> + * + * <tr> + * <td>Class</td> + * <td>X</td> + * <th scope="row">no property {@literal ->} element</th> + * <td>complexcontent<br>empty sequence</td> + * <td> </td> + * </tr> + * + * <tr> + * <td>Class</td> + * <td>X</td> + * <th scope="row">1 [{@code @XmlValue} property] {@literal &&} <br> [property]+ {@literal ->} attributes</th> + * <td>simplecontent</td> + * <td> </td> + * </tr> + * + * <tr> + * <td>Class</td> + * <td>X</td> + * <th scope="row">1 [{@code @XmlValue} property] {@literal &&} <br> no properties {@literal ->} attribute</th> + * <td> </td> + * <td>simpletype</td> + * </tr> + * </tbody> + * </table> + * </blockquote> + * + * <h3> Mapping an enum type </h3> + * + * An enum type maps to an XML schema simple type with enumeration + * facets. The following annotation elements are ignored since they + * are not meaningful: {@code propOrder()} , {@code factoryMethod()} , + * {@code factoryClass()} . + * + * <h3> Usage with other annotations </h3> + * <p> This annotation can be used with the following annotations: + * {@link XmlRootElement}, {@link XmlAccessorOrder}, {@link XmlAccessorType}, + * {@link XmlEnum}. However, {@link + * XmlAccessorOrder} and {@link XmlAccessorType} are ignored when this + * annotation is used on an enum type. + * + * <p> <b> Example 1: </b> Map a class to a complex type with + * xs:sequence with a customized ordering of JavaBean properties. + * </p> + * + * {@snippet : + * @XmlType(propOrder={"street", "city" , "state", "zip", "name" }) + * public class USAddress { + * String getName() {..}; + * void setName(String) {..}; + * + * String getStreet() {..}; + * void setStreet(String) {..}; + * + * String getCity() {..}; + * void setCity(String) {..}; + * + * String getState() {..}; + * void setState(String) {..}; + * + * java.math.BigDecimal getZip() {..}; + * void setZip(java.math.BigDecimal) {..}; + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema mapping for USAddress --> + * <xs:complexType name="USAddress"> + * <xs:sequence> + * <xs:element name="street" type="xs:string"/> + * <xs:element name="city" type="xs:string"/> + * <xs:element name="state" type="xs:string"/> + * <xs:element name="zip" type="xs:decimal"/> + * <xs:element name="name" type="xs:string"/> + * </xs:all> + * </xs:complexType> + * } + * <p> <b> Example 2: </b> Map a class to a complex type with + * xs:all </p> + * {@snippet : + * @XmlType(propOrder={}) + * public class USAddress { ...} + * } + * {@snippet lang="XML" : + * <!-- XML Schema mapping for USAddress --> + * <xs:complexType name="USAddress"> + * <xs:all> + * <xs:element name="name" type="xs:string"/> + * <xs:element name="street" type="xs:string"/> + * <xs:element name="city" type="xs:string"/> + * <xs:element name="state" type="xs:string"/> + * <xs:element name="zip" type="xs:decimal"/> + * </xs:sequence> + * </xs:complexType> + * } + * <p> <b> Example 3: </b> Map a class to a global element with an + * anonymous type. + * </p> + * {@snippet : + * @XmlRootElement + * @XmlType(name="") + * public class USAddress { ...} + * } + * {@snippet lang="XML" : + * <!-- XML Schema mapping for USAddress --> + * <xs:element name="USAddress"> + * <xs:complexType> + * <xs:sequence> + * <xs:element name="name" type="xs:string"/> + * <xs:element name="street" type="xs:string"/> + * <xs:element name="city" type="xs:string"/> + * <xs:element name="state" type="xs:string"/> + * <xs:element name="zip" type="xs:decimal"/> + * </xs:sequence> + * </xs:complexType> + * </xs:element> + * } + * + * <p> <b> Example 4: </b> Map a property to a local element with + * anonymous type. + * {@snippet : + * //Example: Code fragment + * public class Invoice { + * USAddress addr; + * ... + * } + * + * @XmlType(name="") + * public class USAddress { ... } + * } + * } + * {@snippet lang="XML" : + * <!-- XML Schema mapping for USAddress --> + * <xs:complexType name="Invoice"> + * <xs:sequence> + * <xs:element name="addr"> + * <xs:complexType> + * <xs:element name="name", type="xs:string"/> + * <xs:element name="city", type="xs:string"/> + * <xs:element name="city" type="xs:string"/> + * <xs:element name="state" type="xs:string"/> + * <xs:element name="zip" type="xs:decimal"/> + * </xs:complexType> + * </xs:element> + * ... + * </xs:sequence> + * </xs:complexType> + * } + * + * <p> <b> Example 5: </b> Map a property to an attribute with + * anonymous type. + * + * {@snippet : + * //Example: Code fragment + * public class Item { + * public String name; + * @XmlAttribute + * public USPrice price; + * } + * + * // map class to anonymous simple type. + * @XmlType(name="") + * public class USPrice { + * @XmlValue + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example: XML Schema fragment --> + * <xs:complexType name="Item"> + * <xs:sequence> + * <xs:element name="name" type="xs:string"/> + * <xs:attribute name="price"> + * <xs:simpleType> + * <xs:restriction base="xs:decimal"/> + * </xs:simpleType> + * </xs:attribute> + * </xs:sequence> + * </xs:complexType> + * } + * + * <p> <b> Example 6: </b> Define a factoryClass and factoryMethod + * + * {@snippet : + * @XmlType(name="USAddressType", factoryClass=USAddressFactory.class, + * factoryMethod="getUSAddress") + * public class USAddress { + * + * private String city; + * private String name; + * private String state; + * private String street; + * private int zip; + * + * public USAddress(String name, String street, String city, + * String state, int zip) { + * this.name = name; + * this.street = street; + * this.city = city; + * this.state = state; + * this.zip = zip; + * } + * } + * + * public class USAddressFactory { + * public static USAddress getUSAddress() { + * return new USAddress("Mark Baker", "23 Elm St", + * "Dayton", "OH", 90952); + * } + * + * } + * } + * + * <p> <b> Example 7: </b> Define factoryMethod and use the default factoryClass + * + * {@snippet : + * @XmlType(name="USAddressType", factoryMethod="getNewInstance") + * public class USAddress { + * + * private String city; + * private String name; + * private String state; + * private String street; + * private int zip; + * + * private USAddress() {} + * + * public static USAddress getNewInstance() { + * return new USAddress(); + * } + * } + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @see XmlElement + * @see XmlAttribute + * @see XmlValue + * @see XmlSchema + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({TYPE}) +public @interface XmlType { + /** + * Name of the XML Schema type which the class is mapped. + */ + String name() default "##default" ; + + /** + * Specifies the order for XML Schema elements when class is + * mapped to an XML Schema complex type. + * + * <p> Refer to the table for how the propOrder affects the + * mapping of class </p> + * + * <p> The propOrder is a list of names of JavaBean properties in + * the class. Each name in the list is the name of a Java + * identifier of the JavaBean property. The order in which + * JavaBean properties are listed is the order of XML Schema + * elements to which the JavaBean properties are mapped. </p> + * <p> All of the JavaBean properties being mapped to XML Schema elements + * must be listed. + * <p> A JavaBean property or field listed in propOrder must not + * be transient or annotated with {@code @XmlTransient}. + * <p> The default ordering of JavaBean properties is determined + * by @{@link XmlAccessorOrder}. + */ + String[] propOrder() default {""}; + + /** + * Name of the target namespace of the XML Schema type. By + * default, this is the target namespace to which the package + * containing the class is mapped. + */ + String namespace() default "##default" ; + + /** + * Class containing a no-arg factory method for creating an + * instance of this class. The default is this class. + * + * <p>If {@code factoryClass} is DEFAULT.class and + * {@code factoryMethod} is "", then there is no static factory + * method. + * + * <p>If {@code factoryClass} is DEFAULT.class and + * {@code factoryMethod} is not "", then + * {@code factoryMethod} is the name of a static factory method + * in this class. + * + * <p>If {@code factoryClass} is not DEFAULT.class, then + * {@code factoryMethod} must not be "" and must be the name of + * a static factory method specified in {@code factoryClass}. + */ + Class<?> factoryClass() default DEFAULT.class; + + /** + * Used in {@link XmlType#factoryClass()} to + * signal that either factory mehod is not used or + * that it's in the class with this {@link XmlType} itself. + */ + final class DEFAULT { + private DEFAULT() {} + } + + /** + * Name of a no-arg factory method in the class specified in + * {@code factoryClass} factoryClass(). + * + */ + String factoryMethod() default ""; +} + +
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/XmlValue.java b/api/src/main/java/jakarta/xml/bind/annotation/XmlValue.java new file mode 100644 index 0000000..f2d3727 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/XmlValue.java
@@ -0,0 +1,111 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation; + +import java.lang.annotation.Target; +import java.lang.annotation.Retention; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +/** + * <p> + * Enables mapping a class to a XML Schema complex type with a + * simpleContent or an XML Schema simple type. + * </p> + * + * <p> + * <b> Usage: </b> + * <p> + * The {@code @XmlValue} annotation can be used with the following program + * elements: + * <ul> + * <li> a JavaBean property.</li> + * <li> non-static, non transient field.</li> + * </ul> + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * The usage is subject to the following usage constraints: + * <ul> + * <li>At most one field or property can be annotated with the + * {@code @XmlValue} annotation. </li> + * + * <li>{@code @XmlValue} can be used with the following + * annotations: {@link XmlList}. However this is redundant since + * {@link XmlList} maps a type to a simple schema type that derives by + * list just as {@link XmlValue} would. </li> + * + * <li>If the type of the field or property is a collection type, + * then the collection item type must map to a simple schema + * type. </li> + * + * <li>If the type of the field or property is not a collection + * type, then the type must map to an XML Schema simple type. </li> + * + * </ul> + * <p> + * If the annotated JavaBean property is the sole class member being + * mapped to XML Schema construct, then the class is mapped to a + * simple type. + * <p> + * If there are additional JavaBean properties (other than the + * JavaBean property annotated with {@code @XmlValue} annotation) + * that are mapped to XML attributes, then the class is mapped to a + * complex type with simpleContent. + * </p> + * + * <p> <b> Example 1: </b> Map a class to XML Schema simpleType</p> + * + * {@snippet : + * // Example 1: Code fragment + * public class USPrice { + * @XmlValue + * public java.math.BigDecimal price; + * } + * } + * {@snippet lang="XML" : + * <!-- Example 1: XML Schema fragment --> + * <xs:simpleType name="USPrice"> + * <xs:restriction base="xs:decimal"/> + * </xs:simpleType> + * } + * + * <p><b> Example 2: </b> Map a class to XML Schema complexType with + * with simpleContent.</p> + * + * {@snippet : + * // Example 2: Code fragment + * public class InternationalPrice { + * @XmlValue + * public java.math.BigDecimal price; + * + * @XmlAttribute + * public String currency; + * } + * } + * {@snippet lang="XML" : + * <!-- Example 2: XML Schema fragment --> + * <xs:complexType name="InternationalPrice"> + * <xs:simpleContent> + * <xs:extension base="xs:decimal"> + * <xs:attribute name="currency" type="xs:string"/> + * </xs:extension> + * </xs:simpleContent> + * </xs:complexType> + * } + * + * @author Sekhar Vajjhala, Sun Microsystems, Inc. + * @see XmlType + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlValue {}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/CollapsedStringAdapter.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/CollapsedStringAdapter.java new file mode 100644 index 0000000..0ad674b --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/CollapsedStringAdapter.java
@@ -0,0 +1,107 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +/** + * Built-in {@link XmlAdapter} to handle {@code xs:token} and its derived types. + * + * <p> + * This adapter removes leading and trailing whitespaces, then truncate any + * sequence of tab, CR, LF, and SP by a single whitespace character ' '. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +public class CollapsedStringAdapter extends XmlAdapter<String,String> { + + public CollapsedStringAdapter() {} + + /** + * Removes leading and trailing whitespaces of the string + * given as the parameter, then truncate any + * sequence of tab, CR, LF, and SP by a single whitespace character ' '. + */ + @Override + public String unmarshal(String text) { + if(text==null) return null; // be defensive + + int len = text.length(); + + // most of the texts are already in the collapsed form. + // so look for the first whitespace in the hope that we will + // never see it. + int s=0; + while(s<len) { + if(isWhiteSpace(text.charAt(s))) + break; + s++; + } + if(s==len) + // the input happens to be already collapsed. + return text; + + // we now know that the input contains spaces. + // let's sit down and do the collapsing normally. + + StringBuilder result = new StringBuilder(len /*allocate enough size to avoid re-allocation*/ ); + + if(s!=0) { + for( int i=0; i<s; i++ ) + result.append(text.charAt(i)); + result.append(' '); + } + + boolean inStripMode = true; + for (int i = s+1; i < len; i++) { + char ch = text.charAt(i); + boolean b = isWhiteSpace(ch); + if (inStripMode && b) + continue; // skip this character + + inStripMode = b; + if (inStripMode) + result.append(' '); + else + result.append(ch); + } + + // remove trailing whitespaces + len = result.length(); + if (len > 0 && result.charAt(len - 1) == ' ') + result.setLength(len - 1); + // whitespaces are already collapsed, + // so all we have to do is to remove the last one character + // if it's a whitespace. + + return result.toString(); + } + + /** + * No-op. + * <p> + * Just return the same string given as the parameter. + */ + @Override + public String marshal(String s) { + return s; + } + + + /** returns true if the specified char is a white space character. */ + protected static boolean isWhiteSpace(char ch) { + // most of the characters are non-control characters. + // so check that first to quickly return false for most of the cases. + if( ch>0x20 ) return false; + + // other than we have to do four comparisons. + return ch == 0x9 || ch == 0xA || ch == 0xD || ch == 0x20; + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/HexBinaryAdapter.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/HexBinaryAdapter.java new file mode 100644 index 0000000..5a74f80 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/HexBinaryAdapter.java
@@ -0,0 +1,39 @@ +/* + * Copyright (c) 2004, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +import jakarta.xml.bind.DatatypeConverter; + +/** + * {@link XmlAdapter} for {@code xs:hexBinary}. + * + * <p> + * This {@link XmlAdapter} binds {@code byte[]} to the hexBinary representation in XML. + * + * @author Kohsuke Kawaguchi + * @since 1.6, JAXB 2.0 + */ +public final class HexBinaryAdapter extends XmlAdapter<String,byte[]> { + + public HexBinaryAdapter() {} + + @Override + public byte[] unmarshal(String s) { + if(s==null) return null; + return DatatypeConverter.parseHexBinary(s); + } + + @Override + public String marshal(byte[] bytes) { + if(bytes==null) return null; + return DatatypeConverter.printHexBinary(bytes); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/NormalizedStringAdapter.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/NormalizedStringAdapter.java new file mode 100644 index 0000000..b9f735e --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/NormalizedStringAdapter.java
@@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +/** + * {@link XmlAdapter} to handle {@code xs:normalizedString}. + * + * <p> + * Replaces any tab, CR, and LF by a whitespace character ' ', + * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">the whitespace facet 'replace'</a> + * + * @author Kohsuke Kawaguchi, Martin Grebac + * @since 1.6, JAXB 2.0 + */ +public final class NormalizedStringAdapter extends XmlAdapter<String,String> { + + public NormalizedStringAdapter() {} + + /** + * Replace any tab, CR, and LF by a whitespace character ' ', + * as specified in <a href="http://www.w3.org/TR/xmlschema-2/#rf-whiteSpace">the whitespace facet 'replace'</a> + */ + @Override + public String unmarshal(String text) { + if(text==null) return null; // be defensive + + int i=text.length()-1; + + // look for the first whitespace char. + while( i>=0 && !isWhiteSpaceExceptSpace(text.charAt(i)) ) + i--; + + if( i<0 ) + // no such whitespace. replace(text)==text. + return text; + + // we now know that we need to modify the text. + // allocate a char array to do it. + char[] buf = text.toCharArray(); + + buf[i--] = ' '; + for( ; i>=0; i-- ) + if( isWhiteSpaceExceptSpace(buf[i])) + buf[i] = ' '; + + return new String(buf); + } + + /** + * No-op. + * Just return the same string given as the parameter. + */ + @Override + public String marshal(String s) { + return s; + } + + + /** + * Returns true if the specified char is a white space character + * but not 0x20. + */ + protected static boolean isWhiteSpaceExceptSpace(char ch) { + // most of the characters are non-control characters. + // so check that first to quickly return false for most of the cases. + if( ch>=0x20 ) return false; + + // other than we have to do four comparisons. + return ch == 0x9 || ch == 0xA || ch == 0xD; + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlAdapter.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlAdapter.java new file mode 100644 index 0000000..036f193 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlAdapter.java
@@ -0,0 +1,175 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +/** + * Adapts a Java type for custom marshaling. + * + * <p> <b> Usage: </b> </p> + * + * <p> + * Some Java types do not map naturally to an XML representation, for + * example {@code HashMap} or other non JavaBean classes. Conversely, + * an XML representation may map to a Java type but an application may + * choose to access the XML representation using another Java + * type. For example, the schema to Java binding rules bind + * xs:DateTime by default to XmlGregorianCalendar. But an application + * may desire to bind xs:DateTime to a custom type, + * MyXmlGregorianCalendar, for example. In both cases, there is a + * mismatch between <i> bound type </i>, used by an application to + * access XML content and the <i> value type</i>, that is mapped to an + * XML representation. + * + * <p> + * This abstract class defines methods for adapting a bound type to a value + * type or vice versa. The methods are invoked by the Jakarta XML Binding binding + * framework during marshaling and unmarshalling: + * + * <ul> + * <li> <b> XmlAdapter.marshal(...): </b> During marshalling, Jakarta XML Binding + * binding framework invokes XmlAdapter.marshal(..) to adapt a + * bound type to value type, which is then marshaled to XML + * representation. </li> + * + * <li> <b> XmlAdapter.unmarshal(...): </b> During unmarshalling, + * Jakarta XML Binding binding framework first unmarshalls XML representation + * to a value type and then invokes XmlAdapter.unmarshal(..) to + * adapt the value type to a bound type. </li> + * </ul> + * + * Writing an adapter therefore involves the following steps: + * + * <ul> + * <li> Write an adapter that implements this abstract class. </li> + * <li> Install the adapter using the annotation {@link + * XmlJavaTypeAdapter} </li> + * </ul> + * + * <p><b>Example:</b> Customized mapping of {@code HashMap}</p> + * <p> The following example illustrates the use of + * {@code @XmlAdapter} and {@code @XmlJavaTypeAdapter} to + * customize the mapping of a {@code HashMap}. + * + * <p> <b> Step 1: </b> Determine the desired XML representation for HashMap. + * + * {@snippet lang="XML" : + * <hashmap> + * <entry key="id123">this is a value</entry> + * <entry key="id312">this is another value</entry> + * ... + * </hashmap> + * } + * + * <p> <b> Step 2: </b> Determine the schema definition that the + * desired XML representation shown above should follow. + * + * {@snippet lang="XML" : + * <xs:complexType name="myHashMapType"> + * <xs:sequence> + * <xs:element name="entry" type="myHashMapEntryType" + * minOccurs = "0" maxOccurs="unbounded"/> + * </xs:sequence> + * </xs:complexType> + * + * <xs:complexType name="myHashMapEntryType"> + * <xs:simpleContent> + * <xs:extension base="xs:string"> + * <xs:attribute name="key" type="xs:int"/> + * </xs:extension> + * </xs:simpleContent> + * </xs:complexType> + * } + * + * <p> <b> Step 3: </b> Write value types that can generate the above + * schema definition. + * + * {@snippet : + * public class MyHashMapType { + * List<MyHashMapEntryType> entry; + * } + * + * public class MyHashMapEntryType { + * @XmlAttribute + * public Integer key; + * + * @XmlValue + * public String value; + * } + * } + * + * <p> <b> Step 4: </b> Write the adapter that adapts the value type, + * MyHashMapType to a bound type, HashMap, used by the application. + * + * {@snippet : + * public final class MyHashMapAdapter extends + * XmlAdapter<MyHashMapType,HashMap> { ... } + * } + * + * <p> <b> Step 5: </b> Use the adapter. + * + * {@snippet : + * public class Foo { + * @XmlJavaTypeAdapter(MyHashMapAdapter.class) + * HashMap hashmap; + * ... + * } + * } + * + * The above code fragment will map to the following schema: + * + * {@snippet lang="XML" : + * <xs:complexType name="Foo"> + * <xs:sequence> + * <xs:element name="hashmap" type="myHashMapType"> + * </xs:sequence> + * </xs:complexType> + * } + * + * @param <BoundType> + * The type that Jakarta XML Binding doesn't know how to handle. An adapter is written + * to allow this type to be used as an in-memory representation through + * the {@code ValueType}. + * @param <ValueType> + * The type that Jakarta XML Binding knows how to handle out of the box. + * + * @author <ul><li>Sekhar Vajjhala, Sun Microsystems Inc.</li> <li> Kohsuke Kawaguchi, Sun Microsystems Inc.</li></ul> + * @see XmlJavaTypeAdapter + * @since 1.6, JAXB 2.0 + */ +public abstract class XmlAdapter<ValueType,BoundType> { + + /** + * Do-nothing constructor for the derived classes. + */ + protected XmlAdapter() {} + + /** + * Convert a value type to a bound type. + * + * @param v + * The value to be converted. Can be null. + * @throws Exception + * if there's an error during the conversion. The caller is responsible for + * reporting the error to the user through {@link jakarta.xml.bind.ValidationEventHandler}. + */ + public abstract BoundType unmarshal(ValueType v) throws Exception; + + /** + * Convert a bound type to a value type. + * + * @param v + * The value to be converted. Can be null. + * @throws Exception + * if there's an error during the conversion. The caller is responsible for + * reporting the error to the user through {@link jakarta.xml.bind.ValidationEventHandler}. + */ + public abstract ValueType marshal(BoundType v) throws Exception; +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.java new file mode 100644 index 0000000..3eb0b15 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.java
@@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +import jakarta.xml.bind.annotation.XmlAnyElement; +import jakarta.xml.bind.annotation.XmlElementRefs; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlSchemaType; +import jakarta.xml.bind.annotation.XmlElementRef; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlSchema; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlSchemaTypes; +import java.lang.annotation.Target; +import java.lang.annotation.Retention; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.PACKAGE; + + +/** + * Use an adapter that implements {@link XmlAdapter} for custom marshaling. + * + * <p> <b> Usage: </b> </p> + * + * <p> The {@code @XmlJavaTypeAdapter} annotation can be used with the + * following program elements: + * <ul> + * <li> a JavaBean property </li> + * <li> field </li> + * <li> parameter </li> + * <li> package </li> + * <li> from within {@link XmlJavaTypeAdapters} </li> + * </ul> + * + * <p> When {@code @XmlJavaTypeAdapter} annotation is defined on a + * class, it applies to all references to the class. + * <p> When {@code @XmlJavaTypeAdapter} annotation is defined at the + * package level it applies to all references from within the package + * to {@code @XmlJavaTypeAdapter.type()}. + * <p> When {@code @XmlJavaTypeAdapter} annotation is defined on the + * field, property or parameter, then the annotation applies to the + * field, property or the parameter only. + * <p> A {@code @XmlJavaTypeAdapter} annotation on a field, property + * or parameter overrides the {@code @XmlJavaTypeAdapter} annotation + * associated with the class being referenced by the field, property + * or parameter. + * <p> A {@code @XmlJavaTypeAdapter} annotation on a class overrides + * the {@code @XmlJavaTypeAdapter} annotation specified at the + * package level for that class. + * + * <p>This annotation can be used with the following other annotations: + * {@link XmlElement}, {@link XmlAttribute}, {@link XmlElementRef}, + * {@link XmlElementRefs}, {@link XmlAnyElement}. This can also be + * used at the package level with the following annotations: + * {@link XmlAccessorType}, {@link XmlSchema}, {@link XmlSchemaType}, + * {@link XmlSchemaTypes}. + * + * <p><b> Example: </b> See example in {@link XmlAdapter} + * + * @author <ul><li>Sekhar Vajjhala, Sun Microsystems Inc.</li> <li> Kohsuke Kawaguchi, Sun Microsystems Inc.</li></ul> + * @since 1.6, JAXB 2.0 + * @see XmlAdapter + */ +@Retention(RUNTIME) @Target({PACKAGE,FIELD,METHOD,TYPE,PARAMETER}) +public @interface XmlJavaTypeAdapter { + /** + * Points to the class that converts a value type to a bound type or vice versa. + * See {@link XmlAdapter} for more details. + */ + @SuppressWarnings({"rawtypes"}) + Class<? extends XmlAdapter> value(); + + /** + * If this annotation is used at the package level, then value of + * the type() must be specified. + */ + + Class<?> type() default DEFAULT.class; + + /** + * Used in {@link XmlJavaTypeAdapter#type()} to + * signal that the type be inferred from the signature + * of the field, property, parameter or the class. + */ + + final class DEFAULT { + private DEFAULT() {} + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapters.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapters.java new file mode 100644 index 0000000..c300b21 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapters.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.annotation.adapters; + +import static java.lang.annotation.ElementType.PACKAGE; +import java.lang.annotation.Retention; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Target; + +/** + * <p> + * A container for multiple @{@link XmlJavaTypeAdapter} annotations. + * + * <p> Multiple annotations of the same type are not allowed on a program + * element. This annotation therefore serves as a container annotation + * for multiple @XmlJavaTypeAdapter as follows: + * + * {@snippet : + * @XmlJavaTypeAdapters ({ @XmlJavaTypeAdapter(...), @XmlJavaTypeAdapter(...) }) + * } + * + * <p>The {@code @XmlJavaTypeAdapters} annotation is useful for + * defining {@link XmlJavaTypeAdapter} annotations for different types + * at the package level. + * + * <p>See "Package Specification" in jakarta.xml.bind.package javadoc for + * additional common information.</p> + * + * @author <ul><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul> + * @see XmlJavaTypeAdapter + * @since 1.6, JAXB 2.0 + */ +@Retention(RUNTIME) @Target({PACKAGE}) +public @interface XmlJavaTypeAdapters { + /** + * Collection of @{@link XmlJavaTypeAdapter} annotations + */ + XmlJavaTypeAdapter[] value(); +}
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/adapters/package-info.java b/api/src/main/java/jakarta/xml/bind/annotation/adapters/package-info.java new file mode 100644 index 0000000..0f5e1a4 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/adapters/package-info.java
@@ -0,0 +1,34 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * {@link jakarta.xml.bind.annotation.adapters.XmlAdapter} and its spec-defined + * subclasses to allow arbitrary Java classes to be used with Jakarta XML Binding. + * + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * + * <ul> + * <li><a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Specification project</a> + * </ul> + * + * <h2>Related Documentation</h2> + * + * For overviews, tutorials, examples, guides, and tool documentation, + * please see: + * <ul> + * <li>The <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + * </ul> + * + * @see <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + */ +package jakarta.xml.bind.annotation.adapters;
diff --git a/api/src/main/java/jakarta/xml/bind/annotation/package-info.java b/api/src/main/java/jakarta/xml/bind/annotation/package-info.java new file mode 100644 index 0000000..a7c45d6 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/annotation/package-info.java
@@ -0,0 +1,175 @@ +/* + * Copyright (c) 2004, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Defines annotations for customizing Java program elements to XML Schema mapping. + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * <p>The following table shows the Jakarta XML Binding mapping annotations + * that can be associated with each program element. </p> + * <table class="striped"> + * <caption>Annotations for customizing Java program elements to XML Schema mapping</caption> + * <thead> + * <tr> + * <th scope="col">Program Element</th> + * <th scope="col">Jakarta XML Binding annotation</th> + * </tr> + * </thead> + * <tbody style="text-align:left"> + * <tr> + * <th scope="row" style="vertical-align:top">Package</th> + * <td> + * <ul style="list-style-type:none"> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAccessorOrder.html">XmlAccessorOrder</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAccessorType.html">XmlAccessorType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlSchema.html">XmlSchema</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlSchemaType.html">XmlSchemaType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlSchemaTypes.html">XmlSchemaTypes</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapters.html">XmlJavaTypeAdapters</a></li> + * </ul> + * </td> + * </tr> + * <tr> + * <th scope="row" style="vertical-align:top">Class</th> + * <td> + * <ul style="list-style-type:none"> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAccessorOrder.html">XmlAccessorOrder</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAccessorType.html">XmlAccessorType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlInlineBinaryData.html">XmlInlineBinaryData</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlRootElement.html">XmlRootElement</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlType.html">XmlType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a></li> + * </ul> + * </td> + * </tr> + * <tr> + * <th scope="row" style="vertical-align:top">Enum type</th> + * <td> + * <ul style="list-style-type:none"> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlEnum.html">XmlEnum</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlEnumValue.html">XmlEnumValue (enum constant only)</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlRootElement.html">XmlRootElement</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlType.html">XmlType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a></li> + * </ul> + * </td> + * </tr> + * <tr> + * <th scope="row" style="vertical-align:top">JavaBean Property/field</th> + * <td> + * <ul style="list-style-type:none"> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElement.html">XmlElement</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElements.html">XmlElements</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElementRef.html">XmlElementRef</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElementRefs.html">XmlElementRefs</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElementWrapper.html">XmlElementWrapper</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAnyElement.html">XmlAnyElement</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAttribute.html">XmlAttribute</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAnyAttribute.html">XmlAnyAttribute</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlTransient.html">XmlTransient</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlValue.html">XmlValue</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlID.html">XmlID</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlIDREF.html">XmlIDREF</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlList.html">XmlList</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlMixed.html">XmlMixed</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlMimeType.html">XmlMimeType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAttachmentRef.html">XmlAttachmentRef</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlInlineBinaryData.html">XmlInlineBinaryData</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlElementDecl.html">XmlElementDecl (only on method)</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a></li> + * </ul> + * </td> + * </tr> + * <tr> + * <th scope="row" style="vertical-align:top">Parameter</th> + * <td> + * <ul style="list-style-type:none"> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlList.html">XmlList</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlAttachmentRef.html">XmlAttachmentRef</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/XmlMimeType.html">XmlMimeType</a></li> + * <li><a HREF="../../../../jakarta/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a></li> + * </ul> + * </td> + * </tr> + * </tbody> + * </table> + * <h3>Terminology</h3> + * <p> + * <b>JavaBean property and field:</b> For the purposes of + * mapping, there is no semantic difference between a field and + * a JavaBean property. Thus, an annotation that can be applied + * to a JavaBean property can always be applied to a + * field. Hence, in the Javadoc documentation, for brevity, the + * term JavaBean property or property is used to mean either JavaBean + * property or a field. Where required, both are explicitly + * mentioned. + * <p> + * <b>top level class:</b> For the purpose of mapping, there is + * no semantic difference between a top level class and a + * static nested class. Thus, an annotation that can be applied + * to a top level class, can always be applied to a nested + * static class. Hence, in the Javadoc documentation, for + * brevity, the term "top level class" or just class is used to + * mean either a top level class or a nested static + * class. + * <p> + * <b>mapping annotation:</b>A Jakarta XML Binding defined program + * annotation based on the JSR 175 programming annotation + * facility. + * <h3>Common Usage Constraints</h3> + * <p>The following usage constraints are defined here since + * they apply to more than annotation: + * <ul> + * <li> For a property, a given annotation can be applied to + * either read or write property but not both. </li> + * <li> A property name must be different from any other + * property name in any of the super classes of the + * class being mapped. </li> + * <li> A mapped field name or the decapitalized name of a + * mapped property must be unique within a class. </li> + * </ul> + * <h3>Notations</h3> + * <b>Namespace prefixes</b> + * <p>The following namespace prefixes are used in the XML Schema + * fragments in this package. + * <table class="striped"> + * <caption>XML Schema fragments namespace prefixes</caption> + * <thead> + * <tr> + * <th scope="col">Prefix</th> + * <th scope="col">Namespace</th> + * <th scope="col">Notes</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <th scope="row">xs</th> + * <td>http://www.w3.org/2001/XMLSchema</td> + * <td>Namespace of XML Schema namespace</td> + * </tr> + * <tr> + * <th scope="row">ref</th> + * <td>http://ws-i.org/profiles/basic/1.1/xsd</td> + * <td>Namespace for swaref schema component</td> + * </tr> + * <tr> + * <th scope="row">xsi</th> + * <td>http://www.w3.org/2001/XMLSchema-instance</td> + * <td>XML Schema namespace for instances</td> + * </tr> + * </tbody> + * </table> + * + * @since 1.6, JAXB 2.0 + */ +package jakarta.xml.bind.annotation;
diff --git a/api/src/main/java/jakarta/xml/bind/attachment/AttachmentMarshaller.java b/api/src/main/java/jakarta/xml/bind/attachment/AttachmentMarshaller.java new file mode 100644 index 0000000..6bd82ab --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/attachment/AttachmentMarshaller.java
@@ -0,0 +1,190 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.attachment; + +import jakarta.activation.DataHandler; +import jakarta.xml.bind.Marshaller; + +/** + * <p>Enable Jakarta XML Binding marshalling to optimize storage of binary data. + * + * <p>This API enables an efficient cooperative creation of optimized + * binary data formats between a Jakarta XML Binding marshalling process and a MIME-based package + * processor. A Jakarta XML Binding implementation marshals the root body of a MIME-based package, + * delegating the creation of referenceable MIME parts to + * the MIME-based package processor that implements this abstraction. + * + * <p>XOP processing is enabled when {@link #isXOPPackage()} is true. + * See {@link #addMtomAttachment(DataHandler, String, String)} for details. + * + * + * <p>WS-I Attachment Profile 1.0 is supported by + * {@link #addSwaRefAttachment(DataHandler)} being called by the + * marshaller for each Jakarta XML Binding property related to + * {http://ws-i.org/profiles/basic/1.1/xsd}swaRef. + * + * + * @author Marc Hadley + * @author Kohsuke Kawaguchi + * @author Joseph Fialli + * @since 1.6, JAXB 2.0 + * + * @see Marshaller#setAttachmentMarshaller(AttachmentMarshaller) + * + * @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a> + * @see <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html">WS-I Attachments Profile Version 1.0.</a> + */ +public abstract class AttachmentMarshaller { + + /** + * Do-nothing constructor for the derived classes. + */ + protected AttachmentMarshaller() {} + + /** + * <p>Consider MIME content {@code data} for optimized binary storage as an attachment. + * + * <p> + * This method is called by Jakarta XML Binding marshal process when {@link #isXOPPackage()} is + * {@code true}, for each element whose datatype is "base64Binary", as described in + * Step 3 in + * <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#creating_xop_packages">Creating XOP Packages</a>. + * + * <p> + * The method implementor determines whether {@code data} shall be attached separately + * or inlined as base64Binary data. If the implementation chooses to optimize the storage + * of the binary data as a MIME part, it is responsible for attaching {@code data} to the + * MIME-based package, and then assigning a unique content-id, cid, that identifies + * the MIME part within the MIME message. This method returns the cid, + * which enables the Jakarta XML Binding marshaller to marshal a XOP element that refers to that cid in place + * of marshalling the binary data. When the method returns null, the Jakarta XML Binding marshaller + * inlines {@code data} as base64binary data. + * + * <p> + * The caller of this method is required to meet the following constraint. + * If the element infoset item containing {@code data} has the attribute + * {@code xmime:contentType} or if the Jakarta XML Binding property/field representing + * {@code data} is annotated with a known MIME type, + * {@code data.getContentType()} should be set to that MIME type. + * + * <p> + * The {@code elementNamespace} and {@code elementLocalName} + * parameters provide the + * context that contains the binary data. This information could + * be used by the MIME-based package processor to determine if the + * binary data should be inlined or optimized as an attachment. + * + * @param data + * represents the data to be attached. Must be non-null. + * @param elementNamespace + * the namespace URI of the element that encloses the base64Binary data. + * Can be empty but never null. + * @param elementLocalName + * The local name of the element. Always a non-null valid string. + * + * @return + * a valid content-id URI (see <a href="http://www.w3.org/TR/xop10/#RFC2387">RFC 2387</a>) that identifies the attachment containing {@code data}. + * Otherwise, null if the attachment was not added and should instead be inlined in the message. + * + * @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a> + * @see <a href="http://www.w3.org/TR/xml-media-types/">Describing Media Content of Binary Data in XML</a> + */ + public abstract String addMtomAttachment(DataHandler data, String elementNamespace, String elementLocalName); + + /** + * <p>Consider binary {@code data} for optimized binary storage as an attachment. + * + * <p>Since content type is not known, the attachment's MIME content type must be set to "application/octet-stream". + * + * <p> + * The {@code elementNamespace} and {@code elementLocalName} + * parameters provide the + * context that contains the binary data. This information could + * be used by the MIME-based package processor to determine if the + * binary data should be inlined or optimized as an attachment. + * + * @param data + * represents the data to be attached. Must be non-null. The actual data region is + * specified by {@code (data,offset,length)} tuple. + * + * @param offset + * The offset within the array of the first byte to be read; + * must be non-negative and no larger than array.length + * + * @param length + * The number of bytes to be read from the given array; + * must be non-negative and no larger than array.length + * + * @param mimeType + * If the data has an associated MIME type known to Jakarta XML Binding, that is passed + * as this parameter. If none is known, "application/octet-stream". + * This parameter may never be null. + * + * @param elementNamespace + * the namespace URI of the element that encloses the base64Binary data. + * Can be empty but never null. + * + * @param elementLocalName + * The local name of the element. Always a non-null valid string. + * + * @return content-id URI, cid, to the attachment containing + * {@code data} or null if data should be inlined. + * + * @see #addMtomAttachment(DataHandler, String, String) + */ + public abstract String addMtomAttachment(byte[] data, int offset, int length, String mimeType, String elementNamespace, String elementLocalName); + + /** + * <p>Read-only property that returns true if Jakarta XML Binding marshaller should enable XOP creation. + * + * <p>This value must not change during the marshalling process. When this + * value is true, the {@code addMtomAttachment(...)} method + * is invoked when the appropriate binary datatypes are encountered by + * the marshal process. + * + * <p>Marshaller.marshal() must throw IllegalStateException if this value is {@code true} + * and the XML content to be marshalled violates Step 1 in + * <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#creating_xop_packages">Creating XOP Packages</a> + * http://www.w3.org/TR/2005/REC-xop10-20050125/#creating_xop_packages. + * <i>"Ensure the Original XML Infoset contains no element information item with a + * [namespace name] of "http://www.w3.org/2004/08/xop/include" and a [local name] of Include"</i> + * + * <p>When this method returns true and during the marshal process + * at least one call to {@code addMtomAttachment(...)} returns + * a content-id, the MIME-based package processor must label the + * root part with the application/xop+xml media type as described in + * Step 5 of + * <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#creating_xop_packages">Creating XOP Pacakges</a>. + * + * @return true when MIME context is a XOP Package. + */ + public boolean isXOPPackage() { return false; } + + /** + * <p>Add MIME {@code data} as an attachment and return attachment's content-id, cid. + * + * <p> + * This method is called by Jakarta XML Binding marshal process for each element/attribute typed as + * {http://ws-i.org/profiles/basic/1.1/xsd}swaRef. The MIME-based package processor + * implementing this method is responsible for attaching the specified data to a + * MIME attachment, and generating a content-id, cid, that uniquely identifies the attachment + * within the MIME-based package. + * + * <p>Caller inserts the returned content-id, cid, into the XML content being marshalled. + * + * @param data + * represents the data to be attached. Must be non-null. + * @return + * must be a valid URI used as cid. Must satisfy Conformance Requirement R2928 from + * <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html#Referencing_Attachments_from_the_SOAP_Envelope">WS-I Attachments Profile Version 1.0.</a> + */ + public abstract String addSwaRefAttachment(DataHandler data); +}
diff --git a/api/src/main/java/jakarta/xml/bind/attachment/AttachmentUnmarshaller.java b/api/src/main/java/jakarta/xml/bind/attachment/AttachmentUnmarshaller.java new file mode 100644 index 0000000..65361b7 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/attachment/AttachmentUnmarshaller.java
@@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.attachment; + +import jakarta.activation.DataHandler; + +/** + * <p>Enables Jakarta XML Binding unmarshalling of a root document containing optimized binary data formats.</p> + * + * <p>This API enables an efficient cooperative processing of optimized + * binary data formats between a Jakarta XML Binding implementation and MIME-based package + * processor (MTOM/XOP and WS-I AP 1.0). Jakarta XML Binding unmarshalls the body of a package, delegating the + * understanding of the packaging format being used to a MIME-based + * package processor that implements this abstract class.</p> + * + * <p>This abstract class identifies if a package requires XOP processing, {@link #isXOPPackage()} + * and provides retrieval of binary content stored as attachments by content-id.</p> + * + * <h2>Identifying the content-id, cid, to pass to {@code getAttachment*(String cid)}</h2> + * <ul> + * <li> + * For XOP processing, the infoset representation of the cid is described + * in step 2a in + * <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#interpreting_xop_packages">Section 3.2 Interpreting XOP Packages</a> + * </li> + * <li> + * For WS-I AP 1.0, the cid is identified as an element or attribute of + * type {@code ref:swaRef} specified in + * <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html#Referencing_Attachments_from_the_SOAP_Envelope"> + * Section 4.4 Referencing Attachments from the SOAP Envelope</a> + * </li> + * </ul> + * + * @author Marc Hadley + * @author Kohsuke Kawaguchi + * @author Joseph Fialli + * + * @since 1.6, JAXB 2.0 + * + * @see jakarta.xml.bind.Unmarshaller#setAttachmentUnmarshaller(AttachmentUnmarshaller) + * + * @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">XML-binary Optimized Packaging</a> + * @see <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html">WS-I Attachments Profile Version 1.0.</a> + * @see <a href="http://www.w3.org/TR/xml-media-types/">Describing Media Content of Binary Data in XML</a> + */ +public abstract class AttachmentUnmarshaller { + + /** + * Do-nothing constructor for the derived classes. + */ + protected AttachmentUnmarshaller() {} + + /** + * <p>Lookup MIME content by content-id, {@code cid}, and return as a {@link DataHandler}.</p> + * + * <p>The returned {@code DataHandler} instance must be configured + * to meet the following required mapping constraint. + * <table class="striped"> + * <caption>Required Mappings between MIME and Java Types</caption> + * <thead> + * <tr> + * <th scope="col">MIME Type</th> + * <th scope="col">Java Type</th> + * </tr> + * <tr> + * <th scope="col">{@code DataHandler.getContentType()}</th> + * <th scope="col">{@code instanceof DataHandler.getContent()}</th> + * </tr> + * </thead> + * <tbody style="text-align:left"> + * <tr> + * <th scope="row">image/gif</th> + * <td>java.awt.Image</td> + * </tr> + * <tr> + * <th scope="row">image/jpeg</th> + * <td>java.awt.Image</td> + * </tr> + * <tr> + * <th scope="row">text/xml or application/xml</th> + * <td>javax.xml.transform.Source</td> + * </tr> + * </tbody> + * </table> + * Note that it is allowable to support additional mappings. + * + * @param cid It is expected to be a valid lexical form of the XML Schema + * {@code xs:anyURI} datatype. If {@link #isXOPPackage()}{@code ==true}, + * it must be a valid URI per the {@code cid:} URI scheme (see <a href="http://www.ietf.org/rfc/rfc2387.txt">RFC 2387</a>) + * + * @return + * a {@link DataHandler} that represents the MIME attachment. + * + * @throws IllegalArgumentException if the attachment for the given cid is not found. + */ + public abstract DataHandler getAttachmentAsDataHandler(String cid); + + /** + * <p>Retrieve the attachment identified by content-id, {@code cid}, as a {@code byte[]}. + * + * @param cid It is expected to be a valid lexical form of the XML Schema + * {@code xs:anyURI} datatype. If {@link #isXOPPackage()}{@code ==true}, + * it must be a valid URI per the {@code cid:} URI scheme (see <a href="http://www.ietf.org/rfc/rfc2387.txt">RFC 2387</a>) + * + * @return byte[] representation of attachment identified by cid. + * + * @throws IllegalArgumentException if the attachment for the given cid is not found. + */ + public abstract byte[] getAttachmentAsByteArray(String cid); + + /** + * <p>Read-only property that returns true if Jakarta XML Binding unmarshaller needs to perform XOP processing.</p> + * + * <p>This method returns {@code true} when the constraints specified + * in <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/#identifying_xop_documents">Identifying XOP Documents</a> are met. + * This value must not change during the unmarshalling process.</p> + * + * @return true when MIME context is a XOP Document. + */ + public boolean isXOPPackage() { return false; } +} + +
diff --git a/api/src/main/java/jakarta/xml/bind/attachment/package-info.java b/api/src/main/java/jakarta/xml/bind/attachment/package-info.java new file mode 100644 index 0000000..ceafa64 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/attachment/package-info.java
@@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, 2023 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * This package is implemented by a MIME-based package processor that + * enables the interpretation and creation of optimized binary data + * within an MIME-based package format. + * <p> + * Soap MTOM[1], XOP([2][3]) and WS-I AP[4] standardize approaches to + * optimized transmission of binary datatypes as an attachment. + * To optimally support these standards within a message passing + * environment, this package enables an integrated solution between + * a MIME-based package processor and Jakarta XML Binding unmarshall/marshal processes. + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * <ul> + * <li><a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Specification project</a> + * </ul> + * <h2>Related Standards</h2> + * <ul> + * <li><a href="http://www.w3.org/TR/2004/WD-soap12-mtom-20040608/">[1]SOAP Message Transmission Optimization Mechanism</a> </li> + * <li><a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">[2]XML-binary Optimized Packaging</a></li> + * <li><a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html">[3]WS-I Attachments Profile Version 1.0.</a></li> + * <li><a href="http://www.w3.org/TR/xml-media-types/">[4]Describing Media Content of Binary Data in XML</a></li> + * </ul> + * + * @see <a href="http://www.w3.org/TR/2004/WD-soap12-mtom-20040608/">[1]SOAP Message Transmission Optimization Mechanism</a> + * @see <a href="http://www.w3.org/TR/2005/REC-xop10-20050125/">[2]XML-binary Optimized Packaging</a> + * @see <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html">[3]WS-I Attachments Profile Version 1.0.</a> + * @see <a href="http://www.w3.org/TR/xml-media-types/">[4]Describing Media Content of Binary Data in XML</a> + * @since JAXB 2.0 + */ +package jakarta.xml.bind.attachment;
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/AbstractMarshallerImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/AbstractMarshallerImpl.java new file mode 100644 index 0000000..d90c6d8 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/AbstractMarshallerImpl.java
@@ -0,0 +1,505 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.PropertyException; +import jakarta.xml.bind.ValidationEventHandler; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.attachment.AttachmentMarshaller; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamResult; +import javax.xml.validation.Schema; +import java.io.UnsupportedEncodingException; +import java.io.File; +import java.io.OutputStream; +import java.io.FileOutputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +// J2SE1.4 feature +// import java.nio.charset.Charset; +// import java.nio.charset.UnsupportedCharsetException; + +/** + * Partial default {@code Marshaller} implementation. + * + * <p> + * This class provides a partial default implementation for the + * {@link jakarta.xml.bind.Marshaller} interface. + * + * <p> + * The only methods that a Jakarta XML Binding Provider has to implement are + * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.transform.Result)}, + * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.stream.XMLStreamWriter)}, and + * {@link Marshaller#marshal(Object, javax.xml.transform.Result) marshal(Object, javax.xml.stream.XMLEventWriter)}. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.Marshaller + * @since 1.6, JAXB 1.0 + */ +public abstract class AbstractMarshallerImpl implements Marshaller +{ + /** handler that will be used to process errors and warnings during marshal */ + private ValidationEventHandler eventHandler = + new DefaultValidationEventHandler(); + + //J2SE1.4 feature + //private Charset encoding = null; + + /** store the value of the encoding property. */ + private String encoding = "UTF-8"; + + /** store the value of the schemaLocation property. */ + private String schemaLocation = null; + + /** store the value of the noNamespaceSchemaLocation property. */ + private String noNSSchemaLocation = null; + + /** store the value of the formattedOutput property. */ + private boolean formattedOutput = false; + + /** store the value of the fragment property. */ + private boolean fragment = false; + + /** + * Do-nothing constructor for the derived classes. + */ + protected AbstractMarshallerImpl() {} + + @Override + public final void marshal( Object obj, java.io.OutputStream os ) + throws JAXBException { + + checkNotNull( obj, "obj", os, "os" ); + marshal( obj, new StreamResult(os) ); + } + + @Override + public void marshal(Object jaxbElement, File output) throws JAXBException { + checkNotNull(jaxbElement, "jaxbElement", output, "output" ); + try { + try (OutputStream os = new BufferedOutputStream(new FileOutputStream(output))) { + marshal(jaxbElement, new StreamResult(os)); + } + } catch (IOException e) { + throw new JAXBException(e); + } + } + + @Override + public final void marshal( Object obj, java.io.Writer w ) + throws JAXBException { + + checkNotNull( obj, "obj", w, "writer" ); + marshal( obj, new StreamResult(w) ); + } + + @Override + public final void marshal( Object obj, org.xml.sax.ContentHandler handler ) + throws JAXBException { + + checkNotNull( obj, "obj", handler, "handler" ); + marshal( obj, new SAXResult(handler) ); + } + + @Override + public final void marshal( Object obj, org.w3c.dom.Node node ) + throws JAXBException { + + checkNotNull( obj, "obj", node, "node" ); + marshal( obj, new DOMResult(node) ); + } + + /** + * By default, the getNode method is unsupported and throw + * an {@link java.lang.UnsupportedOperationException}. + * <p> + * Implementations that choose to support this method must + * override this method. + */ + @Override + public org.w3c.dom.Node getNode( Object obj ) throws JAXBException { + + checkNotNull( obj, "obj", Boolean.TRUE, "foo" ); + + throw new UnsupportedOperationException(); + } + + /** + * Convenience method for getting the current output encoding. + * + * @return the current encoding or "UTF-8" if it hasn't been set. + */ + protected String getEncoding() { + return encoding; + } + + /** + * Convenience method for setting the output encoding. + * + * @param encoding a valid encoding as specified in the Marshaller class + * documentation + */ + protected void setEncoding( String encoding ) { + this.encoding = encoding; + } + + /** + * Convenience method for getting the current schemaLocation. + * + * @return the current schemaLocation or null if it hasn't been set + */ + protected String getSchemaLocation() { + return schemaLocation; + } + + /** + * Convenience method for setting the schemaLocation. + * + * @param location the schemaLocation value + */ + protected void setSchemaLocation( String location ) { + schemaLocation = location; + } + + /** + * Convenience method for getting the current noNamespaceSchemaLocation. + * + * @return the current noNamespaceSchemaLocation or null if it hasn't + * been set + */ + protected String getNoNSSchemaLocation() { + return noNSSchemaLocation; + } + + /** + * Convenience method for setting the noNamespaceSchemaLocation. + * + * @param location the noNamespaceSchemaLocation value + */ + protected void setNoNSSchemaLocation( String location ) { + noNSSchemaLocation = location; + } + + /** + * Convenience method for getting the formatted output flag. + * + * @return the current value of the formatted output flag or false if + * it hasn't been set. + */ + protected boolean isFormattedOutput() { + return formattedOutput; + } + + /** + * Convenience method for setting the formatted output flag. + * + * @param v value of the formatted output flag. + */ + protected void setFormattedOutput( boolean v ) { + formattedOutput = v; + } + + + /** + * Convenience method for getting the fragment flag. + * + * @return the current value of the fragment flag or false if + * it hasn't been set. + */ + protected boolean isFragment() { + return fragment; + } + + /** + * Convenience method for setting the fragment flag. + * + * @param v value of the fragment flag. + */ + protected void setFragment( boolean v ) { + fragment = v; + } + + + static String[] aliases = { + "UTF-8", "UTF8", + "UTF-16", "Unicode", + "UTF-16BE", "UnicodeBigUnmarked", + "UTF-16LE", "UnicodeLittleUnmarked", + "US-ASCII", "ASCII", + "TIS-620", "TIS620", + + // taken from the project-X parser + "ISO-10646-UCS-2", "Unicode", + + "EBCDIC-CP-US", "cp037", + "EBCDIC-CP-CA", "cp037", + "EBCDIC-CP-NL", "cp037", + "EBCDIC-CP-WT", "cp037", + + "EBCDIC-CP-DK", "cp277", + "EBCDIC-CP-NO", "cp277", + "EBCDIC-CP-FI", "cp278", + "EBCDIC-CP-SE", "cp278", + + "EBCDIC-CP-IT", "cp280", + "EBCDIC-CP-ES", "cp284", + "EBCDIC-CP-GB", "cp285", + "EBCDIC-CP-FR", "cp297", + + "EBCDIC-CP-AR1", "cp420", + "EBCDIC-CP-HE", "cp424", + "EBCDIC-CP-BE", "cp500", + "EBCDIC-CP-CH", "cp500", + + "EBCDIC-CP-ROECE", "cp870", + "EBCDIC-CP-YU", "cp870", + "EBCDIC-CP-IS", "cp871", + "EBCDIC-CP-AR2", "cp918", + + // IANA also defines two that JDK 1.2 doesn't handle: + // EBCDIC-CP-GR --> CP423 + // EBCDIC-CP-TR --> CP905 + }; + + /** + * Gets the corresponding Java encoding name from an IANA name. + * <p> + * This method is a helper method for the derived class to convert + * encoding names. + * + * @exception UnsupportedEncodingException + * If this implementation couldn't find the Java encoding name. + */ + protected String getJavaEncoding( String encoding ) throws UnsupportedEncodingException { + try { + "1".getBytes(encoding); + return encoding; + } catch( UnsupportedEncodingException e ) { + // try known alias + for( int i=0; i<aliases.length; i+=2 ) { + if(encoding.equals(aliases[i])) { + "1".getBytes(aliases[i+1]); + return aliases[i+1]; + } + } + + throw new UnsupportedEncodingException(encoding); + } + /* J2SE1.4 feature + try { + this.encoding = Charset.forName( _encoding ); + } catch( UnsupportedCharsetException uce ) { + throw new JAXBException( uce ); + } + */ + } + + /** + * Default implementation of the setProperty method handles + * the four defined properties in Marshaller. If a provider + * needs to handle additional properties, it should override + * this method in a derived class. + */ + @Override + public void setProperty( String name, Object value ) + throws PropertyException { + + if( name == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); + } + + // recognize and handle four pre-defined properties. + if( JAXB_ENCODING.equals(name) ) { + checkString( name, value ); + setEncoding( (String)value ); + return; + } + if( JAXB_FORMATTED_OUTPUT.equals(name) ) { + checkBoolean( name, value ); + setFormattedOutput((Boolean) value ); + return; + } + if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) ) { + checkString( name, value ); + setNoNSSchemaLocation( (String)value ); + return; + } + if( JAXB_SCHEMA_LOCATION.equals(name) ) { + checkString( name, value ); + setSchemaLocation( (String)value ); + return; + } + if( JAXB_FRAGMENT.equals(name) ) { + checkBoolean(name, value); + setFragment((Boolean) value ); + return; + } + + throw new PropertyException(name, value); + } + + /** + * Default implementation of the getProperty method handles + * the four defined properties in Marshaller. If a provider + * needs to support additional provider specific properties, + * it should override this method in a derived class. + */ + @Override + public Object getProperty( String name ) + throws PropertyException { + + if( name == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); + } + + // recognize and handle four pre-defined properties. + if( JAXB_ENCODING.equals(name) ) + return getEncoding(); + if( JAXB_FORMATTED_OUTPUT.equals(name) ) + return isFormattedOutput()?Boolean.TRUE:Boolean.FALSE; + if( JAXB_NO_NAMESPACE_SCHEMA_LOCATION.equals(name) ) + return getNoNSSchemaLocation(); + if( JAXB_SCHEMA_LOCATION.equals(name) ) + return getSchemaLocation(); + if( JAXB_FRAGMENT.equals(name) ) + return isFragment()?Boolean.TRUE:Boolean.FALSE; + + throw new PropertyException(name); + } + /** + * @see jakarta.xml.bind.Marshaller#getEventHandler() + */ + @Override + public ValidationEventHandler getEventHandler() throws JAXBException { + return eventHandler; + } + + /** + * @see jakarta.xml.bind.Marshaller#setEventHandler(ValidationEventHandler) + */ + @Override + public void setEventHandler(ValidationEventHandler handler) + throws JAXBException { + + if( handler == null ) { + eventHandler = new DefaultValidationEventHandler(); + } else { + eventHandler = handler; + } + } + + + + + /* + * assert that the given object is a Boolean + */ + private void checkBoolean( String name, Object value ) throws PropertyException { + if(!(value instanceof Boolean)) + throw new PropertyException( + Messages.format( Messages.MUST_BE_BOOLEAN, name ) ); + } + + /* + * assert that the given object is a String + */ + private void checkString( String name, Object value ) throws PropertyException { + if(!(value instanceof String)) + throw new PropertyException( + Messages.format( Messages.MUST_BE_STRING, name ) ); + } + + /* + * assert that the parameters are not null + */ + private void checkNotNull( Object o1, String o1Name, + Object o2, String o2Name ) { + + if( o1 == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, o1Name ) ); + } + if( o2 == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, o2Name ) ); + } + } + + @Override + public void marshal(Object obj, XMLEventWriter writer) + throws JAXBException { + + throw new UnsupportedOperationException(); + } + + @Override + public void marshal(Object obj, XMLStreamWriter writer) + throws JAXBException { + + throw new UnsupportedOperationException(); + } + + @Override + public void setSchema(Schema schema) { + throw new UnsupportedOperationException(); + } + + @Override + public Schema getSchema() { + throw new UnsupportedOperationException(); + } + + @Override + @SuppressWarnings("unchecked") + public <A extends XmlAdapter<?, ?>> void setAdapter(A adapter) { + if (adapter==null) { + throw new IllegalArgumentException(); + } + setAdapter((Class<A>)adapter.getClass(),adapter); + } + + @Override + public <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter) { + throw new UnsupportedOperationException(); + } + + @Override + public <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type) { + throw new UnsupportedOperationException(); + } + + @Override + public void setAttachmentMarshaller(AttachmentMarshaller am) { + throw new UnsupportedOperationException(); + } + + @Override + public AttachmentMarshaller getAttachmentMarshaller() { + throw new UnsupportedOperationException(); + } + + @Override + public void setListener(Listener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public Listener getListener() { + throw new UnsupportedOperationException(); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/AbstractUnmarshallerImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/AbstractUnmarshallerImpl.java new file mode 100644 index 0000000..4c6a71a --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/AbstractUnmarshallerImpl.java
@@ -0,0 +1,415 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.w3c.dom.Node; + +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.PropertyException; +import jakarta.xml.bind.UnmarshalException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.ValidationEventHandler; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; +import jakarta.xml.bind.attachment.AttachmentUnmarshaller; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.Reader; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import java.net.URL; + +/** + * Partial default {@code Unmarshaller} implementation. + * + * <p> + * This class provides a partial default implementation for the + * {@link jakarta.xml.bind.Unmarshaller} interface. + * + * <p> + * A Jakarta XML Binding Provider has to implement five methods getUnmarshallerHandler(), + * unmarshal(Node), unmarshal(XMLReader,InputSource), + * unmarshal(XMLStreamReader), and unmarshal(XMLEventReader). + * + * @author <ul> + * <li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li> + * </ul> + * @see jakarta.xml.bind.Unmarshaller + * @since 1.6, JAXB 1.0 + */ +public abstract class AbstractUnmarshallerImpl implements Unmarshaller +{ + /** handler that will be used to process errors and warnings during unmarshal */ + private ValidationEventHandler eventHandler = + new DefaultValidationEventHandler(); + + /** + * XMLReader that will be used to parse a document. + */ + private XMLReader reader = null; + + /** + * Do-nothing constructor for the derived classes. + */ + protected AbstractUnmarshallerImpl() {} + + private SAXParserFactory parserFactory; + + private SAXParserFactory getSAXParserFactory() { + if (null == parserFactory) { + parserFactory = SAXParserFactory.newInstance(); + parserFactory.setNamespaceAware(true); + // there is no point in asking a validation because + // there is no guarantee that the document will come with + // a proper schemaLocation. + parserFactory.setValidating(false); + } + return parserFactory; + } + /** + * Obtains a configured XMLReader. + * <p> + * This method is used when the client-specified + * {@link SAXSource} object doesn't have XMLReader. + * <p> + * {@link Unmarshaller} is not re-entrant, so we will + * only use one instance of XMLReader. + */ + protected XMLReader getXMLReader() throws JAXBException { + if(reader==null) { + try { + reader = getSAXParserFactory().newSAXParser().getXMLReader(); + } catch( ParserConfigurationException | SAXException e ) { + throw new JAXBException(e); + } + } + return reader; + } + + @Override + public Object unmarshal( Source source ) throws JAXBException { + if( source == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "source" ) ); + } + + if(source instanceof SAXSource) + return unmarshal( (SAXSource)source ); + if(source instanceof StreamSource) + return unmarshal( streamSourceToInputSource((StreamSource)source)); + if(source instanceof DOMSource) + return unmarshal( ((DOMSource)source).getNode() ); + + // we don't handle other types of Source + throw new IllegalArgumentException(); + } + + // use the client specified XMLReader contained in the SAXSource. + private Object unmarshal( SAXSource source ) throws JAXBException { + + XMLReader r = source.getXMLReader(); + if( r == null ) + r = getXMLReader(); + + return unmarshal( r, source.getInputSource() ); + } + + /** + * Unmarshalls an object by using the specified XMLReader and the InputSource. + * <p> + * The callee should call the setErrorHandler method of the XMLReader + * so that errors are passed to the client-specified ValidationEventHandler. + */ + protected abstract Object unmarshal( XMLReader reader, InputSource source ) throws JAXBException; + + @Override + public final Object unmarshal( InputSource source ) throws JAXBException { + if( source == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "source" ) ); + } + + return unmarshal( getXMLReader(), source ); + } + + + private Object unmarshal( String url ) throws JAXBException { + return unmarshal( new InputSource(url) ); + } + + @Override + public final Object unmarshal( URL url ) throws JAXBException { + if( url == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "url" ) ); + } + + return unmarshal( url.toExternalForm() ); + } + + @Override + public final Object unmarshal( File f ) throws JAXBException { + if( f == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "file" ) ); + } + + try { + return unmarshal(new BufferedInputStream(new FileInputStream(f))); + } catch( FileNotFoundException e ) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + @Override + public final Object unmarshal( java.io.InputStream is ) + throws JAXBException { + + if( is == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "is" ) ); + } + + InputSource isrc = new InputSource( is ); + return unmarshal( isrc ); + } + + @Override + public final Object unmarshal( Reader reader ) throws JAXBException { + if( reader == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "reader" ) ); + } + + InputSource isrc = new InputSource( reader ); + return unmarshal( isrc ); + } + + + private static InputSource streamSourceToInputSource( StreamSource ss ) { + InputSource is = new InputSource(); + is.setSystemId( ss.getSystemId() ); + is.setByteStream( ss.getInputStream() ); + is.setCharacterStream( ss.getReader() ); + + return is; + } + + + /** + * Allow an application to register a validation event handler. + * <p> + * The validation event handler will be called by the Jakarta XML Binding Provider if any + * validation errors are encountered during calls to any of the + * {@code unmarshal} methods. If the client application does not register + * a validation event handler before invoking the unmarshal methods, then + * all validation events will be silently ignored and may result in + * unexpected behaviour. + * + * @param handler the validation event handler + * @throws JAXBException if an error was encountered while setting the + * event handler + */ + @Override + public void setEventHandler(ValidationEventHandler handler) + throws JAXBException { + + if( handler == null ) { + eventHandler = new DefaultValidationEventHandler(); + } else { + eventHandler = handler; + } + } + + + /** + * Return the current event handler or the default event handler if one + * hasn't been set. + * + * @return the current ValidationEventHandler or the default event handler + * if it hasn't been set + * @throws JAXBException if an error was encountered while getting the + * current event handler + */ + @Override + public ValidationEventHandler getEventHandler() throws JAXBException { + return eventHandler; + } + + + /** + * Creates an UnmarshalException from a SAXException. + * <p> + * This is a utility method provided for the derived classes. + * + * <p> + * When a provider-implemented ContentHandler wants to throw a + * JAXBException, it needs to wrap the exception by a SAXException. + * If the unmarshaller implementation blindly wrap SAXException + * by JAXBException, such an exception will be a JAXBException + * wrapped by a SAXException wrapped by another JAXBException. + * This is silly. + * + * <p> + * This method checks the nested exception to SAXException + * and reduce those excessive wrapping. + * + * @return the resulting UnmarshalException + */ + protected UnmarshalException createUnmarshalException( SAXException e ) { + // check the nested exception to see if it's an UnmarshalException + Exception nested = e.getException(); + if(nested instanceof UnmarshalException) + return (UnmarshalException)nested; + + if(nested instanceof RuntimeException) + // typically this is an unexpected exception, + // just throw it rather than wrap it, so that the full stack + // trace can be displayed. + throw (RuntimeException)nested; + + + // otherwise simply wrap it + if(nested!=null) + return new UnmarshalException(nested); + else + return new UnmarshalException(e); + } + + /** + * Default implementation of the setProperty method always + * throws PropertyException since there are no required + * properties. If a provider needs to handle additional + * properties, it should override this method in a derived class. + */ + @Override + public void setProperty( String name, Object value ) + throws PropertyException { + + if( name == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); + } + + throw new PropertyException(name, value); + } + + /** + * Default implementation of the getProperty method always + * throws PropertyException since there are no required + * properties. If a provider needs to handle additional + * properties, it should override this method in a derived class. + */ + @Override + public Object getProperty( String name ) + throws PropertyException { + + if( name == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "name" ) ); + } + + throw new PropertyException(name); + } + + @Override + public Object unmarshal(XMLEventReader reader) throws JAXBException { + + throw new UnsupportedOperationException(); + } + + @Override + public Object unmarshal(XMLStreamReader reader) throws JAXBException { + + throw new UnsupportedOperationException(); + } + + @Override + public <T> JAXBElement<T> unmarshal(Node node, Class<T> expectedType) throws JAXBException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> JAXBElement<T> unmarshal(Source source, Class<T> expectedType) throws JAXBException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> JAXBElement<T> unmarshal(XMLStreamReader reader, Class<T> expectedType) throws JAXBException { + throw new UnsupportedOperationException(); + } + + @Override + public <T> JAXBElement<T> unmarshal(XMLEventReader reader, Class<T> expectedType) throws JAXBException { + throw new UnsupportedOperationException(); + } + + @Override + public void setSchema(Schema schema) { + throw new UnsupportedOperationException(); + } + + @Override + public Schema getSchema() { + throw new UnsupportedOperationException(); + } + + @Override + @SuppressWarnings("unchecked") + public <A extends XmlAdapter<?, ?>> void setAdapter(A adapter) { + if(adapter==null) { + throw new IllegalArgumentException(); + } + setAdapter((Class<A>) adapter.getClass(),adapter); + } + + @Override + public <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter) { + throw new UnsupportedOperationException(); + } + + @Override + public <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type) { + throw new UnsupportedOperationException(); + } + + @Override + public void setAttachmentUnmarshaller(AttachmentUnmarshaller au) { + throw new UnsupportedOperationException(); + } + + @Override + public AttachmentUnmarshaller getAttachmentUnmarshaller() { + throw new UnsupportedOperationException(); + } + + @Override + public void setListener(Listener listener) { + throw new UnsupportedOperationException(); + } + + @Override + public Listener getListener() { + throw new UnsupportedOperationException(); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/DefaultValidationEventHandler.java b/api/src/main/java/jakarta/xml/bind/helpers/DefaultValidationEventHandler.java new file mode 100644 index 0000000..beb654a --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/DefaultValidationEventHandler.java
@@ -0,0 +1,119 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import org.w3c.dom.Node; + +import jakarta.xml.bind.ValidationEvent; +import jakarta.xml.bind.ValidationEventHandler; +import jakarta.xml.bind.ValidationEventLocator; +import java.net.URL; + +/** + * <p> + * JAXB 1.0 only default validation event handler. This is the default + * handler for all objects created from a JAXBContext that is managing + * schema-derived code generated by a JAXB 1.0 binding compiler. + * + * <p> + * This handler causes the unmarshal and validate operations to fail on the first + * error or fatal error. + * + * <p> + * This handler is not the default handler for Jakarta XML Binding mapped classes following + * Jakarta XML Binding or later versions. Default validation event handling has changed + * and is specified in {@link jakarta.xml.bind.Unmarshaller} and + * {@link jakarta.xml.bind.Marshaller}. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.Unmarshaller + * @see jakarta.xml.bind.ValidationEventHandler + * @since 1.6, JAXB 1.0 + */ +public class DefaultValidationEventHandler implements ValidationEventHandler { + + public DefaultValidationEventHandler() {} + + @Override + public boolean handleEvent( ValidationEvent event ) { + + if( event == null ) { + throw new IllegalArgumentException(); + } + + // calculate the severity prefix and return value + String severity = null; + boolean retVal = false; + switch ( event.getSeverity() ) { + case ValidationEvent.WARNING: + severity = Messages.format( Messages.WARNING ); + retVal = true; // continue after warnings + break; + case ValidationEvent.ERROR: + severity = Messages.format( Messages.ERROR ); + retVal = false; // terminate after errors + break; + case ValidationEvent.FATAL_ERROR: + severity = Messages.format( Messages.FATAL_ERROR ); + retVal = false; // terminate after fatal errors + break; + default: + assert false : + Messages.format( Messages.UNRECOGNIZED_SEVERITY, + event.getSeverity() ); + } + + // calculate the location message + String location = getLocation( event ); + + System.out.println( + Messages.format( Messages.SEVERITY_MESSAGE, + severity, + event.getMessage(), + location ) ); + + // fail on the first error or fatal error + return retVal; + } + + /** + * Calculate a location message for the event + * + */ + private String getLocation(ValidationEvent event) { + StringBuilder msg = new StringBuilder(); + + ValidationEventLocator locator = event.getLocator(); + + if( locator != null ) { + + URL url = locator.getURL(); + Object obj = locator.getObject(); + Node node = locator.getNode(); + int line = locator.getLineNumber(); + + if( url!=null || line!=-1 ) { + msg.append("line ").append(line); + if( url!=null ) + msg.append(" of ").append(url); + } else if( obj != null ) { + msg.append(" obj: ").append(obj); + } else if( node != null ) { + msg.append(" node: ").append(node); + } + } else { + msg.append( Messages.format( Messages.LOCATION_UNAVAILABLE ) ); + } + + return msg.toString(); + } +} +
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/Messages.java b/api/src/main/java/jakarta/xml/bind/helpers/Messages.java new file mode 100644 index 0000000..2b5ad09 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/Messages.java
@@ -0,0 +1,82 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +/** + * Formats error messages. + */ +class Messages +{ + static String format( String property ) { + return format( property, null ); + } + + static String format( String property, Object arg1 ) { + return format( property, new Object[]{arg1} ); + } + + static String format( String property, Object arg1, Object arg2 ) { + return format( property, new Object[]{arg1,arg2} ); + } + + static String format( String property, Object arg1, Object arg2, Object arg3 ) { + return format( property, new Object[]{arg1,arg2,arg3} ); + } + + // add more if necessary. + + /** Loads a string resource and formats it with specified arguments. */ + static String format( String property, Object[] args ) { + String text = ResourceBundle.getBundle(Messages.class.getName()).getString(property); + return MessageFormat.format(text,args); + } + +// +// +// Message resources +// +// + static final String INPUTSTREAM_NOT_NULL = // 0 args + "AbstractUnmarshallerImpl.ISNotNull"; + + static final String MUST_BE_BOOLEAN = // 1 arg + "AbstractMarshallerImpl.MustBeBoolean"; + + static final String MUST_BE_STRING = // 1 arg + "AbstractMarshallerImpl.MustBeString"; + + static final String SEVERITY_MESSAGE = // 3 args + "DefaultValidationEventHandler.SeverityMessage"; + + static final String LOCATION_UNAVAILABLE = // 0 args + "DefaultValidationEventHandler.LocationUnavailable"; + + static final String UNRECOGNIZED_SEVERITY = // 1 arg + "DefaultValidationEventHandler.UnrecognizedSeverity"; + + static final String WARNING = // 0 args + "DefaultValidationEventHandler.Warning"; + + static final String ERROR = // 0 args + "DefaultValidationEventHandler.Error"; + + static final String FATAL_ERROR = // 0 args + "DefaultValidationEventHandler.FatalError"; + + static final String ILLEGAL_SEVERITY = // 0 args + "ValidationEventImpl.IllegalSeverity"; + + static final String MUST_NOT_BE_NULL = // 1 arg + "Shared.MustNotBeNull"; +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/NotIdentifiableEventImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/NotIdentifiableEventImpl.java new file mode 100644 index 0000000..f673c62 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/NotIdentifiableEventImpl.java
@@ -0,0 +1,69 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import jakarta.xml.bind.ValidationEventLocator; + +/** + * Default implementation of the NotIdentifiableEvent interface. + * + * <p> + * Jakarta XML Binding providers are allowed to use whatever class that implements + * the ValidationEvent interface. This class is just provided for a + * convenience. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.NotIdentifiableEvent + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class NotIdentifiableEventImpl + extends ValidationEventImpl + implements jakarta.xml.bind.NotIdentifiableEvent { + + /** + * Create a new NotIdentifiableEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public NotIdentifiableEventImpl( int _severity, String _message, + ValidationEventLocator _locator) { + + super(_severity, _message, _locator); + } + + /** + * Create a new NotIdentifiableEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @param _linkedException An optional linked exception that may provide + * additional information about the event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public NotIdentifiableEventImpl( int _severity, String _message, + ValidationEventLocator _locator, + Throwable _linkedException) { + + super(_severity, _message, _locator, _linkedException); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/ParseConversionEventImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/ParseConversionEventImpl.java new file mode 100644 index 0000000..034eb92 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/ParseConversionEventImpl.java
@@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import jakarta.xml.bind.ParseConversionEvent; +import jakarta.xml.bind.ValidationEventLocator; + +/** + * Default implementation of the ParseConversionEvent interface. + * + * <p> + * Jakarta XML Binding providers are allowed to use whatever class that implements + * the ValidationEvent interface. This class is just provided for a + * convenience. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.ParseConversionEvent + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class ParseConversionEventImpl + extends ValidationEventImpl + implements ParseConversionEvent { + + /** + * Create a new ParseConversionEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public ParseConversionEventImpl( int _severity, String _message, + ValidationEventLocator _locator) { + + super(_severity, _message, _locator); + } + + /** + * Create a new ParseConversionEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @param _linkedException An optional linked exception that may provide + * additional information about the event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public ParseConversionEventImpl( int _severity, String _message, + ValidationEventLocator _locator, + Throwable _linkedException) { + + super(_severity, _message, _locator, _linkedException); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/PrintConversionEventImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/PrintConversionEventImpl.java new file mode 100644 index 0000000..0632381 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/PrintConversionEventImpl.java
@@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import jakarta.xml.bind.PrintConversionEvent; +import jakarta.xml.bind.ValidationEventLocator; + +/** + * Default implementation of the PrintConversionEvent interface. + * + * <p> + * Jakarta XML Binding providers are allowed to use whatever class that implements + * the ValidationEvent interface. This class is just provided for a + * convenience. + * + * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.PrintConversionEvent + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class PrintConversionEventImpl + extends ValidationEventImpl + implements PrintConversionEvent { + + /** + * Create a new PrintConversionEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public PrintConversionEventImpl( int _severity, String _message, + ValidationEventLocator _locator) { + + super(_severity, _message, _locator); + } + + /** + * Create a new PrintConversionEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @param _linkedException An optional linked exception that may provide + * additional information about the event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public PrintConversionEventImpl( int _severity, String _message, + ValidationEventLocator _locator, + Throwable _linkedException) { + + super(_severity, _message, _locator, _linkedException); + } + +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventImpl.java new file mode 100644 index 0000000..03d54b2 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventImpl.java
@@ -0,0 +1,163 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import java.text.MessageFormat; + +import jakarta.xml.bind.ValidationEvent; +import jakarta.xml.bind.ValidationEventLocator; + +/** + * Default implementation of the ValidationEvent interface. + * + * <p> + * Jakarta XML Binding providers are allowed to use whatever class that implements + * the ValidationEvent interface. This class is just provided for a + * convenience. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class ValidationEventImpl implements ValidationEvent +{ + + /** + * Create a new ValidationEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public ValidationEventImpl( int _severity, String _message, + ValidationEventLocator _locator ) { + + this(_severity,_message,_locator,null); + } + + /** + * Create a new ValidationEventImpl. + * + * @param _severity The severity value for this event. Must be one of + * ValidationEvent.WARNING, ValidationEvent.ERROR, or + * ValidationEvent.FATAL_ERROR + * @param _message The text message for this event - may be null. + * @param _locator The locator object for this event - may be null. + * @param _linkedException An optional linked exception that may provide + * additional information about the event - may be null. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public ValidationEventImpl( int _severity, String _message, + ValidationEventLocator _locator, + Throwable _linkedException ) { + + setSeverity( _severity ); + this.message = _message; + this.locator = _locator; + this.linkedException = _linkedException; + } + + private int severity; + private String message; + private Throwable linkedException; + private ValidationEventLocator locator; + + @Override + public int getSeverity() { + return severity; + } + + + /** + * Set the severity field of this event. + * + * @param _severity Must be one of ValidationEvent.WARNING, + * ValidationEvent.ERROR, or ValidationEvent.FATAL_ERROR. + * @throws IllegalArgumentException if an illegal severity field is supplied + */ + public void setSeverity( int _severity ) { + + if( _severity != ValidationEvent.WARNING && + _severity != ValidationEvent.ERROR && + _severity != ValidationEvent.FATAL_ERROR ) { + throw new IllegalArgumentException( + Messages.format( Messages.ILLEGAL_SEVERITY ) ); + } + + this.severity = _severity; + } + + @Override + public String getMessage() { + return message; + } + /** + * Set the message field of this event. + * + * @param _message String message - may be null. + */ + public void setMessage( String _message ) { + this.message = _message; + } + + @Override + public Throwable getLinkedException() { + return linkedException; + } + /** + * Set the linked exception field of this event. + * + * @param _linkedException Optional linked exception - may be null. + */ + public void setLinkedException( Throwable _linkedException ) { + this.linkedException = _linkedException; + } + + @Override + public ValidationEventLocator getLocator() { + return locator; + } + /** + * Set the locator object for this event. + * + * @param _locator The locator - may be null. + */ + public void setLocator( ValidationEventLocator _locator ) { + this.locator = _locator; + } + + /** + * Returns a string representation of this object in a format + * helpful to debugging. + * + * @see Object#equals(Object) + */ + @Override + public String toString() { + String s; + switch(getSeverity()) { + case WARNING: s="WARNING";break; + case ERROR: s="ERROR";break; + case FATAL_ERROR: s="FATAL_ERROR";break; + default: s=String.valueOf(getSeverity());break; + } + return MessageFormat.format("[severity={0},message={1},locator={2}]", + s, + getMessage(), + getLocator() + ); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventLocatorImpl.java b/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventLocatorImpl.java new file mode 100644 index 0000000..4a79bd0 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/ValidationEventLocatorImpl.java
@@ -0,0 +1,264 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.helpers; + +import java.net.URL; +import java.net.MalformedURLException; +import java.text.MessageFormat; + +import jakarta.xml.bind.ValidationEventLocator; +import org.w3c.dom.Node; +import org.xml.sax.Locator; +import org.xml.sax.SAXParseException; + +/** + * Default implementation of the ValidationEventLocator interface. + * + * <p> + * Jakarta XML Binding providers are allowed to use whatever class that implements + * the ValidationEventLocator interface. This class is just provided for a + * convenience. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class ValidationEventLocatorImpl implements ValidationEventLocator +{ + /** + * Creates an object with all fields unavailable. + */ + public ValidationEventLocatorImpl() { + } + + /** + * Constructs an object from an org.xml.sax.Locator. + * <p> + * The object's ColumnNumber, LineNumber, and URL become available from the + * values returned by the locator's getColumnNumber(), getLineNumber(), and + * getSystemId() methods respectively. Node, Object, and Offset are not + * available. + * + * @param loc the SAX Locator object that will be used to populate this + * event locator. + * @throws IllegalArgumentException if the Locator is null + */ + public ValidationEventLocatorImpl( Locator loc ) { + if( loc == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "loc" ) ); + } + + this.url = toURL(loc.getSystemId()); + this.columnNumber = loc.getColumnNumber(); + this.lineNumber = loc.getLineNumber(); + } + + /** + * Constructs an object from the location information of a SAXParseException. + * <p> + * The object's ColumnNumber, LineNumber, and URL become available from the + * values returned by the locator's getColumnNumber(), getLineNumber(), and + * getSystemId() methods respectively. Node, Object, and Offset are not + * available. + * + * @param e the SAXParseException object that will be used to populate this + * event locator. + * @throws IllegalArgumentException if the SAXParseException is null + */ + public ValidationEventLocatorImpl( SAXParseException e ) { + if( e == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "e" ) ); + } + + this.url = toURL(e.getSystemId()); + this.columnNumber = e.getColumnNumber(); + this.lineNumber = e.getLineNumber(); + } + + /** + * Constructs an object that points to a DOM Node. + * <p> + * The object's Node becomes available. ColumnNumber, LineNumber, Object, + * Offset, and URL are not available. + * + * @param _node the DOM Node object that will be used to populate this + * event locator. + * @throws IllegalArgumentException if the Node is null + */ + public ValidationEventLocatorImpl(Node _node) { + if( _node == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "_node" ) ); + } + + this.node = _node; + } + + /** + * Constructs an object that points to a Jakarta XML Binding content object. + * <p> + * The object's Object becomes available. ColumnNumber, LineNumber, Node, + * Offset, and URL are not available. + * + * @param _object the Object that will be used to populate this + * event locator. + * @throws IllegalArgumentException if the Object is null + */ + public ValidationEventLocatorImpl(Object _object) { + if( _object == null ) { + throw new IllegalArgumentException( + Messages.format( Messages.MUST_NOT_BE_NULL, "_object" ) ); + } + + this.object = _object; + } + + /** Converts a system ID to a URL object. */ + private static URL toURL( String systemId ) { + try { + return new URL(systemId); + } catch( MalformedURLException e ) { + // TODO: how should we handle system id here? + return null; // for now + } + } + + private URL url = null; + private int offset = -1; + private int lineNumber = -1; + private int columnNumber = -1; + private Object object = null; + private Node node = null; + + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getURL() + */ + @Override + public URL getURL() { + return url; + } + + /** + * Set the URL field on this event locator. Null values are allowed. + * + * @param _url the url + */ + public void setURL( URL _url ) { + this.url = _url; + } + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getOffset() + */ + @Override + public int getOffset() { + return offset; + } + + /** + * Set the offset field on this event locator. + * + * @param _offset the offset + */ + public void setOffset( int _offset ) { + this.offset = _offset; + } + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getLineNumber() + */ + @Override + public int getLineNumber() { + return lineNumber; + } + + /** + * Set the lineNumber field on this event locator. + * + * @param _lineNumber the line number + */ + public void setLineNumber( int _lineNumber ) { + this.lineNumber = _lineNumber; + } + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getColumnNumber() + */ + @Override + public int getColumnNumber() { + return columnNumber; + } + + /** + * Set the columnNumber field on this event locator. + * + * @param _columnNumber the column number + */ + public void setColumnNumber( int _columnNumber ) { + this.columnNumber = _columnNumber; + } + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getObject() + */ + @Override + public Object getObject() { + return object; + } + + /** + * Set the Object field on this event locator. Null values are allowed. + * + * @param _object the java content object + */ + public void setObject( Object _object ) { + this.object = _object; + } + + /** + * @see jakarta.xml.bind.ValidationEventLocator#getNode() + */ + @Override + public Node getNode() { + return node; + } + + /** + * Set the Node field on this event locator. Null values are allowed. + * + * @param _node the Node + */ + public void setNode( Node _node ) { + this.node = _node; + } + + /** + * Returns a string representation of this object in a format + * helpful to debugging. + * + * @see Object#equals(Object) + */ + @Override + public String toString() { + return MessageFormat.format("[node={0},object={1},url={2},line={3},col={4},offset={5}]", + getNode(), + getObject(), + getURL(), + String.valueOf(getLineNumber()), + String.valueOf(getColumnNumber()), + String.valueOf(getOffset())); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/helpers/package-info.java b/api/src/main/java/jakarta/xml/bind/helpers/package-info.java new file mode 100644 index 0000000..1e4612b --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/helpers/package-info.java
@@ -0,0 +1,38 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * <B>Jakarta XML Binding Provider Use Only:</b> Provides partial default implementations for + * some of the <code>jakarta.xml.bind</code> interfaces. + * + * <p> + * Jakarta XML Binding Providers can extend these classes and implement the abstract + * methods. + * + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * + * <ul> + * <li><a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Specification project</a> + * </ul> + * + * <h2>Related Documentation</h2> + * <p> + * For overviews, tutorials, examples, guides, and tool documentation, + * please see: + * <ul> + * <li>The <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + * </ul> + * + * @see <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + */ +package jakarta.xml.bind.helpers;
diff --git a/api/src/main/java/jakarta/xml/bind/package-info.java b/api/src/main/java/jakarta/xml/bind/package-info.java new file mode 100644 index 0000000..60ba012 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/package-info.java
@@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Provides a runtime binding framework for client applications including + * unmarshalling, marshalling, and validation capabilities. + * <p> + * <code>JAXBContext</code> is the client-entry point to the runtime binding + * framework. + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * <ul> + * <li><a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Specification project</a> + * </ul> + * <h2>Related Documentation</h2> + * For overviews, tutorials, examples, guides, and tool documentation, + * please see: + * <ul> + * <li>The <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + * </ul> + * + * @see <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + */ +package jakarta.xml.bind;
diff --git a/api/src/main/java/jakarta/xml/bind/util/JAXBResult.java b/api/src/main/java/jakarta/xml/bind/util/JAXBResult.java new file mode 100644 index 0000000..4813001 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/util/JAXBResult.java
@@ -0,0 +1,134 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.util; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.UnmarshallerHandler; +import javax.xml.transform.sax.SAXResult; + +/** + * JAXP {@link javax.xml.transform.Result} implementation + * that unmarshalls a Jakarta XML Binding object. + * + * <p> + * This utility class is useful to combine Jakarta XML Binding with + * other Java/XML technologies. + * + * <p> + * The following example shows how to use Jakarta XML Binding to unmarshal a document + * resulting from an XSLT transformation. + * + * {@snippet : + * JAXBResult result = new JAXBResult( + * JAXBContext.newInstance("org.acme.foo") ); + * + * // set up XSLT transformation + * TransformerFactory tf = TransformerFactory.newInstance(); + * Transformer t = tf.newTransformer(new StreamSource("test.xsl")); + * + * // run transformation + * t.transform(new StreamSource("document.xml"),result); + * + * // obtain the unmarshalled content tree + * Object o = result.getResult(); + * } + * + * <p> + * The fact that JAXBResult derives from SAXResult is an implementation + * detail. Thus, in general applications are strongly discouraged from + * accessing methods defined on SAXResult. + * + * <p> + * In particular, it shall never attempt to call the setHandler, + * setLexicalHandler, and setSystemId methods. + * + * @author + * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * @since 1.6 + */ +public class JAXBResult extends SAXResult { + + /** + * Creates a new instance that uses the specified + * JAXBContext to unmarshal. + * + * @param context The JAXBContext that will be used to create the + * necessary Unmarshaller. This parameter must not be null. + * @exception JAXBException if an error is encountered while creating the + * JAXBResult or if the context parameter is null. + */ + public JAXBResult( JAXBContext context ) throws JAXBException { + this( ( context == null ) ? assertionFailed() : context.createUnmarshaller() ); + } + + /** + * Creates a new instance that uses the specified + * Unmarshaller to unmarshal an object. + * + * <p> + * This JAXBResult object will use the specified Unmarshaller + * instance. It is the caller's responsibility not to use the + * same Unmarshaller for other purposes while it is being + * used by this object. + * + * <p> + * The primary purpose of this method is to allow the client + * to configure Unmarshaller. Unless you know what you are doing, + * it's easier and safer to pass a JAXBContext. + * + * @param _unmarshaller the unmarshaller. This parameter must not be null. + * @throws JAXBException if an error is encountered while creating the + * JAXBResult or the Unmarshaller parameter is null. + */ + public JAXBResult( Unmarshaller _unmarshaller ) throws JAXBException { + if( _unmarshaller == null ) + throw new JAXBException( + Messages.format( Messages.RESULT_NULL_UNMARSHALLER ) ); + + this.unmarshallerHandler = _unmarshaller.getUnmarshallerHandler(); + + super.setHandler(unmarshallerHandler); + } + + /** + * Unmarshaller that will be used to unmarshal + * the input documents. + */ + private final UnmarshallerHandler unmarshallerHandler; + + /** + * Gets the unmarshalled object created by the transformation. + * + * @return + * Always return a non-null object. + * + * @exception IllegalStateException + * if this method is called before an object is unmarshalled. + * + * @exception JAXBException + * if there is any unmarshalling error. + * Note that the implementation is allowed to throw SAXException + * during the parsing when it finds an error. + */ + public Object getResult() throws JAXBException { + return unmarshallerHandler.getResult(); + } + + /** + * Hook to throw exception from the middle of a constructor chained call + * to this + */ + private static Unmarshaller assertionFailed() throws JAXBException { + throw new JAXBException( Messages.format( Messages.RESULT_NULL_CONTEXT ) ); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/util/JAXBSource.java b/api/src/main/java/jakarta/xml/bind/util/JAXBSource.java new file mode 100644 index 0000000..495b716 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/util/JAXBSource.java
@@ -0,0 +1,270 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.util; + +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXParseException; +import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.helpers.XMLFilterImpl; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import javax.xml.transform.sax.SAXSource; +import org.xml.sax.XMLFilter; + +/** + * JAXP {@link javax.xml.transform.Source} implementation + * that marshals a Jakarta XML Binding-generated object. + * + * <p> + * This utility class is useful to combine Jakarta XML Binding with + * other Java/XML technologies. + * + * <p> + * The following example shows how to use Jakarta XML Binding to marshal a document + * for transformation by XSLT. + * + * {@snippet : + * MyObject o = // get JAXB content tree + * + * // jaxbContext is a JAXBContext object from which 'o' is created. + * JAXBSource source = new JAXBSource( jaxbContext, o ); + * + * // set up XSLT transformation + * TransformerFactory tf = TransformerFactory.newInstance(); + * Transformer t = tf.newTransformer(new StreamSource("test.xsl")); + * + * // run transformation + * t.transform(source,new StreamResult(System.out)); + * } + * + * <p> + * The fact that JAXBSource derives from SAXSource is an implementation + * detail. Thus, in general applications are strongly discouraged from + * accessing methods defined on SAXSource. In particular, + * the setXMLReader and setInputSource methods shall never be called. + * The XMLReader object obtained by the getXMLReader method shall + * be used only for parsing the InputSource object returned by + * the getInputSource method. + * + * <p> + * Similarly, the InputSource object obtained by the getInputSource + * method shall be used only for being parsed by the XMLReader object + * returned by the getXMLReader. + * + * @author + * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) + * @since 1.6 + */ +public class JAXBSource extends SAXSource { + + /** + * Creates a new {@link javax.xml.transform.Source} for the given content object. + * + * @param context + * JAXBContext that was used to create + * <code>contentObject</code>. This context is used + * to create a new instance of marshaller and must not be null. + * @param contentObject + * An instance of a Jakarta XML Binding-generated class, which will be + * used as a {@link javax.xml.transform.Source} (by marshalling it into XML). It must + * not be null. + * @throws JAXBException if an error is encountered while creating the + * JAXBSource or if either of the parameters are null. + */ + public JAXBSource( JAXBContext context, Object contentObject ) + throws JAXBException { + + this( + ( context == null ) ? + assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTEXT ) ) : + context.createMarshaller(), + + ( contentObject == null ) ? + assertionFailed( Messages.format( Messages.SOURCE_NULL_CONTENT ) ) : + contentObject); + } + + /** + * Creates a new {@link javax.xml.transform.Source} for the given content object. + * + * @param marshaller + * A marshaller instance that will be used to marshal + * <code>contentObject</code> into XML. This must be + * created from a JAXBContext that was used to build + * <code>contentObject</code> and must not be null. + * @param contentObject + * An instance of a Jakarta XML Binding-generated class, which will be + * used as a {@link javax.xml.transform.Source} (by marshalling it into XML). It must + * not be null. + * @throws JAXBException if an error is encountered while creating the + * JAXBSource or if either of the parameters are null. + */ + public JAXBSource( Marshaller marshaller, Object contentObject ) + throws JAXBException { + + if( marshaller == null ) + throw new JAXBException( + Messages.format( Messages.SOURCE_NULL_MARSHALLER ) ); + + if( contentObject == null ) + throw new JAXBException( + Messages.format( Messages.SOURCE_NULL_CONTENT ) ); + + this.marshaller = marshaller; + this.contentObject = contentObject; + + super.setXMLReader(pseudoParser); + // pass a dummy InputSource. We don't care + super.setInputSource(new InputSource()); + } + + private final Marshaller marshaller; + private final Object contentObject; + + // this object will pretend as an XMLReader. + // no matter what parameter is specified to the parse method, + // it just parses the contentObject. + private final XMLReader pseudoParser = new XMLReader() { + @Override + public boolean getFeature(String name) throws SAXNotRecognizedException { + if(name.equals("http://xml.org/sax/features/namespaces")) + return true; + if(name.equals("http://xml.org/sax/features/namespace-prefixes")) + return false; + throw new SAXNotRecognizedException(name); + } + + @Override + public void setFeature(String name, boolean value) throws SAXNotRecognizedException { + if(name.equals("http://xml.org/sax/features/namespaces") && value) + return; + if(name.equals("http://xml.org/sax/features/namespace-prefixes") && !value) + return; + throw new SAXNotRecognizedException(name); + } + + @Override + public Object getProperty(String name) throws SAXNotRecognizedException { + if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) { + return lexicalHandler; + } + throw new SAXNotRecognizedException(name); + } + + @Override + public void setProperty(String name, Object value) throws SAXNotRecognizedException { + if( "http://xml.org/sax/properties/lexical-handler".equals(name) ) { + this.lexicalHandler = (LexicalHandler)value; + return; + } + throw new SAXNotRecognizedException(name); + } + + private LexicalHandler lexicalHandler; + + // we will store this value but never use it by ourselves. + private EntityResolver entityResolver; + @Override + public void setEntityResolver(EntityResolver resolver) { + this.entityResolver = resolver; + } + @Override + public EntityResolver getEntityResolver() { + return entityResolver; + } + + private DTDHandler dtdHandler; + @Override + public void setDTDHandler(DTDHandler handler) { + this.dtdHandler = handler; + } + @Override + public DTDHandler getDTDHandler() { + return dtdHandler; + } + + // SAX allows ContentHandler to be changed during the parsing, + // but JAXB doesn't. So this repeater will sit between those + // two components. + private XMLFilter repeater = new XMLFilterImpl(); + + @Override + public void setContentHandler(ContentHandler handler) { + repeater.setContentHandler(handler); + } + @Override + public ContentHandler getContentHandler() { + return repeater.getContentHandler(); + } + + private ErrorHandler errorHandler; + @Override + public void setErrorHandler(ErrorHandler handler) { + this.errorHandler = handler; + } + @Override + public ErrorHandler getErrorHandler() { + return errorHandler; + } + + @Override + public void parse(InputSource input) throws SAXException { + parse(); + } + + @Override + public void parse(String systemId) throws SAXException { + parse(); + } + + public void parse() throws SAXException { + // parses a content object by using the given marshaller + // SAX events will be sent to the repeater, and the repeater + // will further forward it to an appropriate component. + try { + marshaller.marshal( contentObject, (XMLFilterImpl)repeater ); + } catch( JAXBException e ) { + // wrap it to a SAXException + SAXParseException se = + new SAXParseException( e.getMessage(), + null, null, -1, -1, e ); + + // if the consumer sets an error handler, it is our responsibility + // to notify it. + if(errorHandler!=null) + errorHandler.fatalError(se); + + // this is a fatal error. Even if the error handler + // returns, we will abort anyway. + throw se; + } + } + }; + + /** + * Hook to throw exception from the middle of a constructor chained call + * to this + */ + private static Marshaller assertionFailed( String message ) + throws JAXBException { + + throw new JAXBException( message ); + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/util/Messages.java b/api/src/main/java/jakarta/xml/bind/util/Messages.java new file mode 100644 index 0000000..ce7db2e --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/util/Messages.java
@@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.util; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +/** + * Formats error messages. + */ +class Messages +{ + static String format( String property ) { + return format( property, null ); + } + + static String format( String property, Object arg1 ) { + return format( property, new Object[]{arg1} ); + } + + static String format( String property, Object arg1, Object arg2 ) { + return format( property, new Object[]{arg1,arg2} ); + } + + static String format( String property, Object arg1, Object arg2, Object arg3 ) { + return format( property, new Object[]{arg1,arg2,arg3} ); + } + + // add more if necessary. + + /** Loads a string resource and formats it with specified arguments. */ + static String format( String property, Object[] args ) { + String text = ResourceBundle.getBundle(Messages.class.getName()).getString(property); + return MessageFormat.format(text,args); + } + +// +// +// Message resources +// +// + static final String UNRECOGNIZED_SEVERITY = // 1 arg + "ValidationEventCollector.UnrecognizedSeverity"; + + static final String RESULT_NULL_CONTEXT = // 0 args + "JAXBResult.NullContext"; + + static final String RESULT_NULL_UNMARSHALLER = // 0 arg + "JAXBResult.NullUnmarshaller"; + + static final String SOURCE_NULL_CONTEXT = // 0 args + "JAXBSource.NullContext"; + + static final String SOURCE_NULL_CONTENT = // 0 arg + "JAXBSource.NullContent"; + + static final String SOURCE_NULL_MARSHALLER = // 0 arg + "JAXBSource.NullMarshaller"; + +}
diff --git a/api/src/main/java/jakarta/xml/bind/util/ValidationEventCollector.java b/api/src/main/java/jakarta/xml/bind/util/ValidationEventCollector.java new file mode 100644 index 0000000..b5d33f0 --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/util/ValidationEventCollector.java
@@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.util; + +import jakarta.xml.bind.ValidationEvent; +import jakarta.xml.bind.ValidationEventHandler; +import java.util.ArrayList; +import java.util.List; + +/** + * {@link jakarta.xml.bind.ValidationEventHandler ValidationEventHandler} + * implementation that collects all events. + * + * <p> + * To use this class, create a new instance and pass it to the setEventHandler + * method of the Unmarshaller, Marshaller class. After the call to + * validate or unmarshal completes, call the getEvents method to retrieve all + * the reported errors and warnings. + * + * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul> + * @see jakarta.xml.bind.ValidationEventHandler + * @see jakarta.xml.bind.ValidationEvent + * @see jakarta.xml.bind.ValidationEventLocator + * @since 1.6, JAXB 1.0 + */ +public class ValidationEventCollector implements ValidationEventHandler +{ + private final List<ValidationEvent> events = new ArrayList<>(); + + public ValidationEventCollector() {} + + /** + * Return an array of ValidationEvent objects containing a copy of each of + * the collected errors and warnings. + * + * @return + * a copy of all the collected errors and warnings or an empty array + * if there weren't any + */ + public ValidationEvent[] getEvents() { + return events.toArray(new ValidationEvent[0]); + } + + /** + * Clear all collected errors and warnings. + */ + public void reset() { + events.clear(); + } + + /** + * Returns true if this event collector contains at least one + * ValidationEvent. + * + * @return true if this event collector contains at least one + * ValidationEvent, false otherwise + */ + public boolean hasEvents() { + return !events.isEmpty(); + } + + @Override + public boolean handleEvent( ValidationEvent event ) { + events.add(event); + + boolean retVal = true; + switch( event.getSeverity() ) { + case ValidationEvent.WARNING: + case ValidationEvent.ERROR: + retVal = true; // continue validation + break; + case ValidationEvent.FATAL_ERROR: + retVal = false; // halt validation + break; + default: + _assert( false, + Messages.format( Messages.UNRECOGNIZED_SEVERITY, + event.getSeverity() ) ); + break; + } + + return retVal; + } + + private static void _assert( boolean b, String msg ) { + if( !b ) { + throw new InternalError( msg ); + } + } +}
diff --git a/api/src/main/java/jakarta/xml/bind/util/package-info.java b/api/src/main/java/jakarta/xml/bind/util/package-info.java new file mode 100644 index 0000000..3a3195a --- /dev/null +++ b/api/src/main/java/jakarta/xml/bind/util/package-info.java
@@ -0,0 +1,33 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Useful client utility classes. + * + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + * + * <h2>Package Specification</h2> + * + * <ul> + * <li><a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Specification project</a> + * </ul> + * + * <h2>Related Documentation</h2> + * <p> + * For overviews, tutorials, examples, guides, and tool documentation, + * please see: + * <ul> + * <li>The <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + * </ul> + * + * @see <a href="https://projects.eclipse.org/projects/ee4j.jaxb">Jakarta XML Binding Website</a> + */ +package jakarta.xml.bind.util;
diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java new file mode 100644 index 0000000..e6a54b9 --- /dev/null +++ b/api/src/main/java/module-info.java
@@ -0,0 +1,30 @@ +/* + * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Jakarta XML Binding API. + * + * <p> + * References in this document to JAXB refer to the Jakarta XML Binding unless otherwise noted. + */ +module jakarta.xml.bind { + requires transitive jakarta.activation; + requires transitive java.xml; + requires java.logging; + + exports jakarta.xml.bind; + exports jakarta.xml.bind.annotation; + exports jakarta.xml.bind.annotation.adapters; + exports jakarta.xml.bind.attachment; + exports jakarta.xml.bind.helpers; + exports jakarta.xml.bind.util; + + uses jakarta.xml.bind.JAXBContextFactory; +}
diff --git a/api/src/main/javadoc/doc-files/speclicense.html b/api/src/main/javadoc/doc-files/speclicense.html new file mode 100644 index 0000000..ba29e5e --- /dev/null +++ b/api/src/main/javadoc/doc-files/speclicense.html
@@ -0,0 +1,72 @@ +<html> +<head> +<title>Eclipse Foundation Specification License - v1.0</title> +</head> +<body> +<h1>Eclipse Foundation Specification License - v1.0</h1> +<p>By using and/or copying this document, or the Eclipse Foundation + document from which this statement is linked, you (the licensee) agree + that you have read, understood, and will comply with the following + terms and conditions:</p> + +<p>Permission to copy, and distribute the contents of this document, or + the Eclipse Foundation document from which this statement is linked, in + any medium for any purpose and without fee or royalty is hereby + granted, provided that you include the following on ALL copies of the + document, or portions thereof, that you use:</p> + +<ul> + <li> link or URL to the original Eclipse Foundation document.</li> + <li>All existing copyright notices, or if one does not exist, a notice + (hypertext is preferred, but a textual representation is permitted) + of the form: "Copyright © [$date-of-document] + “Eclipse Foundation, Inc. <<url to this license>> + " + </li> +</ul> + +<p>Inclusion of the full text of this NOTICE must be provided. We + request that authorship attribution be provided in any software, + documents, or other items or products that you create pursuant to the + implementation of the contents of this document, or any portion + thereof.</p> + +<p>No right to create modifications or derivatives of Eclipse Foundation + documents is granted pursuant to this license, except anyone may + prepare and distribute derivative works and portions of this document + in software that implements the specification, in supporting materials + accompanying such software, and in documentation of such software, + PROVIDED that all such works include the notice below. HOWEVER, the + publication of derivative works of this document for use as a technical + specification is expressly prohibited.</p> + +<p>The notice is:</p> + +<p>"Copyright © 2018 Eclipse Foundation. This software or + document includes material copied from or derived from [title and URI + of the Eclipse Foundation specification document]."</p> + +<h2>Disclaimers</h2> + +<p>THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT + HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE + SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS + WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR + OTHER RIGHTS.</p> + +<p>THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE + FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT + OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE + CONTENTS THEREOF.</p> + +<p>The name and trademarks of the copyright holders or the Eclipse + Foundation may NOT be used in advertising or publicity pertaining to + this document or its contents without specific, written prior + permission. Title to copyright in this document will at all times + remain with copyright holders.</p> + +</body> +</html>
diff --git a/api/src/main/resources/jakarta/xml/bind/Messages.properties b/api/src/main/resources/jakarta/xml/bind/Messages.properties new file mode 100644 index 0000000..4ca44f6 --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/Messages.properties
@@ -0,0 +1,48 @@ +# +# Copyright (c) 2003, 2024 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +ContextFinder.ProviderNotFound = \ + Provider {0} not found + +ContextFinder.DefaultProviderNotFound = \ + Implementation of Jakarta XML Binding-API has not been found on module path or classpath. + +ContextFinder.CouldNotInstantiate = \ + Provider {0} could not be instantiated: {1} + +ContextFinder.CantFindPropertiesFile = \ + Unable to locate jaxb.properties for package {0} + +ContextFinder.CantMixProviders = \ + You may not mix Jakarta XML Binding Providers on the context path + +ContextFinder.MissingProperty = \ + jaxb.properties in package {0} does not contain the {1} property. + +ContextFinder.NoPackageInContextPath = \ + No package name is given + +ContextFinder.ErrorLoadClass = \ + Error loading class {0} listed in {1}, make sure that entries are accessible \ + on CLASSPATH and of the form ClassName or OuterClass.InnerClass \ + not ClassName.class or fully.qualified.ClassName + +PropertyException.NameValue = \ + name: {0} value: {1} + +DatatypeConverter.ConverterMustNotBeNull = \ + The DatatypeConverterInterface parameter must not be null + +JAXBContext.IllegalCast = \ + ClassCastException: attempting to cast {0} to {1}. Please make sure that you are specifying the proper ClassLoader. + +JAXBClasses.notOpen = \ + Package {0} with Jakarta XML Binding class {1} defined in a module {2} must be open to at least jakarta.xml.bind module.
diff --git a/api/src/main/resources/jakarta/xml/bind/bindingschema_1_0.xsd b/api/src/main/resources/jakarta/xml/bind/bindingschema_1_0.xsd new file mode 100644 index 0000000..cea2bc3 --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/bindingschema_1_0.xsd
@@ -0,0 +1,419 @@ +<?xml version = "1.0" encoding = "UTF-8"?> +<!-- + + Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<xs:schema + targetNamespace = "http://java.sun.com/xml/ns/jaxb" + xmlns:jaxb = "http://java.sun.com/xml/ns/jaxb" + xmlns:xs = "http://www.w3.org/2001/XMLSchema" + elementFormDefault = "qualified" + attributeFormDefault = "unqualified"> + <xs:annotation> + <xs:documentation>Schema for binding schema. JAXB Version 1.0</xs:documentation> + </xs:annotation> + <xs:group name = "declaration"> + <xs:annotation> + <xs:documentation> + Model group that represents a binding declaration. + Each new binding declaration added to the jaxb namespace + that is not restricted to globalBindings should + be added as a child element to this model group. + + </xs:documentation> + <xs:documentation> + Allow for extension binding declarations. + + </xs:documentation> + </xs:annotation> + <!-- each new binding declaration, not restricted to + globalBindings, should be added here --> + <xs:choice> + <xs:element ref = "jaxb:globalBindings"/> + <xs:element ref = "jaxb:schemaBindings"/> + <xs:element ref = "jaxb:class"/> + <xs:element ref = "jaxb:property"/> + <xs:element ref = "jaxb:typesafeEnumClass"/> + <xs:element ref = "jaxb:typesafeEnumMember"/> + <xs:element ref = "jaxb:javaType"/> + <xs:any namespace = "##other" processContents = "lax"/> + </xs:choice> + </xs:group> + <xs:attribute name = "version" type="xs:token" > + <xs:annotation> + <xs:documentation> + Used to specify the version of the binding schema on the + schema element for inline annotations or jaxb:bindings + for external binding. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attributeGroup name = "propertyAttributes"> + <xs:annotation> + <xs:documentation>Attributes used for property customization. The attribute group + can be referenced either from the globalBindings declaration or from the + property declaration. + The following defaults are defined by the JAXB specification in global + scope only. Thus they apply when the propertyAttributes group is referenced + from the globalBindings declaration but not when referenced from the + property declaration. + collectionType a class that implements java.util.List. The + class is JAXB implementation dependent. + fixedAttributeAsConstantProperty false + enableFailFastCheck false + generateIsSetMethod false + </xs:documentation> + </xs:annotation> + <xs:attribute name = "collectionType" type="jaxb:referenceCollectionType"/> + <xs:attribute name = "fixedAttributeAsConstantProperty" type = "xs:boolean"/> + <xs:attribute name = "enableFailFastCheck" type = "xs:boolean"/> + <xs:attribute name = "generateIsSetMethod" type = "xs:boolean"/> + </xs:attributeGroup> + <xs:attributeGroup name = "XMLNameToJavaIdMappingDefaults"> + <xs:annotation> + <xs:documentation>Customize XMlNames to Java id mapping </xs:documentation> + </xs:annotation> + <xs:attribute name = "underscoreBinding" default = "asWordSeparator" type = "jaxb:underscoreBindingType"/> + <xs:attribute name = "typesafeEnumMemberName" default = "generateError" type = "jaxb:typesafeEnumMemberNameType"/> + </xs:attributeGroup> + <xs:attributeGroup name = "typesafeEnumClassDefaults"> + <xs:attribute name = "typesafeEnumBase" default = "xs:NCname" type = "jaxb:typesafeEnumBaseType"/> + </xs:attributeGroup> + <xs:element name = "globalBindings"> + <xs:annotation> + <xs:documentation>Customization values defined in global scope.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence minOccurs = "0"> + <xs:element ref = "jaxb:javaType" minOccurs = "0" maxOccurs = "unbounded"/> + <xs:any namespace = "##other" processContents = "lax"> + <xs:annotation> + <xs:documentation> + allows extension binding declarations to be specified. + </xs:documentation> + </xs:annotation> + </xs:any> + </xs:sequence> + <xs:attributeGroup ref = "jaxb:XMLNameToJavaIdMappingDefaults"/> + <xs:attributeGroup ref = "jaxb:typesafeEnumClassDefaults"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + <xs:attribute name = "enableJavaNamingConventions" default = "true" type = "xs:boolean"/> + <xs:attribute name = "bindingStyle" default = "elementBinding" type = "jaxb:bindingStyleType"/> + <xs:attribute name = "choiceContentProperty" default = "false" type = "xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name = "schemaBindings"> + <xs:annotation> + <xs:documentation>Customization values with schema scope</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "package" type = "jaxb:packageType" minOccurs = "0"/> + <xs:element name = "nameXmlTransform" type = "jaxb:nameXmlTransformType" minOccurs = "0"/> + </xs:all> + </xs:complexType> + </xs:element> + <xs:element name = "class"> + <xs:annotation> + <xs:documentation>Customize interface and implementation class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Java class name without package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "implClass" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Implementation class name including package prefix. </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "property"> + <xs:annotation> + <xs:documentation>Customize property.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "javadoc" type = "xs:string" minOccurs="0"/> + <xs:element name = "baseType" type="jaxb:propertyBaseType" minOccurs="0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + </xs:complexType> + </xs:element> + <xs:element name = "javaType"> + <xs:annotation> + <xs:documentation>Data type conversions; overriding builtins</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>name of the java type to which xml type is to be bound.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "xmlType" type = "xs:QName"> + <xs:annotation> + <xs:documentation> xml type to which java datatype has to be bound. + Must be present when javaType is scoped to globalBindings + + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "parseMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "printMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "hasNsContext" default = "false" type = "xs:boolean" > + <xs:annotation> + <xs:documentation> + If true, the parsMethod and printMethod must reference a method + signtature that has a second parameter of type NamespaceContext. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumClass"> + <xs:annotation> + <xs:documentation> Bind to a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + <xs:element ref = "jaxb:typesafeEnumMember" minOccurs = "0" maxOccurs = "unbounded"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumMember"> + <xs:annotation> + <xs:documentation> Enumeration member name in a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "value" type="xs:anySimpleType"/> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + </xs:element> + + <!-- TYPE DEFINITIONS --> + + <xs:complexType name = "propertyBaseType"> + <xs:annotation> + <xs:documentation> + Customize the base type of a property. For V1.0, only + javaType is allowed for customization of simple types + at point of reference to a simple type. + </xs:documentation> + </xs:annotation> + <xs:all> + <xs:element ref = "jaxb:javaType" minOccurs = "0"/> + </xs:all> + </xs:complexType> + + <xs:simpleType name = "bindingStyleType"> + <xs:annotation> + <xs:documentation>Allows selection of a binding algorithm</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "elementBinding"/> + <xs:enumeration value = "modelGroupBinding"/> + </xs:restriction> + </xs:simpleType> + + <xs:complexType name = "packageType"> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + <xs:simpleType name = "underscoreBindingType"> + <xs:annotation> + <xs:documentation>Treate underscore in XML Name to Java identifier mapping. </xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "asWordSeparator"/> + <xs:enumeration value = "asCharInWord"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumBaseType"> + <xs:annotation> + <xs:documentation> + XML types or types derived from them which have enumeration facet(s) + which are be mapped to typesafeEnumClass by default. + The following types cannot be specified in this list: + "xsd:QName", "xsd:base64Binary", "xsd:hexBinary", + "xsd:date", "xsd:time", "xsd:dateTime", "xsd:duration", + "xsd:gDay", "xsd:gMonth", "xsd:Year", "xsd:gMonthDay", "xsd:YearMonth" + </xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:QName"/> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumMemberNameType"> + <xs:annotation> + <xs:documentation>Used to customize how to handle name collisions. + i. generate VALUE_1, VALUE_2... if generateName. + ii. generate an error if value is generateError. This is JAXB default behavior. + + </xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "generateName"/> + <xs:enumeration value = "generateError"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "javaIdentifierType"> + <xs:annotation> + <xs:documentation>Placeholder type to indicate Legal Java identifier.</xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:NCName"/> + </xs:simpleType> + <xs:complexType name = "nameXmlTransformRule"> + <xs:annotation> + <xs:documentation>Rule to transform an Xml name into another Xml name</xs:documentation> + </xs:annotation> + <xs:attribute name = "prefix" type = "xs:string"> + <xs:annotation> + <xs:documentation>prepend the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "suffix" type = "xs:string"> + <xs:annotation> + <xs:documentation>Append the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name = "nameXmlTransformType"> + <xs:annotation> + <xs:documentation> + Allows transforming an xml name into another xml name. Use case UDDI 2.0 schema. + + </xs:documentation> + </xs:annotation> + <xs:all> + <xs:element name = "typeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for type definitions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "elementName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for elements</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "modelGroupName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for model group</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "anonymousTypeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for class names generated for an anonymous type.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:all> + </xs:complexType> + <xs:attribute name = "extensionBindingPrefixes"> + <xs:annotation> + <xs:documentation> + A binding compiler only processes this attribute when it occurs on an + an instance of xs:schema element. The value of this attribute is a + whitespace-separated list of namespace prefixes. The namespace bound + to each of the prefixes is designated as a customization declaration + namespace. + + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:list itemType = "xs:normalizedString"/> + </xs:simpleType> + </xs:attribute> + <xs:element name = "bindings"> + <xs:annotation> + <xs:documentation> + Binding declaration(s) for a remote schema. + If attribute node is set, the binding declaraions + are associated with part of the remote schema + designated by schemaLocation attribute. The node + attribute identifies the node in the remote schema + to associate the binding declaration(s) with. + + </xs:documentation> + </xs:annotation> + <!-- a <bindings> element can contain arbitrary number of binding declarations or nested <bindings> elements --> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs = "0" maxOccurs = "unbounded"> + <xs:group ref = "jaxb:declaration"/> + <xs:element ref = "jaxb:bindings"/> + </xs:choice> + </xs:sequence> + <xs:attribute name = "schemaLocation" type = "xs:anyURI"> + <xs:annotation> + <xs:documentation> + Location of the remote schema to associate binding declarations with. + + + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "node" type = "xs:string"> + <xs:annotation> + <xs:documentation> + The value of the string is an XPATH 1.0 compliant string that + resolves to a node in a remote schema to associate + binding declarations with. The remote schema is specified + by the schemaLocation attribute occuring in the current + element or in a parent of this element. + + + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "version" type = "xs:token"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. + Only valid on root level bindings element. + Either this or "jaxb:version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute ref = "jaxb:version"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. + Only valid on root level bindings element. + Either this attribute or "version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:simpleType name="referenceCollectionType"> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="indexed"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="jaxb:javaIdentifierType"/> + </xs:simpleType> + </xs:union> + </xs:simpleType> +</xs:schema> +
diff --git a/api/src/main/resources/jakarta/xml/bind/bindingschema_2_0.xsd b/api/src/main/resources/jakarta/xml/bind/bindingschema_2_0.xsd new file mode 100644 index 0000000..e1b67a2 --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/bindingschema_2_0.xsd
@@ -0,0 +1,460 @@ +<?xml version = "1.0" encoding = "UTF-8"?> +<!-- + + Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<xs:schema + targetNamespace = "http://java.sun.com/xml/ns/jaxb" + xmlns:jaxb = "http://java.sun.com/xml/ns/jaxb" + xmlns:xs = "http://www.w3.org/2001/XMLSchema" + elementFormDefault = "qualified" + attributeFormDefault = "unqualified"> + <xs:annotation> + <xs:documentation> + Schema for JAXB 2.0 binding declarations. + </xs:documentation> + </xs:annotation> + <xs:group name = "declaration"> + <xs:annotation> + <xs:documentation> + Model group that represents a binding declaration. Each new binding + declaration added to the jaxb namespace that is not restricted to + globalBindings should be added as a child element to this model group. + </xs:documentation> + </xs:annotation> + <!-- each new binding declaration, not restricted to + globalBindings, should be added here --> + <xs:choice> + <xs:element ref = "jaxb:globalBindings"/> + <xs:element ref = "jaxb:schemaBindings"/> + <xs:element ref = "jaxb:class"/> + <xs:element ref = "jaxb:property"/> + <xs:element ref = "jaxb:typesafeEnumClass"/> + <xs:element ref = "jaxb:typesafeEnumMember"/> + <xs:element ref = "jaxb:javaType"/> + <xs:element ref = "jaxb:dom"/> + <xs:element ref = "jaxb:inlineBinaryData"/> + <xs:any namespace = "##other" processContents = "lax"/> + </xs:choice> + </xs:group> + <xs:attribute name = "version" type="xs:token" > + <xs:annotation> + <xs:documentation> + Used to specify the version of the binding schema on the schema element for + inline annotations or jaxb:bindings for external binding. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attributeGroup name = "propertyAttributes"> + <xs:annotation><xs:documentation> + Attributes used for property customization. The attribute group can be + referenced either from the globalBindings declaration or from the + property declaration. The following defaults are defined by the JAXB + specification in global scope only. Thus they apply when the + propertyAttributes group is referenced from the globalBindings declaration + but not when referenced from the property declaration. + collectionType a class that implements java.util.List. + fixedAttributeAsConstantProperty false + enableFailFastCheck false + generateIsSetMethod false + optionalProperty wrapper + generateElementProperty false + attachmentRef default + </xs:documentation></xs:annotation> + <xs:attribute name = "collectionType" type="jaxb:referenceCollectionType"/> + <xs:attribute name = "fixedAttributeAsConstantProperty" type = "xs:boolean"/> + <xs:attribute name = "enableFailFastCheck" type = "xs:boolean"/> + <xs:attribute name = "generateIsSetMethod" type = "xs:boolean"/> + <xs:attribute name = "optionalProperty"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="wrapper"/> + <xs:enumeration value="primitive"/> + <xs:enumeration value="isSet"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "generateElementProperty" type="xs:boolean"/> + <xs:attribute name = "attachmentRef"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="resolve"/> + <xs:enumeration value="doNotResolve"/> + <xs:enumeration value="default"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:attributeGroup name = "XMLNameToJavaIdMappingDefaults"> + <xs:annotation> + <xs:documentation>Customize XMLNames to Java id mapping + </xs:documentation> + </xs:annotation> + <xs:attribute name = "underscoreBinding" default = "asWordSeparator" type = "jaxb:underscoreBindingType"/> + </xs:attributeGroup> + <xs:attributeGroup name = "typesafeEnumClassDefaults"> + <xs:attribute name = "typesafeEnumMemberName" default = "skipGeneration" type = "jaxb:typesafeEnumMemberNameType"/> + <xs:attribute name = "typesafeEnumBase" default = "xs:string" type = "jaxb:typesafeEnumBaseType"/> + <xs:attribute name = "typesafeEnumMaxMembers" type="xs:int" default="256"/> + </xs:attributeGroup> + <xs:element name = "globalBindings"> + <xs:annotation> + <xs:documentation>Customization values defined in global scope.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence minOccurs = "0"> + <xs:element ref = "jaxb:javaType" minOccurs = "0" maxOccurs = "unbounded"/> + <xs:element ref = "jaxb:serializable" minOccurs = "0"/> + <xs:any namespace = "##other" processContents = "lax"> + <xs:annotation> + <xs:documentation>allows extension binding declarations to be specified.</xs:documentation> + </xs:annotation> + </xs:any> + </xs:sequence> + <xs:attributeGroup ref = "jaxb:XMLNameToJavaIdMappingDefaults"/> + <xs:attributeGroup ref = "jaxb:typesafeEnumClassDefaults"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + <xs:attribute name="generateValueClass" type="xs:boolean" + default= "true"/> + <xs:attribute name="generateElementClass" type="xs:boolean" + default= "false"/> + <xs:attribute name="mapSimpleTypeDef" type="xs:boolean" + default= "false"/> + <xs:attribute name="localScoping" default= "nested"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="nested"/> + <xs:enumeration value="toplevel"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "enableJavaNamingConventions" default = "true" type = "xs:boolean"/> + <!-- Removed from JAXB 2.0 + <xs:attribute name = "bindingStyle" default = "elementBinding" type = "jaxb:bindingStyleType"/> + --> + <xs:attribute name = "choiceContentProperty" default = "false" type = "xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name = "schemaBindings"> + <xs:annotation> + <xs:documentation>Customization values with schema scope</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "package" type = "jaxb:packageType" minOccurs = "0"/> + <xs:element name = "nameXmlTransform" type = "jaxb:nameXmlTransformType" minOccurs = "0"/> + </xs:all> + </xs:complexType> + </xs:element> + <xs:element name = "class"> + <xs:annotation> + <xs:documentation>Customize interface and implementation class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Java class name without package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "implClass" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Implementation class name including package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="generateValueClass" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Default value derived from [jaxb:globalBindings]@generateValueClass.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "property"> + <xs:annotation> + <xs:documentation>Customize property.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "javadoc" type = "xs:string" minOccurs="0"/> + <xs:element name = "baseType" type="jaxb:propertyBaseType" minOccurs="0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + </xs:complexType> + </xs:element> + <xs:element name = "javaType"> + <xs:annotation> + <xs:documentation>Data type conversions; overriding builtins</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>name of the java type to which xml type is to be bound.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "xmlType" type = "xs:QName"> + <xs:annotation> + <xs:documentation> xml type to which java datatype has to be bound.Must be present when javaType is scoped to globalBindings</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "parseMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "printMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "hasNsContext" default = "false" type = "xs:boolean" > + <xs:annotation> + <xs:documentation> + If true, the parsMethod and printMethod must reference a method + signtature that has a second parameter of type NamespaceContext. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumClass"> + <xs:annotation> + <xs:documentation> Bind to a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + <xs:element ref = "jaxb:typesafeEnumMember" minOccurs = "0" maxOccurs = "unbounded"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "map" type = "xs:boolean" default = "true"/> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumMember"> + <xs:annotation> + <xs:documentation> Enumeration member name in a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "value" type="xs:anySimpleType"/> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + </xs:element> + + <!-- TYPE DEFINITIONS --> + + <xs:complexType name = "propertyBaseType"> + <xs:all> + <xs:element ref = "jaxb:javaType" minOccurs = "0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation> + The name attribute for [baseType] enables more precise control over the actual base type for a JAXB property. This customization enables specifying a more general base type than the property's default base type. The name attribute value must be a fully qualified Java class name. Additionally, this Java class must be a super interface/class of the default Java base type for the property. When the default base type is a primitive type, consider the default Java base type to be the Java wrapper class of that primitive type.This customization is useful to enable simple type substitution for a JAXB property representing with too restrictive of a default base type. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <!-- Removed in JAXB 2.0. modelGroupBinding no longer exists. + <xs:simpleType name = "bindingStyleType"> + <xs:annotation><xs:documentation>Allows selection of a binding algorithm</xs:documentation></xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "elementBinding"/> + <xs:enumeration value = "modelGroupBinding"/> + </xs:restriction> + </xs:simpleType> + --> + + <xs:complexType name = "packageType"> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + <xs:simpleType name = "underscoreBindingType"> + <xs:annotation> + <xs:documentation>Treate underscore in XML Name to Java identifier mapping.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "asWordSeparator"/> + <xs:enumeration value = "asCharInWord"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumBaseType"> + <xs:annotation> + <xs:documentation> + XML types or types derived from them which have enumeration facet(s) + which are be mapped to typesafeEnumClass by default. + The following types cannot be specified in this list: + "xsd:QName", "xsd:base64Binary", "xsd:hexBinary", + "xsd:date", "xsd:time", "xsd:dateTime", "xsd:duration", + "xsd:gDay", "xsd:gMonth", "xsd:Year", "xsd:gMonthDay", "xsd:YearMonth" + </xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:QName"/> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumMemberNameType"> + <xs:annotation> + <xs:documentation>Used to customize how to handle name collisions.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "generateName"/> + <xs:enumeration value = "generateError"/> + <xs:enumeration value = "skipGeneration"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "javaIdentifierType"> + <xs:annotation> + <xs:documentation>Placeholder type to indicate Legal Java identifier.</xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:NCName"/> + </xs:simpleType> + <xs:complexType name = "nameXmlTransformRule"> + <xs:annotation> + <xs:documentation>Rule to transform an Xml name into another Xml name</xs:documentation> + </xs:annotation> + <xs:attribute name = "prefix" type = "xs:string"> + <xs:annotation> + <xs:documentation>prepend the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "suffix" type = "xs:string"> + <xs:annotation> + <xs:documentation>Append the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name = "nameXmlTransformType"> + <xs:annotation> + <xs:documentation>Allows transforming an xml name into another xml name. Use case UDDI 2.0 schema.</xs:documentation> + </xs:annotation> + <xs:all> + <xs:element name = "typeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for type definitions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "elementName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for elements</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "modelGroupName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for model group</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "anonymousTypeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for class names generated for an anonymous type.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:all> + </xs:complexType> + <xs:attribute name = "extensionBindingPrefixes"> + <xs:annotation> + <xs:documentation> + A binding compiler only processes this attribute when it occurs on an + an instance of xs:schema element. The value of this attribute is a + whitespace-separated list of namespace prefixes. The namespace bound + to each of the prefixes is designated as a customization declaration + namespace. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:list itemType = "xs:normalizedString"/> + </xs:simpleType> + </xs:attribute> + <xs:element name = "bindings"> + <xs:annotation> + <xs:documentation> + Binding declaration(s) for a remote schema. + If attribute node is set, the binding declaraions + are associated with part of the remote schema + designated by schemaLocation attribute. The node + attribute identifies the node in the remote schema + to associate the binding declaration(s) with. + </xs:documentation> + </xs:annotation> + <!-- a <bindings> element can contain arbitrary number of binding declarations or nested <bindings> elements --> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs = "0" maxOccurs = "unbounded"> + <xs:group ref = "jaxb:declaration"/> + <xs:element ref = "jaxb:bindings"/> + </xs:choice> + </xs:sequence> + <xs:attribute name = "schemaLocation" type = "xs:anyURI"> + <xs:annotation> + <xs:documentation> + Location of the remote schema to associate binding declarations with. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "node" type = "xs:string"> + <xs:annotation> + <xs:documentation> + The value of the string is an XPATH 1.0 compliant string that + resolves to a node in a remote schema to associate + binding declarations with. The remote schema is specified + by the schemaLocation attribute occuring in the current + element or in a parent of this element. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "version" type = "xs:token"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this or "jaxb:version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute ref = "jaxb:version"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this attribute or "version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:simpleType name="referenceCollectionType"> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="indexed"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="jaxb:javaIdentifierType"/> + </xs:simpleType> + </xs:union> + </xs:simpleType> + <xs:element name="dom"> + <xs:complexType> + <xs:attribute name = "type" type="xs:NCName" default="w3c"> + <xs:annotation> + <xs:documentation>Specify DOM API to bind to JAXB property to.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name="inlineBinaryData"> + <xs:annotation> + <xs:documentation>Disable MTOM/XOP encoding for this binary data. Annotation can be placed on a type defintion that derives from a W3C XSD binary data type or on an element that has a type that is or derives from a W3C XSD binary data type.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "serializable"> + <xs:complexType> + <xs:attribute name="uid" type="xs:long" default="1"/> + </xs:complexType> + </xs:element> +</xs:schema> +
diff --git a/api/src/main/resources/jakarta/xml/bind/bindingschema_3_0.xsd b/api/src/main/resources/jakarta/xml/bind/bindingschema_3_0.xsd new file mode 100644 index 0000000..78b8750 --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/bindingschema_3_0.xsd
@@ -0,0 +1,482 @@ +<?xml version = "1.0" encoding = "UTF-8"?> +<!-- + + Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<xs:schema + targetNamespace = "https://jakarta.ee/xml/ns/jaxb" + xmlns:jaxb = "https://jakarta.ee/xml/ns/jaxb" + xmlns:xs = "http://www.w3.org/2001/XMLSchema" + elementFormDefault = "qualified" + attributeFormDefault = "unqualified"> + <xs:annotation> + <xs:documentation> + This is the XML Schema for the Jakarta XML Binding binding + customization descriptor. + All binding customization descriptors must indicate + the descriptor schema by using the Jakarta XML Binding namespace: + + https://jakarta.ee/xml/ns/jaxb + + and by indicating the version of the schema by + using the version element as shown below: + + <bindings xmlns="https://jakarta.ee/xml/ns/jaxb" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://jakarta.ee/xml/ns/jaxb + https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd" + version="3.0"> + ... + </bindings> + + The instance documents may indicate the published version of + the schema using the xsi:schemaLocation attribute for Jakarta XML Binding + namespace with the following location: + + https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd + </xs:documentation> + </xs:annotation> + <xs:group name = "declaration"> + <xs:annotation> + <xs:documentation> + Model group that represents a binding declaration. Each new binding + declaration added to the jaxb namespace that is not restricted to + globalBindings should be added as a child element to this model group. + </xs:documentation> + </xs:annotation> + <!-- each new binding declaration, not restricted to + globalBindings, should be added here --> + <xs:choice> + <xs:element ref = "jaxb:globalBindings"/> + <xs:element ref = "jaxb:schemaBindings"/> + <xs:element ref = "jaxb:class"/> + <xs:element ref = "jaxb:property"/> + <xs:element ref = "jaxb:typesafeEnumClass"/> + <xs:element ref = "jaxb:typesafeEnumMember"/> + <xs:element ref = "jaxb:javaType"/> + <xs:element ref = "jaxb:dom"/> + <xs:element ref = "jaxb:inlineBinaryData"/> + <xs:any namespace = "##other" processContents = "lax"/> + </xs:choice> + </xs:group> + <xs:attribute name = "version" type="xs:token" > + <xs:annotation> + <xs:documentation> + Used to specify the version of the binding schema on the schema element for + inline annotations or jaxb:bindings for external binding. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attributeGroup name = "propertyAttributes"> + <xs:annotation><xs:documentation> + Attributes used for property customization. The attribute group can be + referenced either from the globalBindings declaration or from the + property declaration. The following defaults are defined by the JAXB + specification in global scope only. Thus they apply when the + propertyAttributes group is referenced from the globalBindings declaration + but not when referenced from the property declaration. + collectionType a class that implements java.util.List. + fixedAttributeAsConstantProperty false + enableFailFastCheck false + generateIsSetMethod false + optionalProperty wrapper + generateElementProperty false + attachmentRef default + </xs:documentation></xs:annotation> + <xs:attribute name = "collectionType" type="jaxb:referenceCollectionType"/> + <xs:attribute name = "fixedAttributeAsConstantProperty" type = "xs:boolean"/> + <xs:attribute name = "enableFailFastCheck" type = "xs:boolean"/> + <xs:attribute name = "generateIsSetMethod" type = "xs:boolean"/> + <xs:attribute name = "optionalProperty"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="wrapper"/> + <xs:enumeration value="primitive"/> + <xs:enumeration value="isSet"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "generateElementProperty" type="xs:boolean"/> + <xs:attribute name = "attachmentRef"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="resolve"/> + <xs:enumeration value="doNotResolve"/> + <xs:enumeration value="default"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:attributeGroup name = "XMLNameToJavaIdMappingDefaults"> + <xs:annotation> + <xs:documentation>Customize XMLNames to Java id mapping + </xs:documentation> + </xs:annotation> + <xs:attribute name = "underscoreBinding" default = "asWordSeparator" type = "jaxb:underscoreBindingType"/> + </xs:attributeGroup> + <xs:attributeGroup name = "typesafeEnumClassDefaults"> + <xs:attribute name = "typesafeEnumMemberName" default = "skipGeneration" type = "jaxb:typesafeEnumMemberNameType"/> + <xs:attribute name = "typesafeEnumBase" default = "xs:string" type = "jaxb:typesafeEnumBaseType"/> + <xs:attribute name = "typesafeEnumMaxMembers" type="xs:int" default="256"/> + </xs:attributeGroup> + <xs:element name = "globalBindings"> + <xs:annotation> + <xs:documentation>Customization values defined in global scope.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence minOccurs = "0"> + <xs:element ref = "jaxb:javaType" minOccurs = "0" maxOccurs = "unbounded"/> + <xs:element ref = "jaxb:serializable" minOccurs = "0"/> + <xs:any namespace = "##other" processContents = "lax"> + <xs:annotation> + <xs:documentation>allows extension binding declarations to be specified.</xs:documentation> + </xs:annotation> + </xs:any> + </xs:sequence> + <xs:attributeGroup ref = "jaxb:XMLNameToJavaIdMappingDefaults"/> + <xs:attributeGroup ref = "jaxb:typesafeEnumClassDefaults"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + <xs:attribute name="generateValueClass" type="xs:boolean" + default= "true"/> + <xs:attribute name="generateElementClass" type="xs:boolean" + default= "false"/> + <xs:attribute name="mapSimpleTypeDef" type="xs:boolean" + default= "false"/> + <xs:attribute name="localScoping" default= "nested"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="nested"/> + <xs:enumeration value="toplevel"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "enableJavaNamingConventions" default = "true" type = "xs:boolean"/> + <!-- Removed from JAXB 2.0 + <xs:attribute name = "bindingStyle" default = "elementBinding" type = "jaxb:bindingStyleType"/> + --> + <xs:attribute name = "choiceContentProperty" default = "false" type = "xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name = "schemaBindings"> + <xs:annotation> + <xs:documentation>Customization values with schema scope</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "package" type = "jaxb:packageType" minOccurs = "0"/> + <xs:element name = "nameXmlTransform" type = "jaxb:nameXmlTransformType" minOccurs = "0"/> + </xs:all> + </xs:complexType> + </xs:element> + <xs:element name = "class"> + <xs:annotation> + <xs:documentation>Customize interface and implementation class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Java class name without package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "implClass" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Implementation class name including package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="generateValueClass" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Default value derived from [jaxb:globalBindings]@generateValueClass.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "property"> + <xs:annotation> + <xs:documentation>Customize property.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "javadoc" type = "xs:string" minOccurs="0"/> + <xs:element name = "baseType" type="jaxb:propertyBaseType" minOccurs="0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + </xs:complexType> + </xs:element> + <xs:element name = "javaType"> + <xs:annotation> + <xs:documentation>Data type conversions; overriding builtins</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>name of the java type to which xml type is to be bound.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "xmlType" type = "xs:QName"> + <xs:annotation> + <xs:documentation> xml type to which java datatype has to be bound.Must be present when javaType is scoped to globalBindings</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "parseMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "printMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "hasNsContext" default = "false" type = "xs:boolean" > + <xs:annotation> + <xs:documentation> + If true, the parsMethod and printMethod must reference a method + signtature that has a second parameter of type NamespaceContext. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumClass"> + <xs:annotation> + <xs:documentation> Bind to a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + <xs:element ref = "jaxb:typesafeEnumMember" minOccurs = "0" maxOccurs = "unbounded"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "map" type = "xs:boolean" default = "true"/> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumMember"> + <xs:annotation> + <xs:documentation> Enumeration member name in a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "value" type="xs:anySimpleType"/> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + </xs:element> + + <!-- TYPE DEFINITIONS --> + + <xs:complexType name = "propertyBaseType"> + <xs:all> + <xs:element ref = "jaxb:javaType" minOccurs = "0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation> + The name attribute for [baseType] enables more precise control over the actual base type for a JAXB property. This customization enables specifying a more general base type than the property's default base type. The name attribute value must be a fully qualified Java class name. Additionally, this Java class must be a super interface/class of the default Java base type for the property. When the default base type is a primitive type, consider the default Java base type to be the Java wrapper class of that primitive type.This customization is useful to enable simple type substitution for a JAXB property representing with too restrictive of a default base type. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <!-- Removed in JAXB 2.0. modelGroupBinding no longer exists. + <xs:simpleType name = "bindingStyleType"> + <xs:annotation><xs:documentation>Allows selection of a binding algorithm</xs:documentation></xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "elementBinding"/> + <xs:enumeration value = "modelGroupBinding"/> + </xs:restriction> + </xs:simpleType> + --> + + <xs:complexType name = "packageType"> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + <xs:simpleType name = "underscoreBindingType"> + <xs:annotation> + <xs:documentation>Treate underscore in XML Name to Java identifier mapping.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "asWordSeparator"/> + <xs:enumeration value = "asCharInWord"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumBaseType"> + <xs:annotation> + <xs:documentation> + XML types or types derived from them which have enumeration facet(s) + which are be mapped to typesafeEnumClass by default. + The following types cannot be specified in this list: + "xsd:QName", "xsd:base64Binary", "xsd:hexBinary", + "xsd:date", "xsd:time", "xsd:dateTime", "xsd:duration", + "xsd:gDay", "xsd:gMonth", "xsd:Year", "xsd:gMonthDay", "xsd:YearMonth" + </xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:QName"/> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumMemberNameType"> + <xs:annotation> + <xs:documentation>Used to customize how to handle name collisions.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "generateName"/> + <xs:enumeration value = "generateError"/> + <xs:enumeration value = "skipGeneration"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "javaIdentifierType"> + <xs:annotation> + <xs:documentation>Placeholder type to indicate Legal Java identifier.</xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:NCName"/> + </xs:simpleType> + <xs:complexType name = "nameXmlTransformRule"> + <xs:annotation> + <xs:documentation>Rule to transform an Xml name into another Xml name</xs:documentation> + </xs:annotation> + <xs:attribute name = "prefix" type = "xs:string"> + <xs:annotation> + <xs:documentation>prepend the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "suffix" type = "xs:string"> + <xs:annotation> + <xs:documentation>Append the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name = "nameXmlTransformType"> + <xs:annotation> + <xs:documentation>Allows transforming an xml name into another xml name. Use case UDDI 2.0 schema.</xs:documentation> + </xs:annotation> + <xs:all> + <xs:element name = "typeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for type definitions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "elementName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for elements</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "modelGroupName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for model group</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "anonymousTypeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for class names generated for an anonymous type.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:all> + </xs:complexType> + <xs:attribute name = "extensionBindingPrefixes"> + <xs:annotation> + <xs:documentation> + A binding compiler only processes this attribute when it occurs on an + an instance of xs:schema element. The value of this attribute is a + whitespace-separated list of namespace prefixes. The namespace bound + to each of the prefixes is designated as a customization declaration + namespace. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:list itemType = "xs:normalizedString"/> + </xs:simpleType> + </xs:attribute> + <xs:element name = "bindings"> + <xs:annotation> + <xs:documentation> + Binding declaration(s) for a remote schema. + If attribute node is set, the binding declaraions + are associated with part of the remote schema + designated by schemaLocation attribute. The node + attribute identifies the node in the remote schema + to associate the binding declaration(s) with. + </xs:documentation> + </xs:annotation> + <!-- a <bindings> element can contain arbitrary number of binding declarations or nested <bindings> elements --> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs = "0" maxOccurs = "unbounded"> + <xs:group ref = "jaxb:declaration"/> + <xs:element ref = "jaxb:bindings"/> + </xs:choice> + </xs:sequence> + <xs:attribute name = "schemaLocation" type = "xs:anyURI"> + <xs:annotation> + <xs:documentation> + Location of the remote schema to associate binding declarations with. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "node" type = "xs:string"> + <xs:annotation> + <xs:documentation> + The value of the string is an XPATH 1.0 compliant string that + resolves to a node in a remote schema to associate + binding declarations with. The remote schema is specified + by the schemaLocation attribute occuring in the current + element or in a parent of this element. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "version" type = "xs:token"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this or "jaxb:version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute ref = "jaxb:version"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this attribute or "version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:simpleType name="referenceCollectionType"> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="indexed"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="jaxb:javaIdentifierType"/> + </xs:simpleType> + </xs:union> + </xs:simpleType> + <xs:element name="dom"> + <xs:complexType> + <xs:attribute name = "type" type="xs:NCName" default="w3c"> + <xs:annotation> + <xs:documentation>Specify DOM API to bind to JAXB property to.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name="inlineBinaryData"> + <xs:annotation> + <xs:documentation>Disable MTOM/XOP encoding for this binary data. Annotation can be placed on a type defintion that derives from a W3C XSD binary data type or on an element that has a type that is or derives from a W3C XSD binary data type.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "serializable"> + <xs:complexType> + <xs:attribute name="uid" type="xs:long" default="1"/> + </xs:complexType> + </xs:element> +</xs:schema> +
diff --git a/api/src/main/resources/jakarta/xml/bind/helpers/Messages.properties b/api/src/main/resources/jakarta/xml/bind/helpers/Messages.properties new file mode 100644 index 0000000..a46de23 --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/helpers/Messages.properties
@@ -0,0 +1,47 @@ +# +# Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +AbstractUnmarshallerImpl.ISNotNull = \ + InputStream can not be null + +AbstractMarshallerImpl.MustBeBoolean = \ + {0} must be boolean + +AbstractMarshallerImpl.MustBeString = \ + {0} must be a String + + +DefaultValidationEventHandler.SeverityMessage = \ + DefaultValidationEventHandler: {0} {1} \n\ +\ \ \ \ \ Location: {2} + +DefaultValidationEventHandler.LocationUnavailable = \ + unavailable + +DefaultValidationEventHandler.UnrecognizedSeverity = \ + Unrecognized event severity field "{0}" + +DefaultValidationEventHandler.Warning = \ + [WARNING]: + +DefaultValidationEventHandler.Error = \ + [ERROR]: + +DefaultValidationEventHandler.FatalError = \ + [FATAL_ERROR]: + +ValidationEventImpl.IllegalSeverity = \ + Illegal severity + +Shared.MustNotBeNull = \ + {0} parameter must not be null + +
diff --git a/api/src/main/resources/jakarta/xml/bind/util/Messages.properties b/api/src/main/resources/jakarta/xml/bind/util/Messages.properties new file mode 100644 index 0000000..8cc5c4e --- /dev/null +++ b/api/src/main/resources/jakarta/xml/bind/util/Messages.properties
@@ -0,0 +1,29 @@ +# +# Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +ValidationEventCollector.UnrecognizedSeverity = \ + Unrecognized event severity field "{0}" + +JAXBResult.NullContext = \ + JAXBContext can not be null + +JAXBResult.NullUnmarshaller = \ + Unmarshaller can not be null + +JAXBSource.NullContext = \ + JAXBContext can not be null + +JAXBSource.NullContent = \ + Content object can not be null + +JAXBSource.NullMarshaller = \ + Marshaller can not be null +
diff --git a/api/src/test/java/org/eclipse/jaxb/api/DatatypeConverterTest.java b/api/src/test/java/org/eclipse/jaxb/api/DatatypeConverterTest.java new file mode 100644 index 0000000..b38ca39 --- /dev/null +++ b/api/src/test/java/org/eclipse/jaxb/api/DatatypeConverterTest.java
@@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package org.eclipse.jaxb.api; + +import jakarta.xml.bind.DatatypeConverter; +import org.junit.Assert; +import org.junit.Test; + +public class DatatypeConverterTest { + + @Test + public void testParseBoolean() { + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("11")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("1A")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("non")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("fals")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("falses")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("false s")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("falst")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("tru")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("trux")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("truu")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("truxx")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("truth")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("truelle")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("truec")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("true c")); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBoolean("oui")); + + + Assert.assertEquals(false, DatatypeConverter.parseBoolean("0")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean(" 0")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean(" 0 ")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean("0 ")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean("1")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean(" 1")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean(" 1 ")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean("1 ")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean("false")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean(" false")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean("false ")); + Assert.assertEquals(false, DatatypeConverter.parseBoolean(" false ")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean("true")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean(" true")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean("true ")); + Assert.assertEquals(true, DatatypeConverter.parseBoolean(" true ")); + } + + @Test + public void testPrint() { + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printInteger(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printDateTime(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printHexBinary(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printTime(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printDate(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printDecimal(null)); + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printBase64Binary(null)); + + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printShort(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printFloat(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printBoolean(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printByte(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printUnsignedInt(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printString(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printInt(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printLong(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printDouble(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printQName(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printUnsignedShort(null)); + //Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.printAnySimpleType(null)); + + } + + @Test + public void testBase64() { + Assert.assertThrows(IllegalArgumentException.class, () -> DatatypeConverter.parseBase64Binary("Qxx==")); + Assert.assertNotEquals("Hello, world!", new String(DatatypeConverter.parseBase64Binary("SGVsbG8sIJdvcmxkIQ=="))); + + Assert.assertEquals("Hello, world!", new String(DatatypeConverter.parseBase64Binary("SGVsbG8sIHdvcmxkIQ=="))); + } +}
diff --git a/etc/config/copyright-exclude b/etc/config/copyright-exclude new file mode 100644 index 0000000..b8578b6 --- /dev/null +++ b/etc/config/copyright-exclude
@@ -0,0 +1,11 @@ +.iml +.ipr +.txt +.bat +.sh +etc/config/copyright-exclude +javadoc/doc-files/speclicense.html +jaxb-api-test/src/test/resources/logging.properties +jaxb-api-test/src/test/resources/jakarta/xml/bind/test.policy +jaxb-api-test/src/test/resources/jaxb/test/usr/jaxb.index +/LICENSE.md
diff --git a/etc/config/edl-copyright.txt b/etc/config/edl-copyright.txt new file mode 100644 index 0000000..1858057 --- /dev/null +++ b/etc/config/edl-copyright.txt
@@ -0,0 +1,9 @@ +/* + * Copyright (c) YYYY Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */
diff --git a/etc/jenkins/continuous.groovy b/etc/jenkins/continuous.groovy new file mode 100644 index 0000000..6ad0643 --- /dev/null +++ b/etc/jenkins/continuous.groovy
@@ -0,0 +1,77 @@ +// Copyright (c) 2019, 2024 Oracle and/or its affiliates. All rights reserved. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Distribution License v. 1.0, which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: BSD-3-Clause + +// Job input parameters: +// SPEC_VERSION - Specification version to release +// NEXT_SPEC_VERSION - Next specification snapshot version to set (e.g. 1.2.4-SNAPSHOT) +// API_VERSION - API version to release +// NEXT_API_VERSION - Next API snapshot version to set (e.g. 1.2.4-SNAPSHOT) +// BRANCH - Branch to release +// DRY_RUN - Do not publish artifacts to OSSRH and code changes to GitHub +// OVERWRITE - Allows to overwrite existing version in git and OSSRH staging repositories + +// Job internal argumets: +// GIT_USER_NAME - Git user name (for commits) +// GIT_USER_EMAIL - Git user e-mail (for commits) +// SSH_CREDENTIALS_ID - Jenkins ID of SSH credentials +// GPG_CREDENTIALS_ID - Jenkins ID of GPG credentials (stored as KEYRING variable) + +pipeline { + + agent any + + tools { + jdk 'openjdk-jdk21-latest' + maven 'apache-maven-latest' + } + + environment { + SPEC_DIR="${WORKSPACE}/spec" + API_DIR="${WORKSPACE}" + } + + stages { + // Initialize build environment + stage('Init') { + steps { + git branch: BRANCH, credentialsId: SSH_CREDENTIALS_ID, url: GIT_URL + // GPG initialization + withCredentials([file(credentialsId: GPG_CREDENTIALS_ID, variable: 'KEYRING')]) { + sh ''' + gpg --batch --import ${KEYRING} + for fpr in $(gpg --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); + do + echo -e "5\ny\n" | gpg --batch --command-fd 0 --expert --edit-key $fpr trust; + done + + ''' + } + // Git configuration + sh ''' + git config --global user.name "${GIT_USER_NAME}" + git config --global user.email "${GIT_USER_EMAIL}" + ''' + } + } + // Perform release + stage('Build') { + steps { + sshagent([SSH_CREDENTIALS_ID]) { + sh ''' + etc/jenkins/continuous.sh + ''' + } + junit '**/target/surefire-reports/*.xml' + jacoco() + recordIssues(tools: [java(), javaDoc(), spotBugs(useRankAsPriority: true)]) + } + } + + } + +}
diff --git a/etc/jenkins/continuous.sh b/etc/jenkins/continuous.sh new file mode 100755 index 0000000..35f21f6 --- /dev/null +++ b/etc/jenkins/continuous.sh
@@ -0,0 +1,18 @@ +#!/bin/bash -e +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause + +# +# Arguments: +# N/A + +echo '-[ Jakarta XML Binding Specification Build ]------------------------------------' +(cd spec && mvn -U -C -B -Dstatus='DRAFT' clean install) +echo '-[ Jakarta XML Binding API Build ]----------------------------------------------' +mvn -U -C -B -V -Psnapshots,oss-release clean deploy spotbugs:spotbugs
diff --git a/etc/jenkins/release.groovy b/etc/jenkins/release.groovy new file mode 100644 index 0000000..5bd32f0 --- /dev/null +++ b/etc/jenkins/release.groovy
@@ -0,0 +1,71 @@ +// Copyright (c) 2019, 2024 Oracle and/or its affiliates. All rights reserved. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Distribution License v. 1.0, which is available at +// http://www.eclipse.org/org/documents/edl-v10.php. +// +// SPDX-License-Identifier: BSD-3-Clause + +// Job input parameters: +// API_VERSION - API version to release +// NEXT_API_VERSION - Next API snapshot version to set (e.g. 1.2.4-SNAPSHOT) +// BRANCH - Branch to release +// DRY_RUN - Do not publish artifacts to OSSRH and code changes to GitHub +// OVERWRITE - Allows to overwrite existing version in git and OSSRH staging repositories + +// Job internal argumets: +// GIT_USER_NAME - Git user name (for commits) +// GIT_USER_EMAIL - Git user e-mail (for commits) +// SSH_CREDENTIALS_ID - Jenkins ID of SSH credentials +// GPG_CREDENTIALS_ID - Jenkins ID of GPG credentials (stored as KEYRING variable) + +pipeline { + + agent any + + tools { + jdk 'openjdk-jdk21-latest' + maven 'apache-maven-latest' + } + + environment { + API_DIR="${WORKSPACE}" + } + + stages { + // Initialize build environment + stage('Init') { + steps { + git branch: BRANCH, credentialsId: SSH_CREDENTIALS_ID, url: GIT_URL + // GPG initialization + withCredentials([file(credentialsId: GPG_CREDENTIALS_ID, variable: 'KEYRING')]) { + sh ''' + gpg --batch --import ${KEYRING} + for fpr in $(gpg --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); + do + echo -e "5\ny\n" | gpg --batch --command-fd 0 --expert --edit-key $fpr trust; + done + + ''' + } + // Git configuration + sh ''' + git config --global user.name "${GIT_USER_NAME}" + git config --global user.email "${GIT_USER_EMAIL}" + ''' + } + } + // Perform release + stage('Release') { + steps { + sshagent([SSH_CREDENTIALS_ID]) { + sh ''' + etc/jenkins/release.sh "${API_VERSION}" "${NEXT_API_VERSION}" \ + "${DRY_RUN}" "${OVERWRITE}" + ''' + } + } + } + } + +}
diff --git a/etc/jenkins/release.sh b/etc/jenkins/release.sh new file mode 100755 index 0000000..b54968a --- /dev/null +++ b/etc/jenkins/release.sh
@@ -0,0 +1,109 @@ +#!/bin/bash -ex +# +# Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause + +# +# Arguments: +# $1 - API_VERSION +# $2 - NEXT_API_VERSION +# $3 - DRY_RUN +# $4 - OVERWRITE + +API_VERSION="${1}" +NEXT_API_VERSION="${2}" +DRY_RUN="${3}" +OVERWRITE="${4}" + + +export MAVEN_SKIP_RC="true" + +. etc/scripts/maven.incl.sh +. etc/scripts/nexus.incl.sh + +read_version 'API' "${API_DIR}" + +if [ -z "${API_RELEASE_VERSION}" ]; then + echo '-[ Missing required API release version number! ]-------------------------------' + exit 1 +fi + +RELEASE_TAG="${API_RELEASE_VERSION}" +RELEASE_BRANCH="${API_RELEASE_VERSION}-RELEASE" + +if [ ${DRY_RUN} = 'true' ]; then + echo '-[ Dry run turned on ]----------------------------------------------------------' + MVN_DEPLOY_ARGS='install' + echo '-[ Skipping GitHub branch and tag checks ]--------------------------------------' +else + MVN_DEPLOY_ARGS='deploy' + GIT_ORIGIN=`git remote` + echo '-[ Prepare branch ]-------------------------------------------------------------' + if [[ -n `git branch -r | grep "${GIT_ORIGIN}/${RELEASE_BRANCH}"` ]]; then + if [ "${OVERWRITE}" = 'true' ]; then + echo "${GIT_ORIGIN}/${RELEASE_BRANCH} branch already exists, deleting" + git push --delete origin "${RELEASE_BRANCH}" && true + else + echo "Error: ${GIT_ORIGIN}/${RELEASE_BRANCH} branch already exists" + exit 1 + fi + fi + echo '-[ Release tag cleanup ]--------------------------------------------------------' + if [[ -n `git ls-remote --tags ${GIT_ORIGIN} | grep "${RELEASE_TAG}\$"` ]]; then + if [ "${OVERWRITE}" = 'true' ]; then + echo "${RELEASE_TAG} tag already exists, deleting" + git push --delete origin "${RELEASE_TAG}" && true + else + echo "Error: ${RELEASE_TAG} tag already exists" + exit 1 + fi + fi +fi + +# Always delete local branch if exists +git branch --delete "${RELEASE_BRANCH}" && true +git checkout -b ${RELEASE_BRANCH} + +# Always delete local tag if exists +git tag --delete "${RELEASE_TAG}" && true + +# Read Maven identifiers +read_mvn_id 'API' "${API_DIR}/jaxb-api" + +# Set Nexus identifiers +API_STAGING_DESC="${API_GROUP_ID}:${API_ARTIFACT_ID}:${API_RELEASE_VERSION}" +API_STAGING_KEY=$(echo ${API_STAGING_DESC} | sed -e 's/\./\\\./g') + +# Set release versions +echo '-[ API release version ]--------------------------------------------------------' +set_version 'API' "${API_DIR}" "${API_RELEASE_VERSION}" "${API_GROUP_ID}" "${API_ARTIFACT_ID}" '' + +drop_artifacts "${API_STAGING_KEY}" "${API_DIR}" + +echo '-[ Deploy artifacts to staging repository ]-----------------------------' +# Verify, sign and deploy release +(cd ${API_DIR} && \ + mvn -U -C -B -V \ + -Poss-release,staging -DskipTests \ + -DstagingDescription="${API_STAGING_DESC}" \ + clean ${MVN_DEPLOY_ARGS}) + +echo '-[ Tag release ]----------------------------------------------------------------' +git tag "${RELEASE_TAG}" -m "JAXB-API ${API_RELEASE_VERSION} release" + +# Set next release cycle snapshot version +echo '-[ API next snapshot version ]--------------------------------------------------' +set_version 'API' "${API_DIR}" "${API_NEXT_SNAPSHOT}" "${API_GROUP_ID}" "${API_ARTIFACT_ID}" '' + +if [ ${DRY_RUN} = 'true' ]; then + echo '-[ Skipping GitHub update ]-----------------------------------------------------' +else + echo '-[ Push branch and tag to GitHub ]----------------------------------------------' + git push origin "${RELEASE_BRANCH}" + git push origin "${RELEASE_TAG}" +fi
diff --git a/etc/scripts/maven.incl.sh b/etc/scripts/maven.incl.sh new file mode 100644 index 0000000..605a266 --- /dev/null +++ b/etc/scripts/maven.incl.sh
@@ -0,0 +1,95 @@ +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause + +# Maven plugins +VERSIONS_PLUGIN='org.codehaus.mojo:versions-maven-plugin:2.7' +HELP_PLUGIN='org.apache.maven.plugins:maven-help-plugin:3.2.0' + +# Compute version strings for next development cycle. +# Version strings are set as new shell variables with provided prefix. +# Arguments: +# $1 - Variable prefix +# $2 - Source version +# Variables set: +# "${1}_NEXT_VERSION" - Next version string: Source string with last component increased by 1 +# "${1}_NEXT_SNAPSHOT" - Next snapshot string: Next version string with '-SNAPSHOT' suffix +next_version() { + set -f + local NEXT_COMPONENTS=(${2//\./ }) + local LAST_INDEX=$((${#NEXT_COMPONENTS[@]} - 1)) + local NEXT_COMPONENTS[${LAST_INDEX}]=$((${NEXT_COMPONENTS[${LAST_INDEX}]} + 1)) + local COMPONENTS_STR="${NEXT_COMPONENTS[@]}" + local NEXT_VERSION="${COMPONENTS_STR// /.}" + local NEXT_SNAPSHOT="${NEXT_VERSION}-SNAPSHOT" + echo "${1} Next Version: ${NEXT_VERSION}" + echo "${1} Next Snapshot: ${NEXT_SNAPSHOT}" + eval "${1}_NEXT_VERSION"="${NEXT_VERSION}" + eval "${1}_NEXT_SNAPSHOT"="${NEXT_SNAPSHOT}" +} + +# Prepare release version string and next development cycle versions. +# Version strings are set as new shell variables with provided prefix. +# Arguments: +# $1 - Variable prefix +# $2 - Build directory +# Source variables: +# "${1}_VERSION" - Release version override (optional) +# Variables set: +# "${1}_RELEASE_VERSION" - Release version +read_version() { + local VERSION_VAR="${1}_VERSION" + local SNAPSHOT_VERSION=`(cd ${2} && mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.version 2> /dev/null | grep -E '^[0-9]+(\.[0-9]+)+-SNAPSHOT$')` + if [ -z "${!VERSION_VAR}" ]; then + local RELEASE_VERSION="${SNAPSHOT_VERSION/-SNAPSHOT/}" + else + local RELEASE_VERSION="${!VERSION_VAR}" + fi + echo "${1} Release Version: ${RELEASE_VERSION}" + eval "${1}_RELEASE_VERSION"="${RELEASE_VERSION}" + next_version "${1}" "${RELEASE_VERSION}" +} + +# Read Maven identifier (groupId and artifactId). +# Maven identifier is set as new shell variables with provided prefix. +# Arguments: +# $1 - Variable prefix +# $2 - Build directory +# Variables set: +# "${1}_GROUP_ID" - Maven groupId +# "${1}_ARTIFACT_ID" - Maven artifactId +read_mvn_id() { + local GROUP_ID=`(cd ${2} && mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.groupId | grep -Ev '(^\[)')` + local ARTIFACT_ID=`(cd ${2} && mvn -B ${HELP_PLUGIN}:evaluate -Dexpression=project.artifactId | grep -Ev '(^\[)')` + echo "${1} Group ID: ${GROUP_ID}" + echo "${1} Artifact ID: ${ARTIFACT_ID}" + eval "${1}_GROUP_ID"="${GROUP_ID}" + eval "${1}_ARTIFACT_ID"="${ARTIFACT_ID}" +} + +# Set Maven artifact version. +# Arguments: +# $1 - Artifact identifier (e.g. 'SPEC', 'API', 'RI') +# $2 - Build directory +# $3 - Version to set +# $4 - Group ID +# $5 - Artifact ID +# $6 - Additional Maven arguments +set_version() { + echo '--[ Set version ]---------------------------------------------------------------' + # Set release version + (cd ${2} && \ + mvn -U -C \ + ${6} \ + -DnewVersion="${3}" \ + -DgenerateBackupPoms=false \ + clean ${VERSIONS_PLUGIN}:set) + echo '--[ Commit modified pom.xml files ]---------------------------------------------' + local POM_FILES=`git status | grep -E 'modified:.*pom\.xml' | sed -e 's/[[:space:]][[:space:]]*modified:[[:space:]][[:space:]]*//'` + git add ${POM_FILES} && \ + git commit -m "Update ${1} version of ${4}:${5} to ${3}" +}
diff --git a/etc/scripts/nexus.incl.sh b/etc/scripts/nexus.incl.sh new file mode 100644 index 0000000..de5632a --- /dev/null +++ b/etc/scripts/nexus.incl.sh
@@ -0,0 +1,22 @@ +# Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause + +# Drop old artifacts from staging repository +# Arguments: +# $1 - Staging key value with grep REGEX prefixes +# $2 - Build directory +drop_artifacts() { + echo '-[ Drop old staging repository deployments ]------------------------------------' + for staging_key in `(cd ${2} && mvn -B nexus-staging:rc-list | egrep "^\[INFO\] [A-Z,a-z,-]+-[0-9]+\s+[A-Z]+\s+${1}\$" | awk '{print $2}')`; do + echo "Repository ID: ${staging_key}" + (cd ${2} && \ + mvn -U -C \ + -DstagingRepositoryId="${staging_key}" \ + nexus-staging:rc-drop) + done +}
diff --git a/etc/spotbugs-exclude.xml b/etc/spotbugs-exclude.xml new file mode 100644 index 0000000..3655eb2 --- /dev/null +++ b/etc/spotbugs-exclude.xml
@@ -0,0 +1,61 @@ +<!-- + + Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<FindBugsFilter> + + <!-- + TODO: reevaluate for MR + As designed, impossible to change, maybe with MR. + --> + <Match> + <Bug pattern="EI_EXPOSE_REP"/> + <Or> + <Class name="~.*\.*Exception"/> + <Class name="~.*\.W3CDomHandler"/> + <Class name="~.*\.ValidationEventImpl"/> + <Class name="~.*\.ValidationEventLocatorImpl"/> + </Or> + </Match> + + <!-- + TODO: reevaluate for MR + As designed, impossible to change, maybe with MR. + --> + <Match> + <Bug pattern="EI_EXPOSE_REP2"/> + <Or> + <Class name="~.*\.*Exception"/> + <Class name="~.*\.W3CDomHandler"/> + <Class name="~.*\.ValidationEventImpl"/> + <Class name="~.*\.ValidationEventLocatorImpl"/> + <Class name="jakarta.xml.bind.util.JAXBSource"/> + </Or> + </Match> + + <!-- + As designed. + --> + <Match> + <Class name="jakarta.xml.bind.util.JAXBSource$1"/> + <Bug pattern="XFB_XML_FACTORY_BYPASS"/> + </Match> + + <!-- + TODO: reevaluate for MR + As designed, impossible to change, maybe with MR? + --> + <Match> + <Class name="jakarta.xml.bind.annotation.adapters.HexBinaryAdapter"/> + <Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/> + </Match> + +</FindBugsFilter>
diff --git a/jaxb-api-test/pom.xml b/jaxb-api-test/pom.xml new file mode 100644 index 0000000..1222cc2 --- /dev/null +++ b/jaxb-api-test/pom.xml
@@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright (c) 2018, 2023 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>jakarta.xml.bind-api-parent</artifactId> + <groupId>jakarta.xml.bind</groupId> + <version>4.0.2</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>jakarta.xml.bind-api-test</artifactId> + <packaging>jar</packaging> + + <properties> + <spotbugs.skip>true</spotbugs.skip> + <config.dir>${project.basedir}/../etc/config</config.dir> + <legal.doc.source>${project.basedir}/..</legal.doc.source> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>jakarta.xml.bind</groupId> + <artifactId>jakarta.xml.bind-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>jakarta.activation</groupId> + <artifactId>jakarta.activation-api</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <release>11</release> + </configuration> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy</id> + <phase>process-resources</phase> + <goals> + <goal>copy-dependencies</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}/modules</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <phase>generate-sources</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${project.build.directory}/classes/META-INF</outputDirectory> + <resources> + <resource> + <directory>${legal.doc.source}</directory> + <includes> + <include>LICENSE.md</include> + <include>NOTICE.md</include> + </includes> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <argLine> + --module-path ${project.build.directory}/modules/jakarta.activation-api-${activation.version}.jar:${project.build.directory}/modules/jakarta.xml.bind-api-${project.version}.jar + </argLine> + <systemPropertyVariables> + <java.util.logging.config.file> + src/test/resources/logging.properties + </java.util.logging.config.file> + </systemPropertyVariables> + </configuration> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <release>11</release> + <doclint>none</doclint> + <nodeprecated>false</nodeprecated> + <use>false</use> + <author>true</author> + <version>true</version> + <doctitle>Jakarta XML Binding API Library Tests documentation</doctitle> + <header><![CDATA[Jakarta XML Binding<br>v${project.version}]]> + </header> + <bottom> + <![CDATA[ +Comments to : <a href="mailto:${release.spec.feedback}">${release.spec.feedback}</a>.<br> +Copyright © 2020 Eclipse Foundation. All rights reserved.<br> +Use is subject to <a href="{@docRoot}/doc-files/speclicense.html" target="_top">license terms</a>.]]> + </bottom> + <detectJavaApiLink>false</detectJavaApiLink> + <detectOfflineLinks>false</detectOfflineLinks> + <docfilessubdirs>true</docfilessubdirs> + </configuration> + </plugin> + </plugins> + </build> +</project>
diff --git a/jaxb-api-test/src/main/java/jakarta/xml/bind/tests/SampleTest.java b/jaxb-api-test/src/main/java/jakarta/xml/bind/tests/SampleTest.java new file mode 100644 index 0000000..076fda6 --- /dev/null +++ b/jaxb-api-test/src/main/java/jakarta/xml/bind/tests/SampleTest.java
@@ -0,0 +1,17 @@ +/* + * Copyright (c) 2003, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package jakarta.xml.bind.tests; + +/** + * Sample test class + */ +public class SampleTest { + +}
diff --git a/jaxb-api-test/src/main/java/module-info.java b/jaxb-api-test/src/main/java/module-info.java new file mode 100644 index 0000000..f6add3e --- /dev/null +++ b/jaxb-api-test/src/main/java/module-info.java
@@ -0,0 +1,14 @@ +/* + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Placeholder for + */ +module jakarta.xml.bind.tests.src {}
diff --git a/jaxb-api-test/src/main/javadoc/doc-files/speclicense.html b/jaxb-api-test/src/main/javadoc/doc-files/speclicense.html new file mode 100644 index 0000000..ba29e5e --- /dev/null +++ b/jaxb-api-test/src/main/javadoc/doc-files/speclicense.html
@@ -0,0 +1,72 @@ +<html> +<head> +<title>Eclipse Foundation Specification License - v1.0</title> +</head> +<body> +<h1>Eclipse Foundation Specification License - v1.0</h1> +<p>By using and/or copying this document, or the Eclipse Foundation + document from which this statement is linked, you (the licensee) agree + that you have read, understood, and will comply with the following + terms and conditions:</p> + +<p>Permission to copy, and distribute the contents of this document, or + the Eclipse Foundation document from which this statement is linked, in + any medium for any purpose and without fee or royalty is hereby + granted, provided that you include the following on ALL copies of the + document, or portions thereof, that you use:</p> + +<ul> + <li> link or URL to the original Eclipse Foundation document.</li> + <li>All existing copyright notices, or if one does not exist, a notice + (hypertext is preferred, but a textual representation is permitted) + of the form: "Copyright © [$date-of-document] + “Eclipse Foundation, Inc. <<url to this license>> + " + </li> +</ul> + +<p>Inclusion of the full text of this NOTICE must be provided. We + request that authorship attribution be provided in any software, + documents, or other items or products that you create pursuant to the + implementation of the contents of this document, or any portion + thereof.</p> + +<p>No right to create modifications or derivatives of Eclipse Foundation + documents is granted pursuant to this license, except anyone may + prepare and distribute derivative works and portions of this document + in software that implements the specification, in supporting materials + accompanying such software, and in documentation of such software, + PROVIDED that all such works include the notice below. HOWEVER, the + publication of derivative works of this document for use as a technical + specification is expressly prohibited.</p> + +<p>The notice is:</p> + +<p>"Copyright © 2018 Eclipse Foundation. This software or + document includes material copied from or derived from [title and URI + of the Eclipse Foundation specification document]."</p> + +<h2>Disclaimers</h2> + +<p>THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT + HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR + WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE + SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS + WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR + OTHER RIGHTS.</p> + +<p>THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE + FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT + OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE + CONTENTS THEREOF.</p> + +<p>The name and trademarks of the copyright holders or the Eclipse + Foundation may NOT be used in advertising or publicity pertaining to + this document or its contents without specific, written prior + permission. Title to copyright in this document will at all times + remain with copyright holders.</p> + +</body> +</html>
diff --git a/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextServiceProviderNPETest.java b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextServiceProviderNPETest.java new file mode 100644 index 0000000..8a34537 --- /dev/null +++ b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextServiceProviderNPETest.java
@@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.test; + +import org.junit.Before; +import org.junit.Test; + +import jakarta.xml.bind.*; +import java.util.Map; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.TestCase.fail; + +/** + * regression test for + * JDK-8145104: NPE is thrown when JAXBContextFactory implementation is specified in system property + */ +public class JAXBContextServiceProviderNPETest { + + public static class Factory implements JAXBContextFactory { + + @Override + public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException { + return new MyContext(); + } + + @Override + public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) + throws JAXBException { + return new MyContext(); + } + } + + static class MyContext extends JAXBContext { + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + + } + + @Test + public void testContextPath() { + try { + JAXBContext ctx = JAXBContext.newInstance("whatever", ClassLoader.getSystemClassLoader()); + assertNotNull("Expected non-null instance to be returned from the test Factory", ctx); + assertEquals("Expected MyContext instance to be returned from the test Factory", MyContext.class, ctx.getClass()); + } catch (Throwable t) { + t.printStackTrace(); + fail("Not expected to fail!"); + } + } + + @Test + public void testClasses() { + try { + JAXBContext ctx = JAXBContext.newInstance(new Class[0]); + assertNotNull("Expected non-null instance to be returned from the test Factory", ctx); + assertEquals("Expected MyContext instance to be returned from the test Factory", MyContext.class, ctx.getClass()); + } catch (Throwable t) { + t.printStackTrace(); + fail("Not expected to fail!"); + } + } + + @Before + public void setup() { + System.setProperty("jakarta.xml.bind.JAXBContextFactory", "jakarta.xml.bind.test.JAXBContextServiceProviderNPETest$Factory"); + } + + public static void main(String[] args) throws JAXBException { + JAXBContextServiceProviderNPETest tst = new JAXBContextServiceProviderNPETest(); + tst.setup(); + tst.testContextPath(); + tst.testClasses(); + } + +} +
diff --git a/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextTest.java b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextTest.java new file mode 100644 index 0000000..0287bb9 --- /dev/null +++ b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextTest.java
@@ -0,0 +1,344 @@ +/* + * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.test; + + +import jaxb.test.usr.A; +import junit.framework.AssertionFailedError; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import jakarta.xml.bind.JAXBContext; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Arrays; +import java.util.Collection; +import java.util.logging.Logger; + +import static junit.framework.TestCase.assertTrue; + +/* + * test for JDK-8131334: SAAJ Plugability Layer: using java.util.ServiceLoader + * + * There are unsafe scenarios not to be run within the build (modifying jdk files). + * To run those, following needs to be done: + * 1. allow java to write into $JAVA_HOME/conf: mkdir $JAVA_HOME/conf; chmod a+rw $JAVA_HOME/conf + * 2. use "runUnsafe" property: mvn clean test -DrunUnsafe=true + */ +@RunWith(Parameterized.class) +public class JAXBContextTest { + + static final Logger logger = Logger.getLogger(JAXBContextTest.class.getName()); + + static final Boolean skipUnsafe = !Boolean.getBoolean("runUnsafe"); + + // test configuration ------------------------------------------ + + // test-classes directory (required for setup and for security settings) + static final String classesDir = JAXBContextTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(); + private static final String FACTORY_ID_LEGACY = "jakarta.xml.bind.context.factory"; + private static final String FACTORY_ID = "jakarta.xml.bind.JAXBContextFactory"; + private static final String PACKAGE_LEGACY = "jaxb.factory.legacy."; // TODO: ??? + private static final String PACKAGE_SPI = "jaxb.factory.spi."; // TODO: ??? + private static final Object DEFAULT = "com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl"; + + + static { + System.setProperty("classesDir", classesDir); + } + + // configuration to be created by the test + static Path providersDir = Paths.get(classesDir, "META-INF", "services"); + static Path providersFileLegacy = providersDir.resolve("jakarta.xml.bind.JAXBContext"); + static Path providersFile = providersDir.resolve("jakarta.xml.bind.JAXBContextFactory"); + + // configuration to be created by the test + static Path jaxbPropsDir = Paths.get(classesDir, "jaxb", "test", "usr"); + static Path jaxbPropsFile = jaxbPropsDir.resolve("jaxb.properties"); + + // test instance ----------------------------------------------- + + // scenario name - just for logging + String scenario; + + // java policy file for testing w/security manager + private String expectedFactory; + private Class<?> expectedException; + + // Broken configurations were commented out. + @Parameterized.Parameters + public static Collection configurations() { + return Arrays.asList(new Object[][]{ + // scenario-name, jaxb.properties, svc, arg1, arg2, system-props +// {"scenario-1", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Valid", null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, null}, + {"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null}, + {"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-13", FACTORY_ID_LEGACY + "="+PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid3"}, + +// {"scenario-1", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Valid", null, PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + {"scenario-3", FACTORY_ID_LEGACY + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null}, + {"scenario-4", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-13", FACTORY_ID_LEGACY + "="+PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid3"}, + +// {"scenario-1", FACTORY_ID + "="+PACKAGE_SPI+"Valid", null, PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + {"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null}, + {"scenario-4", FACTORY_ID + "="+PACKAGE_SPI+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-13", FACTORY_ID + "="+PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid3"}, + +// {"scenario-1", FACTORY_ID + "="+PACKAGE_LEGACY+"Valid", null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, null}, + {"scenario-3", FACTORY_ID + "=non.existing.FactoryClass", null, null, jakarta.xml.bind.JAXBException.class, null}, + {"scenario-4", FACTORY_ID + "="+PACKAGE_LEGACY+"Invalid", null, null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-13", FACTORY_ID + "="+PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid3"}, + + + {"scenario-2", "something=AnotherThing", null, null, jakarta.xml.bind.JAXBException.class, null}, + + // service loader + {"scenario-8", null, PACKAGE_SPI+"Valid\n", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + {"scenario-9", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + {"scenario-11", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null}, + {"scenario-15", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + + // service loader - legacy +// {"scenario-8 legacy-svc", null, PACKAGE_SPI+"Valid\n", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, +// {"scenario-9 legacy-svc", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + {"scenario-11 legacy-svc", null, PACKAGE_SPI+"Invalid", null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-15 legacy-svc", null, PACKAGE_SPI+"Valid", PACKAGE_SPI+"Valid$JAXBContext1", null, null}, + + // service loader - legacy +// {"scenario-8 legacy-svc", null, PACKAGE_LEGACY+"Valid\n", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null}, +// {"scenario-9 legacy-svc", null, PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null}, + {"scenario-11 legacy-svc", null, PACKAGE_LEGACY+"Invalid", null, jakarta.xml.bind.JAXBException.class, null}, +// {"scenario-15 legacy-svc", null, PACKAGE_LEGACY+"Valid", PACKAGE_LEGACY+"Valid$JAXBContext1", null, null}, + + // system property + {"scenario-5", null, null, PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid"}, + {"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_SPI+"Invalid"}, + {"scenario-14", null, PACKAGE_SPI+"Valid2", PACKAGE_SPI+"Valid$JAXBContext1", null, PACKAGE_SPI+"Valid"}, + + {"scenario-5", null, null, PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid"}, + {"scenario-7", null, null, null, jakarta.xml.bind.JAXBException.class, PACKAGE_LEGACY+"Invalid"}, + {"scenario-14", null, PACKAGE_LEGACY+"Valid2", PACKAGE_LEGACY+"Valid$JAXBContext1", null, PACKAGE_LEGACY+"Valid"}, + {"scenario-6", null, null, null, jakarta.xml.bind.JAXBException.class, "jaxb.factory.NonExisting"}, + + {"scenario-10", null, "jaxb.factory.NonExisting", null, jakarta.xml.bind.JAXBException.class, null}, + + {"scenario-12", null, null, DEFAULT, jakarta.xml.bind.JAXBException.class, null}, + }); + } + + // scenario-name, jaxb.properties, svc, arg1, arg2, system-props + public JAXBContextTest( + String scenario, + String jaxbPropertiesClass, + String spiClass, + String expectedFactory, + Class<?> expectedException, + String systemProperty + ) { + + // ensure setup may be done ... + System.setSecurityManager(null); + + if (systemProperty != null) { + System.setProperty("jakarta.xml.bind.JAXBContextFactory", systemProperty); + } else { + System.clearProperty("jakarta.xml.bind.JAXBContextFactory"); + } + + this.scenario = scenario; + this.expectedFactory = expectedFactory; + this.expectedException = expectedException; + + if (skipUnsafe && scenario.startsWith("unsafe")) { + log("Skipping unsafe scenario:" + scenario); + return; + } + + prepare(jaxbPropertiesClass, spiClass); + } + + @Test + public void testPath() throws IOException { + logConfigurations(); + try { + JAXBContext ctx = JAXBContext.newInstance("jaxb.test.usr"); + handleResult(ctx); + } catch (Throwable throwable) { + handleThrowable(throwable); + } finally { + doFinally(); + } + } + + @Test + public void testClasses() throws IOException { + logConfigurations(); + try { + JAXBContext ctx = JAXBContext.newInstance(new Class[] {A.class}, null); + handleResult(ctx); + } catch (Throwable throwable) { + handleThrowable(throwable); + } finally { + doFinally(); + } + } + + @Test + public void testClass() throws IOException { + logConfigurations(); + try { + JAXBContext ctx = JAXBContext.newInstance(A.class); + handleResult(ctx); + } catch (Throwable throwable) { + handleThrowable(throwable); + } finally { + doFinally(); + } + } + + private void handleResult(JAXBContext ctx) { + assertTrue("No ctx found.", ctx != null); + log(" TEST: context class = [" + ctx.getClass().getName() + "]\n"); + String className = ctx.getClass().getName(); + assertTrue("Incorrect ctx: [" + className + "], Expected: [" + expectedFactory + "]", + className.equals(expectedFactory)); + + log(" TEST PASSED"); + } + + private void handleThrowable(Throwable throwable) { + if (throwable instanceof AssertionFailedError) throw ((AssertionFailedError)throwable); + Class<?> throwableClass = throwable.getClass(); + boolean correctException = throwableClass.equals(expectedException); + if (!correctException) { + throwable.printStackTrace(); + } + if (expectedException == null) { + throw new AssertionFailedError("Unexpected exception:" + throwableClass); + } + assertTrue("Got unexpected exception: [" + throwableClass + "], expected: [" + expectedException + "]", + correctException); + log(" TEST PASSED"); + } + + private void doFinally() { + cleanResource(providersFile); + //cleanResource(providersDir); + + // unsafe; not running: + cleanResource(jaxbPropsFile); + System.setSecurityManager(null); + } + + @Test + public void testPathSM() throws IOException { + enableSM(); + testPath(); + } + + @Test + public void testClassSM() throws IOException { + enableSM(); + testClass(); + } + + @Test + public void testClassesSM() throws IOException { + enableSM(); + testClasses(); + } + + + private void enableSM() { + System.setSecurityManager(null); + System.setProperty("java.security.policy", classesDir + "jakarta/xml/bind/test.policy"); + System.setSecurityManager(new SecurityManager()); + } + + private void cleanResource(Path resource) { + try { + if (Files.exists(resource)) { + Files.deleteIfExists(resource); + } + } catch (IOException ignored) { + ignored.printStackTrace(); + } + } + + private void prepare(String propertiesClassName, String providerClassName) { + + try { + log("providerClassName = " + providerClassName); + log("propertiesClassName = " + propertiesClassName); + + cleanResource(providersFile); + cleanResource(providersFileLegacy); + if (scenario.contains("legacy-svc")) { + setupFile(providersFileLegacy, providersDir, providerClassName); + } else { + setupFile(providersFile, providersDir, providerClassName); + } + + + // unsafe; not running: + if (propertiesClassName != null) { + setupFile(jaxbPropsFile, jaxbPropsDir, propertiesClassName); + } else { + cleanResource(jaxbPropsFile); + } + + log(" SETUP OK."); + + } catch (IOException e) { + log(" SETUP FAILED."); + e.printStackTrace(); + } + } + + private void logConfigurations() throws IOException { + logFile(providersFile); + logFile(providersFileLegacy); + logFile(jaxbPropsFile); + } + + private void logFile(Path path) throws IOException { + if (Files.exists(path)) { + log("File [" + path + "] exists: ["); + log(new String(Files.readAllBytes(path))); + log("]"); + } + } + + private void setupFile(Path file, Path dir, String value) throws IOException { + cleanResource(file); + if (value != null) { + log("writing configuration [" + value + "] into file [" + file.toAbsolutePath() + "]"); + Files.createDirectories(dir); + Files.write( + file, + value.getBytes(), + StandardOpenOption.CREATE); + } + } + + private void log(String msg) { + logger.info("[" + scenario + "] " + msg); +// System.out.println("[" + scenario + "] " + msg); + } + +} + +
diff --git a/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextWrapExceptionTest.java b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextWrapExceptionTest.java new file mode 100644 index 0000000..f312f1a --- /dev/null +++ b/jaxb-api-test/src/test/java/jakarta/xml/bind/test/JAXBContextWrapExceptionTest.java
@@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jakarta.xml.bind.test; + +import org.junit.Before; +import org.junit.Test; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import java.util.Map; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static junit.framework.TestCase.assertNull; + +/** + * regression test for + * JDK-8145112: newInstance(String, ClassLoader): java.lang.JAXBException should not be wrapped as expected + * according to spec + */ +public class JAXBContextWrapExceptionTest { + + public static class Factory { + + public static JAXBContext createContext(Class[] classesToBeBound, Map<String, ?> properties) throws JAXBException { + throw new JAXBException("test"); + } + + public static JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) + throws JAXBException { + throw new JAXBException("test"); + } + } + + @Test + public void testContextPath() { + try { + JAXBContext.newInstance("whatever", ClassLoader.getSystemClassLoader()); + } catch (Throwable t) { + assertEquals("test", t.getMessage()); + assertNull("Root cause must be null", t.getCause()); + } + } + + @Test + public void testClasses() { + try { + JAXBContext.newInstance(new Class[0]); + assertTrue("This should fail", false); + } catch (Throwable t) { + assertEquals("test", t.getMessage()); + assertNull("Root cause must be null", t.getCause()); + } + } + + @Before + public void setup() { + System.setProperty("jakarta.xml.bind.JAXBContextFactory", "jakarta.xml.bind.test.JAXBContextWrapExceptionTest$Factory"); + } + + public static void main(String[] args) throws JAXBException { + new JAXBContextWrapExceptionTest().testContextPath(); + new JAXBContextWrapExceptionTest().testClasses(); + } + +} +
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/legacy/Invalid.java b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Invalid.java new file mode 100644 index 0000000..38148c9 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Invalid.java
@@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.legacy; + +/** + * Invalid JAXBContext factory class for tests + * - doesn't contain required static methods + */ +public class Invalid { +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid.java b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid.java new file mode 100644 index 0000000..0c34eba --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid.java
@@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.legacy; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * Valid JAXBContext factory class for tests + * - contains required static methods and creates dummy JAXBContext + */ +public class Valid { + + public static JAXBContext createContext(java.lang.String path, java.lang.ClassLoader cl) { + return new JAXBContext1(); + } + + public static JAXBContext createContext(Class[] classes, Map<String, Object> properties) throws JAXBException { + return new JAXBContext1(); + } + + + public static class JAXBContext1 extends JAXBContext { + + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + } +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid2.java b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid2.java new file mode 100644 index 0000000..ce29d8b --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid2.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.legacy; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * (Another) Valid JAXBContext factory class for tests + * - contains required static methods and creates dummy JAXBContext + * - several implementations necessary to test different configuration approaches + */ +public class Valid2 { + + public static JAXBContext createContext(String path, ClassLoader cl) { + return new JAXBContext1(); + } + + public static JAXBContext createContext(Class[] classes, Map<String, Object> properties) throws JAXBException { + return new JAXBContext1(); + } + + + public static class JAXBContext1 extends JAXBContext { + + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + } +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid3.java b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid3.java new file mode 100644 index 0000000..e214765 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/legacy/Valid3.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.legacy; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * (Another) Valid JAXBContext factory class for tests + * - contains required static methods and creates dummy JAXBContext + * - several implementations necessary to test different configuration approaches + */ +public class Valid3 { + + public static JAXBContext createContext(String path, ClassLoader cl) { + return new JAXBContext1(); + } + + public static JAXBContext createContext(Class[] classes, Map<String, Object> properties) throws JAXBException { + return new JAXBContext1(); + } + + + public static class JAXBContext1 extends JAXBContext { + + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + } +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/spi/Invalid.java b/jaxb-api-test/src/test/java/jaxb/factory/spi/Invalid.java new file mode 100644 index 0000000..97aa949 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/spi/Invalid.java
@@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.spi; + +/** + * Invalid JAXBContext factory class for tests + * - doesn't contain required static methods + */ +public class Invalid { +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid.java b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid.java new file mode 100644 index 0000000..8602c68 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.spi; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBContextFactory; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * Created by miran on 10/11/14. + */ +public class Valid implements JAXBContextFactory { + + @Override + public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + @Override + public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + public static class JAXBContext1 extends JAXBContext { + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + } + +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid2.java b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid2.java new file mode 100644 index 0000000..f48de92 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid2.java
@@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.spi; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBContextFactory; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * Created by miran on 10/11/14. + */ +public class Valid2 implements JAXBContextFactory { + + @Override + public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + @Override + public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + public static class JAXBContext1 extends JAXBContext { + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + } + +}
diff --git a/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid3.java b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid3.java new file mode 100644 index 0000000..db67496 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/factory/spi/Valid3.java
@@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.factory.spi; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBContextFactory; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; +import java.util.Map; + +/** + * Created by miran on 10/11/14. + */ +public class Valid3 implements JAXBContextFactory { + + @Override + public JAXBContext createContext(Class<?>[] classesToBeBound, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + @Override + public JAXBContext createContext(String contextPath, ClassLoader classLoader, Map<String, ?> properties) throws JAXBException { + return new JAXBContext1(); + } + + public static class JAXBContext1 extends JAXBContext { + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return null; + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return null; + } + + } + +}
diff --git a/jaxb-api-test/src/test/java/jaxb/test/usr/A.java b/jaxb-api-test/src/test/java/jaxb/test/usr/A.java new file mode 100644 index 0000000..bf19578 --- /dev/null +++ b/jaxb-api-test/src/test/java/jaxb/test/usr/A.java
@@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +package jaxb.test.usr; + +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; + +/** + * Simple user class for testing creation of JAXBContext + */ +@XmlType +@XmlRootElement +public class A { + + String name; +}
diff --git a/jaxb-api-test/src/test/java/module-info.java b/jaxb-api-test/src/test/java/module-info.java new file mode 100644 index 0000000..f9de673 --- /dev/null +++ b/jaxb-api-test/src/test/java/module-info.java
@@ -0,0 +1,18 @@ +/* + * Copyright (c) 2018, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0, which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * Tests for jaxb API. + */ +module jakarta.xml.bind.tests { + requires jakarta.xml.bind; + requires java.logging; + requires junit; +}
diff --git a/jaxb-api-test/src/test/resources/jakarta/xml/bind/test.policy b/jaxb-api-test/src/test/resources/jakarta/xml/bind/test.policy new file mode 100644 index 0000000..a10467b --- /dev/null +++ b/jaxb-api-test/src/test/resources/jakarta/xml/bind/test.policy
@@ -0,0 +1,15 @@ +grant { + // security manager + permission java.lang.RuntimePermission "setSecurityManager"; + + permission java.lang.RuntimePermission "accessDeclaredMembers"; + + // writing configuration files + permission java.io.FilePermission "${classesDir}/-", "read, write, delete"; + + permission java.util.PropertyPermission "*", "read"; + permission java.lang.RuntimePermission "*"; + + // reading / modifying jdk/conf/jaxm.properties + permission java.io.FilePermission "${java.home}${/}-", "read, write, delete"; +}; \ No newline at end of file
diff --git a/jaxb-api-test/src/test/resources/jaxb/test/usr/jaxb.index b/jaxb-api-test/src/test/resources/jaxb/test/usr/jaxb.index new file mode 100644 index 0000000..8c7e5a6 --- /dev/null +++ b/jaxb-api-test/src/test/resources/jaxb/test/usr/jaxb.index
@@ -0,0 +1 @@ +A \ No newline at end of file
diff --git a/jaxb-api-test/src/test/resources/logging.properties b/jaxb-api-test/src/test/resources/logging.properties new file mode 100644 index 0000000..51fc022 --- /dev/null +++ b/jaxb-api-test/src/test/resources/logging.properties
@@ -0,0 +1,2 @@ +handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level=FINEST
diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0274e21 --- /dev/null +++ b/pom.xml
@@ -0,0 +1,238 @@ +<?xml version="1.0"?> +<!-- + + Copyright (c) 1997, 2024 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Distribution License v. 1.0, which is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + SPDX-License-Identifier: BSD-3-Clause + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.ee4j</groupId> + <artifactId>project</artifactId> + <version>1.0.9</version> + <relativePath/> + </parent> + + <groupId>jakarta.xml.bind</groupId> + <artifactId>jakarta.xml.bind-api-parent</artifactId> + <version>4.0.2</version> + <packaging>pom</packaging> + <name>Jakarta XML Binding</name> + <description>Jakarta XML Binding API</description> + <url>https://github.com/jakartaee/jaxb-api</url> + + <scm> + <connection>scm:git:git://github.com/jakartaee/jaxb-api.git</connection> + <developerConnection>scm:git:git@github.com:jakartaee/jaxb-api.git</developerConnection> + <url>https://github.com/jakartaee/jaxb-api.git</url> + <tag>HEAD</tag> + </scm> + + <licenses> + <license> + <name>Eclipse Distribution License - v 1.0</name> + <url>http://www.eclipse.org/org/documents/edl-v10.php</url> + <distribution>repo</distribution> + </license> + </licenses> + + <developers> + <developer> + <name>Roman Grigoriadi</name> + <email>roman.grigoriadi@oracle.com</email> + <organization>Oracle Corporation</organization> + </developer> + </developers> + + <issueManagement> + <system>github</system> + <url>https://github.com/jakartaee/jaxb-api/issues</url> + </issueManagement> + + <mailingLists> + <mailingList> + <name>Jakarta XML Binding mailing list</name> + <post>jaxb-dev@eclipse.org</post> + <subscribe>https://accounts.eclipse.org/mailing-list/jaxb-dev</subscribe> + <unsubscribe>https://accounts.eclipse.org/mailing-list/jaxb-dev</unsubscribe> + <archive>https://dev.eclipse.org/mhonarc/lists/jaxb-dev</archive> + </mailingList> + </mailingLists> + + <properties> + <copyright.exclude>${config.dir}/copyright-exclude</copyright.exclude> + <copyright.ignoreyear>true</copyright.ignoreyear> + <copyright.scmonly>true</copyright.scmonly> + <copyright.templatefile>${config.dir}/edl-copyright.txt</copyright.templatefile> + <copyright.update>false</copyright.update> + <spotbugs.skip>false</spotbugs.skip> + <spotbugs.threshold>Low</spotbugs.threshold> + <spotbugs.version>4.8.3.1</spotbugs.version> + + <maven.compiler.release>11</maven.compiler.release> + + <release.spec.feedback>jaxb-dev@eclipse.org</release.spec.feedback> + <release.spec.date>Mar 2022</release.spec.date> + <api.package>jakarta.xml.bind</api.package> + <extension.name>jakarta.xml.bind</extension.name> + <spec.version>4.0</spec.version> + <activation.version>2.1.3</activation.version> + <config.dir>${project.basedir}/etc/config</config.dir> + <vendor.name>Eclipse Foundation</vendor.name> + </properties> + + <modules> + <module>api</module> + </modules> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>jakarta.activation</groupId> + <artifactId>jakarta.activation-api</artifactId> + <version>${activation.version}</version> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>buildnumber-maven-plugin</artifactId> + <version>3.2.0</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <version>3.5.0</version> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.12.1</version> + </plugin> + <plugin> + <groupId>org.glassfish.copyright</groupId> + <artifactId>glassfish-copyright-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.2.5</version> + </plugin> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <version>3.6.3</version> + </plugin> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <version>3.4.1</version> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>5.1.9</version> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>3.3.0</version> + </plugin> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <version>3.3.0</version> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>3.3.1</version> + </plugin> + <plugin> + <artifactId>maven-deploy-plugin</artifactId> + <version>3.1.1</version> + </plugin> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>3.6.1</version> + </plugin> + <plugin> + <groupId>com.github.spotbugs</groupId> + <artifactId>spotbugs-maven-plugin</artifactId> + <version>${spotbugs.version}</version> + <configuration> + <skip>${spotbugs.skip}</skip> + <threshold>${spotbugs.threshold}</threshold> + </configuration> + </plugin> + </plugins> + </pluginManagement> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <compilerArgs> + <arg>-Xlint:all</arg> + </compilerArgs> + </configuration> + </plugin> + <plugin> + <groupId>org.glassfish.copyright</groupId> + <artifactId>glassfish-copyright-maven-plugin</artifactId> + <configuration> + <templateFile>${copyright.templatefile}</templateFile> + <excludeFile>${copyright.exclude}</excludeFile> + <!-- skip files not under SCM--> + <scmOnly>${copyright.scmonly}</scmOnly> + <!-- for use with repair --> + <update>${copyright.update}</update> + <!-- check that year is correct --> + <ignoreYear>${copyright.ignoreyear}</ignoreYear> + <quiet>false</quiet> + </configuration> + <executions> + <execution> + <phase>validate</phase> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addDefaultEntries>false</addDefaultEntries> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Implementation-Build-Id>${project.version} - ${buildNumber}</Implementation-Build-Id> + </manifestEntries> + </archive> + </configuration> + </plugin> + </plugins> + + </build> + + <profiles> + <profile> + <id>test</id> + <modules> + <module>jaxb-api-test</module> + </modules> + </profile> + </profiles> +</project>
diff --git a/spec/LICENSE b/spec/LICENSE new file mode 100644 index 0000000..e48e096 --- /dev/null +++ b/spec/LICENSE
@@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership.
diff --git a/spec/README.md b/spec/README.md new file mode 100644 index 0000000..5941424 --- /dev/null +++ b/spec/README.md
@@ -0,0 +1,22 @@ +Jakarta XML Binding Specification +============================ + +This project generates the Jakarta XML Binding Specification. + +Building +-------- + +Prerequisites: + +* JDK8+ +* Maven 3.0.3+ + +Run the full build: + +`mvn install` + +Locate the html files: +- `target/generated-docs/jakarta.xml.bind-spec-<version>.html` + +Locate the PDF files: +- `target/generated-docs/jakarta.xml.bind-spec-<version>.pdf`
diff --git a/spec/pom.xml b/spec/pom.xml new file mode 100644 index 0000000..cd37cab --- /dev/null +++ b/spec/pom.xml
@@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright (c) 2017, 2024 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v. 2.0, which is available at + http://www.eclipse.org/legal/epl-2.0. + + This Source Code may also be made available under the following Secondary + Licenses when the conditions for such availability set forth in the + Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + version 2 with the GNU Classpath Exception, which is available at + https://www.gnu.org/software/classpath/license.html. + + SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.ee4j</groupId> + <artifactId>project</artifactId> + <version>1.0.6</version> + <relativePath/> + </parent> + + <groupId>jakarta.xml.bind</groupId> + <artifactId>xml-binding-spec</artifactId> + <version>4.0-SNAPSHOT</version> + <packaging>pom</packaging> + + <name>Jakarta XML Binding Specification</name> + + <scm> + <connection>scm:git:git://github.com/jakartaee/jaxb-api.git</connection> + <developerConnection>scm:git:git@github.com:jakartaee/jaxb-api.git</developerConnection> + <url>https://github.com/jakartaee/jaxb-api.git</url> + <tag>HEAD</tag> + </scm> + <distributionManagement> + <site> + <url>scm:git:git@github.com:jakartaee/jaxb-api.git</url> + </site> + </distributionManagement> + + <properties> + <site.output.dir>${project.build.directory}/staging</site.output.dir> + <maven.site.skip>true</maven.site.skip> + <asciidoctor.maven.plugin.version>2.2.4</asciidoctor.maven.plugin.version> + <asciidoctorj.pdf.version>2.3.9</asciidoctorj.pdf.version> + <spec.name>jakarta-${project.artifactId}-${project.version}</spec.name> + <!-- status: DRAFT, BETA, etc., or blank for final --> + <status>DRAFT</status> + <maven.build.timestamp.format>MMMM dd, yyyy</maven.build.timestamp.format> + <revisiondate>${maven.build.timestamp}</revisiondate> + </properties> + + <build> + <defaultGoal>package</defaultGoal> + <plugins> + <!-- Sets minimal Maven version --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <version>3.4.0</version> + <executions> + <execution> + <id>enforce-env</id> + <goals> + <goal>enforce</goal> + </goals> + <configuration> + <rules> + <requireMavenVersion> + <version>3.6.0</version> + </requireMavenVersion> + <requireJavaVersion> + <version>[11,)</version> + <message>You need Java SE 11 or newer</message> + </requireJavaVersion> + </rules> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctor-maven-plugin</artifactId> + <version>${asciidoctor.maven.plugin.version}</version> + <dependencies> + <dependency> + <groupId>org.asciidoctor</groupId> + <artifactId>asciidoctorj-pdf</artifactId> + <version>${asciidoctorj.pdf.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>asciidoc-to-html</id> + <phase>generate-resources</phase> + <goals> + <goal>process-asciidoc</goal> + </goals> + <configuration> + <backend>html5</backend> + <outputFile>${project.build.directory}/generated-docs/${spec.name}.html</outputFile> + <attributes> + <doctype>book</doctype> + <status>${status}</status> + <data-uri /> + <icons>font</icons> + <toc>left</toc> + <icons>font</icons> + <sectanchors>true</sectanchors> + <idprefix /> + <idseparator>-</idseparator> + <docinfo1>true</docinfo1> + </attributes> + </configuration> + </execution> + <execution> + <id>asciidoc-to-pdf</id> + <phase>generate-resources</phase> + <goals> + <goal>process-asciidoc</goal> + </goals> + <configuration> + <backend>pdf</backend> + <outputFile>${project.build.directory}/generated-docs/${spec.name}.pdf</outputFile> + <attributes> + <pdf-stylesdir>${project.basedir}/src/theme</pdf-stylesdir> + <pdf-style>jakartaee</pdf-style> + <doctype>book</doctype> + <status>${status}</status> + <data-uri /> + <icons>font</icons> + <pagenums /> + <toc /> + <icons>font</icons> + <sectanchors>true</sectanchors> + <idprefix /> + <idseparator>-</idseparator> + <docinfo1>true</docinfo1> + <embedAssets>true</embedAssets> + </attributes> + </configuration> + </execution> + </executions> + <configuration> + <sourceDocumentName>${project.artifactId}.adoc</sourceDocumentName> + <attributes> + <sourceDirectory>${basedir}/src/main/asciidoc</sourceDirectory> + <imagesdir>images</imagesdir> + <source-highlighter>coderay</source-highlighter> + <revremark>${status}</revremark> + <revdate>${revisiondate}</revdate> + <revnumber>${project.version}</revnumber> + </attributes> + </configuration> + </plugin> + <!-- + This is the rule that builds the zip file for download. + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>3.6.0</version> + <inherited>false</inherited> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <descriptors> + <descriptor>${project.basedir}/src/assembly/assembly.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project>
diff --git a/spec/src/assembly/assembly.xml b/spec/src/assembly/assembly.xml new file mode 100644 index 0000000..239db60 --- /dev/null +++ b/spec/src/assembly/assembly.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- + + Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v. 2.0, which is available at + http://www.eclipse.org/legal/epl-2.0. + + This Source Code may also be made available under the following Secondary + Licenses when the conditions for such availability set forth in the + Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + version 2 with the GNU Classpath Exception, which is available at + https://www.gnu.org/software/classpath/license.html. + + SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +--> + +<assembly> + <id>spec</id> + <formats> + <format>zip</format> + </formats> + <baseDirectory>xml-binding-spec</baseDirectory> + <fileSets> + <fileSet> + <directory>target/generated-docs</directory> + <outputDirectory></outputDirectory> + </fileSet> + </fileSets> +</assembly>
diff --git a/spec/src/main/asciidoc/XMLBinding.adoc b/spec/src/main/asciidoc/XMLBinding.adoc new file mode 100644 index 0000000..b794cce --- /dev/null +++ b/spec/src/main/asciidoc/XMLBinding.adoc
@@ -0,0 +1,22 @@ +// +// Copyright (c) 2020 Contributors to the Eclipse Foundation +// + +include::ch01-introduction.adoc[] +include::ch02-requirements.adoc[] +include::ch03-architecture.adoc[] +include::ch04-binding_framework.adoc[] +include::ch05-java_representation.adoc[] +include::ch06-binding_xml_schema.adoc[] +include::ch07-customize_xml_schema.adoc[] +include::ch08-java_types.adoc[] +include::ch09-compatibility.adoc[] + +include::appA-references.adoc[] +include::appB-runtime_processing.adoc[] +include::appC-normative_schema.adoc[] +include::appD-binding_xml.adoc[] +include::appE-external_binding.adoc[] +include::appF-xml_schema.adoc[] +include::appH-binary_data.adoc[] +include::appI-changelog.adoc[]
diff --git a/spec/src/main/asciidoc/appA-references.adoc b/spec/src/main/asciidoc/appA-references.adoc new file mode 100644 index 0000000..4f35a0f --- /dev/null +++ b/spec/src/main/asciidoc/appA-references.adoc
@@ -0,0 +1,97 @@ +// +// Copyright (c) 2020 Contributors to the Eclipse Foundation +// + +[appendix] +== References + +[XSD Part 0] XML Schema Part 0: Primer, + +Available at _http://www.w3.org/TR/2004/REC-xmlschema-0-20041028/_ + +(schema fragments borrowed from this widely used source). + +[XSD Part 1] XML Schema Part 1: Structures, + +Available at _http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/_. + +[XSD Part 2] XML Schema Part 2: Datatypes, + +Available at _http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/_. + +[XMl-Infoset] XML Information Set, John Cowan +and Richard Tobin, eds., W3C, 16 March 2001. + +Available at _http://www.w3.org/TR/2001/WD-xml-infoset-20010316/_. + +[XML 1.0] Extensible Markup Language (XML) +1.0 (Second Edition), + +W3C Recommendation 6 October 2000. + +Available at _http://www.w3.org/TR/2000/REC-xml-20001006_. + +[Namespaces in XML] Namespaces in XML + +W3C Recommendation 14 January 1999. + +Available at _http://www.w3.org/TR/1999/REC-xml-names-19990114_. + +[XPath], XML Path Language, James Clark and +Steve DeRose, eds., W3C, 16 November 1999. + +Available at _http://www.w3.org/TR/1999/REC-xpath-19991116_. + +[XSLT 1.0] XSL Transformations (XSLT), +Version 1.0, James Clark, + +W3C Recommendation 16 November 1999. + +Available at _http://www.w3.org/TR/1999/REC-xslt-19991116_. + +[BEANS] JavaBeans(TM), Version 1.01, July 24, 1997. + +Available at _http://java.sun.com/beans_. + +[XSD Primer] XML Schema Part 0: Primer, + +W3C Recommendation 2 May 2001 + +Available at _http://www.w3.org/TR/xmlschema-0/_. + +[BLOCH] Joshua Bloch, Effective Java, + +Chapter 3, Typesafe Enums + +_http://developer.java.sun.com/developer/Books/shiftintojavapage1.html#replaceenum_. + +[BLOCH_2] Joshua Bloch, Effective Java, + +Chapter 1, Item 1: Consider factory methods over constructors + +[RFC2396] Uniform Resource Identifiers (URI): +Generic Syntax, + +_http://www.ietf.org/rfc/rfc2396.txt._ + +[XML-RPC] Jakarta XML RPC, + +_https://jakarta.ee/specifications/xml-rpc/_. + +[XML-WS] Jakarta XML Web Services, + +_https://jakarta.ee/specifications/xml-web-services/_. + +[JAXB 1.0] XML Data Binding Specification, + +_https://jcp.org/en/jsr/detail?id=31_ + +[JLS] or [JLS3] The Java Language +Specification, 3rd Edition, Gosling, Joy, Steele, Bracha. + +Available at +_http://java.sun.com/docs/books/jls_. + +[NIST] NIST XML Schema Test Suite, + +_http://xw2k.sdct.itl.nist.gov/xml/page4.html._ + +[MTOM] SOAP Message Transmission Optimization +Mechanism, + +_http://www.w3.org/TR/2004/WD-soap12-mtom-20040608/_. + +[XOP] Martin Gudgin, Noah Mendelsohn, Mark +Nottingham, and Herve Ruellan. XML-binary Optimized Packaging. + +Recommendation, W3C, January 2005. + _http://www.w3.org/TR/xop10/_. + +[MIME] Anish Karmarkar, Ümit Yalçinalp, +"Describing Media Content of Binary Data in XML", + +W3C note, + +_http://www.w3.org/TR/2005/NOTE-xml-media-types-20050504_ + +[WSIAP] Chris Ferris, Anish Karmarkar, and +Canyang Kevin Liu. Attachments Profile Version 1.0. Final 1 Material, +WS-I, April 2006. + +_http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html_. + +[WSIBP] WS-I Basic Profile 1.0, + +_http://www.ws-i.org/Profile/Basic/2003-08/BasicProfile-1.0a.html_ + +[CA] Jakarta Annotations + +_https://jakarta.ee/specifications/annotations/_
diff --git a/spec/src/main/asciidoc/appB-runtime_processing.adoc b/spec/src/main/asciidoc/appB-runtime_processing.adoc new file mode 100644 index 0000000..c060efb --- /dev/null +++ b/spec/src/main/asciidoc/appB-runtime_processing.adoc
@@ -0,0 +1,1073 @@ +// +// Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation +// + +[appendix] +== Runtime Processing + +=== Introduction + +Two of the important goals of Jakarta XML Binding specification are +portability and handling of invalid XML content +(for e.g. schema evolution). These goals imply that a Jakarta XML Binding Provider must +be capable of marshalling and unmarshalling XML instances using Jakarta XML Binding +annotated classes derived using another Jakarta XML Binding Provider. To ensure +portable behavior of Jakarta XML Binding mapped classes across JAXB Providers requires +a specification of runtime processing model of the Jakarta XML Binding binding +framework. + +This appendix specifies the runtime +processing model of XML instances and requirements on Jakarta XML Binding +Provider's runtime. It differs from the documentation found elsewhere in +the specification/javadocs. Chapter 4,"Binding Framework" and the +javadocs for the package jakarta.xml.bind do describe the Jakarta XML Binding binding +framework. But these are written from a Jakarta XML Binding developer perspective +rather than from a Jakarta XML Binding Provider perspective and thus do not +describe requirements on Jakarta XML Binding Provider runtime. This was sufficient +for JAXB 1.0 since portability was not a goal for JAXB 1.0 and schema +derived implementation classes were coupled to the JAXB 1.0 Provider +runtime. However, this is insufficient for Jakarta XML Binding, where portability +and handling invalid XML content are goals. + +=== Scope and Conventions + +==== Scope + +This appendix describes marshalling and unmarshalling. + +==== Format + +The specification uses the following for +specifying runtime behavior: + +* XML Infoset, Second Edition, +http://www.w3.org/TR/xml-infoset augmented with attributes xsi:type and +xsi:nil that can be used by a document author. +* XML Schema abstract schema component model. +* JAXB defined annotations as needed + +==== Notations + +The following notations/conventions are used: + +* For brevity, property is used but is used +to mean JavaBean property or a field. +* XML Infoset properties that are associated +with an information item are enclosed in [...], for e.g. AII.[local +name]. And program elements the constitute the Java representation to +which an information item are identified as for e.g. AII.valuetype. +* *AII: Attribute Information Item in XML Infoset* +* AII.[local name] : local name property in infoset for AII +* AII.[namespace] : namespace property in infoset for AII +* AII.[owner element] : owner element in infoset for AII +* AII.[normalized value]: normalized value in inforset for AII +* AII.property : JAXB property to which AII +is mapped. The property in in the java type to which AII.[owner element] +is mapped. +* AII.valuetype: Java type representing the XML serialized for AII. +* AII.boundtype: Java type that is bound; +this differs from AII.valuetype only if JAXB property is associated with +a @XmlJavaTypeAdapter. +* AII.schematype : schema type to which AII +is bound statically using Java -> XML schema mapping rules. +* *EII: Element Information Item in infoset* +* EII.[local name] : local name property in XML infoset for EII +* EII.[namespace] : namespace property in XML infoset for EII +* EII.[children]: children property in XML infoset for EII +* EII.[parent]: parent property in XML infoset for EII +* EII.property : JAXB property to which EII +is mapped. The property is in the javatype to which EII.[parent] is +mapped. +* EII.valuetype : java type representing the XML serialized for EII +* EII.boundtype : java type that is bound; +this differs from EII.valuetype only if JAXB property is associated with +a @XmlJavaTypeAdapter. +* EII.schematype : schema type to which EII +is bound statically using java -> XML schema mapping rules. +* EII.xsitype : the xsi:type specified in the +XML instance by a document author. null if no xsi:type was specified. +* EII.xsinil : the xsi:nil specified in the +XML instance by a document author. null if no xsi:nil was specified. + +=== Unmarshalling + +This section specifies the runtime behavior +and JAXB provider requirements related to unmarshalling. The +specification includes unmarshalling of invalid XML content in an XML +instance. + +This section specifies only flexible, standard unmarshalling (flexible +because unmarshalling deals with invalid XML content). Other +unmarshalling modes will not be specified. Flexible unmarshalling +specified here must be supported by all JAXB Providers. + +The unmarshalling methods in the binding +framework fall into the following categories: + +. Unmarshal methods that do not take a declaredType as parameter: ++ +[source,java,indent="4"] +---- +jakarta.xml.bind.Unmarshaller.unmarshal(...) +jakarta.xml.bind.Binder.unmarshal(...) +---- +. Unmarshal methods that take a declaredType as a parameter: ++ +[source,java,indent="4"] +---- +jakarta.xml.bind.Unmarshaller.unmarshal(..., java.lang.Class<T> declaredType) +jakarta.xml.bind.Binder.unmashal(..., java.lang.Class<T> declaredType) +---- +The unmarshal methods that do not take +declaredType as parameter must be unmarshalled as specified in +<<globally-declared-root-element>>. + +The unmarshal methods that take a +`declaredType` as a parameter must be unmarshalled as specified in +<<declared-type>>. + +==== Globally Declared Root Element + +There are two ways that a root element can be +represented in Java representation: + +* as an element instance factory method that +is generated in the public ObjectFactory class of a package when a +schema is compiled. An element instance factory method is annotated with +a @XmlElementDecl annotation. For e.g. ++ +[source,java,indent="4"] +---- +public class ObjectFactory { + @XmlElementDecl(...) + public JAXBElement<T> createFoo(T elementValue); + ... + } +---- +* as a type (either an enum type or a class) +that has been annotated with @XmlRootElement. For e.g. ++ +[source,java,indent="4"] +---- +@XmlRootElement(...) +public class Foo {...} +---- + +The unmarshalling of XML content results in a +content tree with a root that is an instance of either a `JAXBElement` +instance or a type that is annotated with `@XmlRootElement`. The +content tree must be created as follows: + +. lookup an element factory method in the ObjectFactory class matching on: ++ +EII.[namespace] == @XmlElementDecl.namespace() && EII.[local name] == @XmlElementDecl.name() +or for a type annotated with @XmlRootElement matching on: +EII.[namespace] == @XmlRootElement.namespace() && EII.[local name] == @XmlRootElement.name() ++ +[NOTE] +.Note +==== +The lookup will only find one of the +above not both. If both a type as well as an element factory method were +found, it would be flagged as an error when JAXBContext is created. +==== +. if an element factory method in the +ObjectFactory class or a type annotated with @XmlRootElement is found, +then determine the _valueType_. +.. if an element factory method is found, +there is no @XmlJavaTypeAdapter associated with the value parameter to +the element factory method, then the valueType is the java type of the +value parameter to the element factory method. For e.g. ++ +[source,java,indent="4"] +---- +@XmlElementDecl(name = "bar", namespace = "") +public JAXBElement<Foo> createBar(Foo value) { + return new JAXBElement<Foo>( + _Bar_QNAME, ((Class) Foo.class), null, value); +} +---- +the _valueType_ type is Foo. ++ +[NOTE] +.Note +==== +For ease of understanding the code generated by the Sun JAXB RI implementation +has been shown above. But the implementation could be JAXB Provider dependent. +==== ++ +if the parameter is associated with @XmlJavaTypeAdapter, then the _valueType_ +is the java type specified in @XmlJavaTypeAdapter.value(). + +.. if a type annotated with @XmlRootElement is +found then _valueType_ is the type. For e.g. ++ +[source,java,indent="4"] +---- +@XmlRootElement(...) +public class Foo {...} +---- ++ +[NOTE] +.Note +==== +@XmlRootElement and @XmlJavaTypeAdapter are mutually exclusive. +==== ++ +Go to step 4, "Check for type substitution" + +. If neither the element factory method nor a +type annotated with @XmlRootElement is found, then the element is +unknown. Set _valueType_ of the element to null. ++ +Even though the element is unknown, a +document author can still perform type substitution. This case can arise +if the XML schema contains only schema types and no global elements. For +e.g a document author could have specified a xsi:type that has been +mapped by JAXB. For e.g. ++ +[source,xml,indent="4"] +---- + <unknownElement xsi:type="PurchaseOrder"/> +---- +So goto step 4, "Check for type substitution" + +. "Check for type substitution" +.. if `xsi:type` is not specified, and the +_valueType_ is null (i.e. the root element is unknown and we got to this +step from step 3), throw a `jakarta.xml.bind.UnmarshalException` and +terminate processing. +.. otherwise, if `xsi:type` is specified, but +is not mapped to a JAXB mapped type (e.g. class is not marked with +@XmlType declaration), then throw a `jakarta.xml.bind.UnmarshalException` +and terminate processing. +.. otherwise, if `xsi:type` is specified, and is +mapped to a JAXB mapped type set the _valueType_ to the javatype to which +xsi:type is mapped. +.. otherwise, `xsi:type` is not specified; _valueType_ is unchanged. +. Unmarshal _valueType_ as specified in <<value-type>>. +. If the element factory method is annotated +with @XmlJavaTypeAdapter, then convert the _valueType_ into a _boundType_ ++ +[source,java] +---- +boundType = @XmlJavaTypeAdapter.value().unmarshal(valueType) +---- +. Determine the content root type to be returned by unmarshal() method. +.. if the element lookup returned an element +instance factory method, then create a JAXBElement instance using the +_boundType_. The content root type is the JAXBElement instance. +.. otherwise, if the element lookup returned a +type annotated with @XmlRootElement, then the content root type is the +_boundType_. +.. otherwise, the element is an unknown +element. Wrap the _boundType_ using JAXBElement with an element name in +the XML instance document (e.g. "unknown Element"). The content root +type is the JAXBElement instance. +. return the content root type. + +==== Declared Type + +The unmarshalling process described in this +section must be followed for the unmarshal methods that take a +`declaredType` as a parameter. + +. Determine the _valueType_ to be unmarshalled +as follows: +.. if `xsi:type` is specified, but is not +mapped to a JAXB mapped type, then throw a +`jakarta.xml.bind.UnmarshalException` and terminate processing. +.. otherwise if `xsi:type` is specified and is +mapped to JAXB mapped type, then _valueType_ is the JAXB mapped type. +.. otherwise _valueType_ is the argument passed +to `declaredType` parameter in the +`unmarshal(..., java.lang.Class<T>declaredType)` call. +. Unmarshal _valueType_ as specified in <<value-type>>. + +==== Value Type + +The following steps unmarshal either +EII.valuetype or AII.valuetype, depending upon whether an EII or AII is +being unmarshalled. + +[NOTE] +.Note +==== +Whether an EII or AII is being +unmarshalled is determined by the "caller" of this section. +AII.valuetype and EII.valuetype are assumed to be set by the time this +section entered. +==== + +. If an instance of _valueType_ does not exist, +create an instance of _valueType_ as follows (for e.g. if a value of a +property with type `java.util.List` is non null, then unmarshal the +value into that `java.util.List` instance rather than creating a new +instance of `java.util.List` and assigning that to the property): +.. if _valueType_ is a class and is the type +parameter specified in the element factory method, then instantiate the +class using element factory method; otherwise instantiate the class +using factory method if specified by `@XmlType.factoryClass()` and +`@XmlType.factoryMethod()` or if there is no factory method, using the +no-arg constructor. +.. if _valueType_ is an enum type, then obtain +an instance of the enum type for the enum constant annotated with +`@XmlEnumValue` and `@XmlEnumValue.value()` matches the lexical +representation of the EII. +. Invoke any event callbacks in the following order as follows: +.. If _valueType_ implements an unmarshal event +callback `beforeUnmarshal(..)` as specified in Section 4.4.1,"Unmarshal +Event Callback", then invoke `beforeUnmarshal(..)`. +.. If `Unmarshaller.getListener()` returns +`Unmarshaller.Listener` that is not `null`, then invoke +`Unmarshaller.Listener.beforeUnmarshal(..)`. +. If an EII.valuetype is being unmarshalled, +unmarshal into this instance the following. Note: The following steps +can be done in any order; the steps are just broken down and listed +separately for clarity: ++ +If EII.valueType being unmarshalled + +.. unmarshal each child element information +item in EII.[children] as specified in <<element-information-item>>. +.. unmarshal each attribute information item +in EII.[attributes] as specified in <<attribute-information-item>>. +. Unmarshal the value of EII.schematype or +AII.schematype following the Java to XML Schema rules defined in Chapter +8, "Java Types to XML". If the value in XML instance is unparseable, +then it must be handled as specified in <<Unparseable Data for Simple types>>. +. Invoke any event callbacks in the following order as follows: +.. If _valueType_ implements an unmarshal event +callback `afterUnmarshal(..)` as specified in Section 4.4.1,"Unmarshal +Event Callback, then invoke `afterUnmarshal(..)`. +.. If `Unmarshaller.getListener()` returns +`Unmarshaller.Listener` that is not `null`, then invoke +`Unmarshaller.Listener.afterUnmarshal(..)`. +. return // either AII.valuetype or +EII.valuetype. + +==== Element Information Item + +An EII must be unmarshalled as follows: + +. infer EII.property as specified in <<property-inference-element-information-item>>. +. if EII.property is null, then there is no +property to hold the value of the element. If validation is on (i.e. +Unmarshaller.getSchema() is not null), then report a +jakarta.xml.bind.ValidationEvent. Otherwise, this will cause any unknown +elements to be ignored. ++ +If EII.property is not null and there is no +setter method as specified in section <<getterssetters>> +then report a jakarta.xml.bind.ValidationEvent. ++ +Goto step 8. + +. infer the EII.valuetype as described in <<type-inference-element-information-item>>. +. if EII.valuetype is null, then go to step 8. ++ +[NOTE] +.Note +==== +EII.valuetype = null implies that there +was problem. so don't attempt to unmarshal the element. +==== +. Unmarshal EII.valuetype as specified in <<value-type>>. +. if there is a @XmlJavaTypeAdapter +associated with EII.property, then adapt the EII.valuetype as follows: ++ +-- +[source,java] +---- +EII.boundtype = @XmlJavaTypeAdapter.value().unmarshal(EII.valuetype) +---- +otherwise +[source,java] +---- +EII.boundtype = EII.valuetype +---- +-- +. set the value of EII.property to EII.boundtype as follows: ++ +-- +Wrap EII.boundtype into a jakarta.xml.bind.JAXBElement instance if: + +.. the property is not a collection type and +its type is jakarta.xml.bind.JAXBElement +.. the property is a collection type and is a +collection of JAXBElement instances (annotated with @XmlElementRef or +@XmlElementRefs) +-- ++ +-- +If EII.property is not a collection type: + +.. set the value of EII.property to EII.boundtype. +-- ++ +If EII.property is collection type: + +.. add EII.boundtype to the end of the collection. + ++ +[NOTE] +.Note +==== +Adding JAXBElement instance or a type +to the end of the collection preserves document order. And document +order could be different from the order in XML Schema if the instance +contains invalid XML content. + +==== + +. return + +==== Attribute Information Item + +An attribute information item must be unmarshalled as follows: + +. infer AII.property as described in section +<<property-inference-attribute-information-item>>. +. if AII.property is null, then the attribute +is invalid with respect to the XML schema. This is possible if for e.g. +schema has evolved. If validation is on (i.e. Unmarshaller.getSchema() +is not null), then report a jakarta.xml.bind.ValidationEvent. Otherwise, +this will cause any unknown elements to be ignored. ++ +If AII.property is not null and there is no +setter method as specified in section <<getterssetters>> +then report a jakarta.xml.bind.ValidationEvent. ++ +Goto step 8. + +. infer the AII.valuetype as described in +<<type-inference-attribute-information-item>>. +. if AII.valuetype is null, then go to step 8. ++ +[NOTE] +.Note +==== +AII.valuetype = null implies that there +was problem. so don't attempt to unmarshal the attribute. +==== +. Unmarshal AII.valuetype as specified in <<value-type>>. +. If AII.property is associated with a +`@XmlJavaTypeAdapter`, adapt AII.valuetype as follows: ++ +[source,java] +---- +AII.boundtype = @XmlJavaTypeAdapter.value().unmarshal(AII.valuetype) +---- +otherwise ++ +[source,java] +---- +AII.boundtype = AII.valuetype +---- +. If AII.property is single valued: +.. set the value of AII.property to AII.boundtype. ++ +If AII.property is a collection type (e.g. +List<Integer> was mapped to a Xml Schema list simple type using @XmlList +annotation): ++ +add EII.boundtype to the end of the collection. +. return + +==== Property Inference + +Unmarshalling requires the inference of a +property or a field that contains the value of EII and AII being +unmarshalled. + +===== Property Inference - Element Information Item + +The property to which an EII is mapped is +inferred based on name. + +[NOTE] +.Note +==== +Inferring the property to which the EII is mapped by name rather than +it’s position in the content model within the schema is key to +dealing with invalid XML content. +==== + +Infer EII.property by matching constraints described below: + +. initialize EII.property to null +. if property is mapped to XML Schema element +declaration, elem, in the content model of EII.[parent].schematype && +EII.[local name] == elem.{name} && EII.[namespace] == elem.{namespace} +set EII.property to property. ++ +Goto step 4. + +. If there is a JAXB property mapped to XML +Schema wildcard (`xs:any`) (as determined by `@XmlAnyElement`), set +this JAXB property to EII.property. This property will hold wildcard +content (e.g. invalid XML content caused by schema evolution). +. return EII.property + +===== Property Inference - Attribute Information Item + +Infer the property for the AII by matching +constraints described below: + +. initialize AII.property to null +. if property mapped to XML Schema attribute +declaration, attr, in the content model of AII.[owner].schematype && +AII.[local name] == attr.{name} && AII.[namespace] == attr.{namespace} +set AII.property to property ++ +Goto step 4. + +. if there is a property mapped to a XML +Schema `xs:anyAttribute` (i.e. annotated with `@XmlAnyAttribute`), then +set this property to AII.property. This property holds XML content +matching wildcard attribute (`xs:anyAttribute`) or unknown attributes +(which can occur for e.g. if schema has evolved). +. return AII.property + +==== Type Inference + +Unmarshalling requires the inference of the +type of a property or a field that to contain the value of EII and AII +being unmarshalled. + +===== Type Inference - Element Information Item + +This section describes how to infer EII.valuetype; +this holds the value of the element (content model + attributes). + +EII.valuetype must be inferred as described below: + +. initialize EII.valuetype to null. +. if EII.xsitype is set, document author has +performed type substitution. ++ +Goto step 4 to handle type substitution. +. if EII.schematype is not mapped to a java type, then +.. report a validation event. +.. Go to step 7. + ++ +otherwise +.. set EII.valuetype to the javatype to which +EII.schematype is mapped. +.. Go to step 7. ++ +[NOTE] +.Note +==== +This case can arise for example, when +EII.schematype is compiled into a java type at schema compilation time, +but the javatype was not registered with `JAXBContext.newInstance(..)`. +==== + ++ +. check if EII.xsitype is mapped to a JAXB +mapped type. It is possible that EII.xsitype is compiled to a javatype +at schema compilation time, but the javatype was not registered with +`JAXBContext.newInstance(..)` ++ +If EII.xsitype is not mapped, then report a +validation event. ++ +Goto step 7. + +. check if the java type to which EII.xsitype +is mapped is assignment comparable with the static type of the +property/field if no `@XmlJavaTypeAdapter` is associated with the +property/field or with the `valueType` specified in +`XmlAdapter<valueType, boundType>` if a `@XmlJavaTypeAdapter` is +associated with the property/field. ++ +The above check can fail for e.g when a +document author attempts to substitute a complex type that derives from +simple type but customization to enable simple type substitution was not +used. For e.g. + +.. {nbsp} ++ +[source,xml,indent="2"] +---- +<!-- local element with simple type --> +<xs:element name="foo" type="xs:int"/> + +<!-- complex type for substituting the simple type --> +<xs:complexType name="MyInt"> + <xs:extension xs:int> + ...add attributes + </xs:extends> +</xs:complexType> +---- +.. customization to handle type substitution +of simple types is not used. So the property is ++ +[source,java,indent="4"] +---- +public int getFoo(); +public void setFoo(int); +public class MyInt {...} +---- +.. the document author attempts to substitute complexType MyInt. ++ +[source,xml,indent="2"] +---- + <foo xsi:type="MyInt"/> +---- +.. The type MyInt is not assignment comparable with int. +. set EII.valuetype to javatype to which EII.xsitype is mapped. ++ +[NOTE] +.Note +==== +If we got to this step, this implies that type substitution is valid. +==== +. return EII.valuetype + +===== Type Inference - Attribute Information Item + +Infer the AII.valuetype as follows: + +. initialize AII.valuetype to null. +. if AII.schematype is not mapped to a java +type, then report a validation event. Otherwise, set AII.valuetype to +the java type to which AII.schematype is mapped. ++ +[NOTE] +.Note +==== +This case can arise for example, when +AII.schematype is compiled into a java type at schema compilation time, +but the java type is not registered with the `JAXBContext.newInstance(..)` +==== +. return AII.valuetype + +==== Invalid XML Content + +===== Unparseable Data for Simple types + +If simple type data cannot be parsed into a +java datatype, then the value of the java datatype must not change the +current set value. An access to the datatype must return the value as +specified in <<missing-element-information-item>>. +If the conversion of lexical representation into a +value results in an exception, then the exception must be caught and a +validation event reported. This is to ensure that such conversion errors +do not terminate unmarshalling. + +[source,xml,indent="2"] +---- +<!-- Example: XML Schema fragment --> +<xs:element name="foo" type="xs:int"/> +---- +[source,xml,indent="2"] +---- +<!-- Example: XML instance. + Data is not parseable into type xs:int; + however unmarshal will still succeed. --> +<foo> SUN </foo> +---- + +===== Missing element information item + +This case arises when an element declaration +required by a XML schema is missing from the XML instance. + +Property or field access must return the +value specified in <<value-for-missing-elementsattributes>>. + +===== Missing Attribute + +This case arises when a property or a field +is mapped to an XML attribute but the attribute is missing from the XML +instance. + +Property or field access must return the +value specified in <<value-for-missing-elementsattributes>>. + +===== Value for missing elements/attributes + +If an attribute or an element is missing from +an XML instance, then unmarshal will not change the current set value. +An access to the property will return the set value or if unset, the +uninitialized value. The uninitialized value of the property or field +depends upon it's type. If the type is + +. int - value is 0 +. boolean - value is false +. a reference (must be mapped to a simple type) - value is null. +. float - the value is +0.0f +. double - the value is 0.0d +. short - the value is (short) 0 +. long - the value is 0L + +[NOTE] +.Note +==== +The uninitialized values are returned +only if the value is not set. A value could be set for example in a +validation handler that catches the validation event. +==== + +===== Unknown Element + +In this case, XML instance contains EII for +which there is no corresponding element declaration in the XML schema. +If the valuetype to which the EII.parent maps contains a property/field +annotated with `@XmlAnyElement`, this EII can be unmarshalled into the +property/field. + +Unknown attribute handling during +unmarshalling is specified in <<property-inference-element-information-item>>. + +===== Unknown attribute + +In this case, XML instance contains AII for +which there is no corresponding attribute declaration in the XML schema. +If the valuetype to which the AII.parent maps contains a property/field +annotated with `@XmlAnyAttribute`, the AII can be unmarshalled into the +property/field. + +Unknown attribute handling during +unmarshalling is specified in <<property-inference-attribute-information-item>>. + +=== Marshalling + +To marshal a content tree, a JAXB application invokes one of the following marshal methods: + +[source,java,indent="4"] +---- +Marshaller.marshal(Object jaxbElement, ...) throws JAXBException; +Binder.marshal(Object jaxbObject, ...) throws JAXBException; +---- + +A JAXB Provider must marshal the content tree as follows: + +* marshal the XML root element tag as +specified in <<xml-root-element-tag>> +* marshal `obj` as specified in section +<<type>>. + +==== XML Root Element Tag + +. If `obj` is an instance of +`jakarta.xml.bind.JAXBElement` then marshal `obj` as specified in +<<jaxbelement>> ++ +Goto step 4 + +. If `obj.getClass()` is annotated with +`@XmlRootElement`, then set {EII.[local name], EII.[namespace]} by +deriving them from the @XmlRootElement annotation following the Java to +Schema mapping rules in chapter 8. Marshal obj instance as specified in +<<type>>. ++ +Goto step 4 + +. If obj has neither an @XmlRootElement nor +is a JAXBElement instance, then throw a `JAXBException` and terminate +processing. +. done + +==== Type + +The type must be marshalled as follows. If the type is an instance of + +* JAXBElement, then marshal as specified in <<jaxbelement>>. +* Otherwise, marshal the type as follows. If +the type is a: +** class, then marshal as specified in +<<class-2>>. +** primitive type or standard class, then +marshal as specified in <<primitives-and-standard-classes>> +** enum type then marshal following the schema +to which it is mapped. + +===== JAXBElement + +An `obj`, that is an instance of +`jakarta.xml.bind.JAXBElement` must be marshalled as specified here: + +. `JAXBElement jaxbelem = (JAXBElement) obj;` +. set {EII.[local name] , EII.[namespace]} to `jaxbelem.getName()` +. if `jaxbelem.isNil()`, add `xsi:nil` to EII.[attributes] ++ +[NOTE] +.Note +==== +It is valid for a content model that is nil to have attributes. For e.g. +[source,xml,indent="2"] +---- +<foo xsi:nil attr1="1"/> +---- +The attributes will be marshalled when the value that the JAXBElement wraps is marshalled. +==== + +. if `jaxbelem.isTypeSubstituted()` is true, +then type substitution has occurred i.e. `jaxbelem.getDeclaredType()` +(static type) is different from `jaxbelem.getValue()` (the type of the +value for this instance). So, +.. EII.[local name] = "type" +.. EII.[prefix] = "xsi" +.. EII.[normalized value] = QName of the +schema type to which `jaxbelem.getValue()` is mapped following +Java -> Schema mapping rules in Chapter 8. For e.g. ++ +[source,xml,indent="2"] +---- +<foo xsi:type="MyAddrType"/> +---- +. set _boundType_ to jaxbelem.getValue() if +jaxbelem.isTypeSubstituted() is true otherwise +jaxbelem.getDeclaredType() +. determine the _valueType_ to be marshalled. +If the program element being processed is associated with +@XmlJavaTypeAdapter then _boundType_ is ++ +[source,java,indent="2"] +---- +valueType = @XmlJavaTypeAdapter.value().marshal(boundType) +---- +otherwise _valueType_ is _boundType_ + +. map _valueType_ to XML infoset information +items as specified in <<type>> and add +them to EII. +. marshal EII. + +===== class + +A class must be mapped to XML infoset items as follows: + +. If a class mapped to a value as specified <<xmlvalue>>, +then map the value to an XML infoset and add it to EII.[children] ++ +return + +. For each property that is mapped to XML +attribute as specified in <<xmlattribute>>: +.. derive {AII.[local name], AII.[prefix], +AII.[namespace] } from {name} {target namespace}. +.. AII.[normalized value] = value of property +as specified in <<property-type>> +.. add AII to EII.[attributes] ++ +[NOTE] +.Note +==== +There order in which the properties are +marshalled is not specified (XML attributes are unordered by XML +Schema). +==== + +. For each property that is mapped to an XML +element declaration, elem: +.. derive {childEII.[local name], +childEII.[prefix], childEII.[namespace]} from elem.{name} +elem.{target namespace} +.. map property type to XML infoset items into +childEII as specified in <<property-type>>. +.. add childEII to EII.[children] + +===== property type + +The value of a property with type , _boundType_, +must be marshalled into childEII (set by "caller of this +section") as follows: + +. If property does not have a getter method +as specified in section <<getterssetters>> +then report a jakarta.xml.bind.ValidationEvent. ++ +Goto step 4. +. If the value of the property being marshalled is a subtype _boundType_, then +.. EII.[local name] = "type" +.. EII.[prefix] = "xsi" +.. EII.[normalized value] = QName of the +schema type to which `jaxbelem.getValue()` is mapped following +Java -> Schema mapping rules in Chapter 8. For e.g. ++ +[source,xml,indent="2"] +---- +<foo xsi:type="MyAddrType"/> +---- +.. add EII to childEII +. Marshal the value as specified in <<type>>. +. Return + +===== Primitives and Standard classes + +Primitive values and standard classes +described in this section map to XML schema simple types. + +The value of a primitive type or a standard +class must be marshalled to a lexical representation or unmarshalled +from a lexical representation as specified in the below: + +* using a print or parse method in +jakarta.xml.bind.DatatypeConverter interface: ++ +Many of the types have a corresponding print +and parse method in jakarta.xml.bind.DatatypeConverter interface for +converting a value to a lexical representation in XML and vice versa. +The implementation of DatatypeConverter is JAXB Provider specific. ++ +A XML Schema simple type can have more than +lexical representation (e.g. "true" "false" "0" "1"). Since the +DatatypeConverter implementation is JAXB Provider specific, the exact +lexical representation that a value is marshalled to can vary from one +JAXB Provider to another. However, the lexical representation must be +valid with respect to the XML Schema. + +* some data types such as +XMLGregorianCalendar contain methods on the class that return or consume +their XML lexical representation. For such datatypes, the method +indicated in the table is used. +* A wrapper class (e.g. java.lang.Integer) +must be converted to its non wrapper counterpart (e.g. int) and then +marshalled. + + +.Lexical Representation of Standard Classes +[cols=",,",options="header"] +|=== +| Java Standard Classes | printMethod | parseMethod +| `java.lang.String` | `printString` | `parseString` +| `java.util.Calendar` | `printDateTime` | `parseDateTime` +| `java.util.Date` | `printDateTime` | `parseDateTime` +| `java.net.URI` | `URI.toString()` | `URI(String str)` + +| `javax.xml.datatype.XMLGregorianCalendar` | `XMLGregorianCalendar +.toXMLFormat()` +| `DatatypeFactory. +newXMLGregorianCalendar(String lexicalRepresentation)` + +| `javax.xml.datatype.Duration` | `Duration.toString()` +| `DatatypeFactory.newDuration(String lexicalRepresentation)` + +| `java.util.UUID` | `UUID.toString()` | `UUID.fromString()` +|=== + +===== Null Value + +A null value in Java representation can be +marshalled either as an absence of an element from an XML instance or as +`xsi:nil`. The marshalled value depends upon the values of +`@XmlElement.required()` and `@XmlElement.nillable()` annotation +elements on the property/field and must be marshalled as shown below. +For clarity, example schema fragments (as determined by the mapping +rules specified in Chapter 8) for the following field + +[source,java,indent="4"] +---- +@XmlElement(required="...", nillable="...") +foo; +---- + +are reproduced here along with the XML representation for null value produced by marshalling. + +* `@XmlElement(required=true, nillable=false)` ++ +The value of the property/field cannot be null. ++ +[source,xml,indent="2"] +---- +<!-- Example: Generated schema --> +<xs:element name="foo" minOccurs="1" ...> + ... +</xs:element> +---- +* `@XmlElement(required=true, nillable=true)` ++ +null is marshalled as `xsi:nil="true"` ++ +[source,xml,indent="2"] +---- +<!-- Example: Generated schema --> +<xs:element name="foo" minOccurs="1" nillable="true" ...> + ... +</xs:element> + +<!-- marshalled XML representation for null value --> +<foo xsi:nil="true" .../> +---- +* `@XmlElement(required=false, nillable=true)` ++ +null is marshalled as `xsi:nil="true"` ++ +[source,xml,indent="2"] +---- +<!-- Example: Generated schema --> +<xs:element name="foo" minOccurs="0" ...> + ... +</xs:element> + +<!-- Example: marshalled XML representation for null value --> +<foo xsi:nil="true" .../> +---- +* `@XmlElement(required=false, nillable=false)` ++ +null is not marshalled i.e it maps to absence +of an element from XML instance. ++ +[source,xml,indent="2"] +---- +<!-- Example: Generated schema --> +<xs:element name="foo" minOccurs="0" ...> + ... +</xs:element> + +<!-- Example: null value for foo not marshalled --> +---- + +=== Getters/Setters + +When `@XmlAccessType.PUBLIC_MEMBER` or +`@XmlAccessType.PROPERTY` is in effect for a class, then the instance of +the class is marshalled using getter/setter methods as opposed to +fields. This section outlines the constraints the must be checked at +runtime. A constraint failure is handled as specified elsewhere in the +chapter from where this section is referenced. + +*_Unmarshalling:_* A property must have a setter method if + +* `@XmlAccessorType.PUBLIC_MEMBER` or +`@XmlAccessorType.PROPERTY` applies to the property. +* or if the property’s getter/setter method +is annotated with a mapping annotation. + +The one exception to the above constraint is: +if property type is `java.util.List` then only a getter method is +required. + +[NOTE] +.Design Note +==== +For a JavaBean property with getter/setter methods, a setter method is required for +unmarshalling when public API (as opposed to fields) is used +i.e. either `@XmlAccessorType.PUBLIC_MEMBER` or `@XmlAccessorType.PROPERTY` +is in effect. If `@XmlAccessorType.FIELD` is in effect, then unmarshalling is +based on fields and hence a setter method is not required. +There is however one exception. + +When starting from schema, a schema component (e.g. a repeating occurrence of an element) +can be bound to a `java.util.List` property (so modifications to `java.util.List` +can be intercepted, a design decision from JAXB 1.0). Thus only in this case +a setter method is not required. E.g. + +[source,java,indent="4"] +---- +public java.util.List getFoo(); +// public void setFoo(..) not required +---- +==== + +*_Marshalling:_* A property must have a getter method if + +* `@XmlAccessType.PUBLIC_MEMBER` or +`@XmlAccessType.PROPERTY` applies to the class +* or if the property’s getter/setter method +is annotated with a mapping annotation.
diff --git a/spec/src/main/asciidoc/appC-normative_schema.adoc b/spec/src/main/asciidoc/appC-normative_schema.adoc new file mode 100644 index 0000000..73d3a5f --- /dev/null +++ b/spec/src/main/asciidoc/appC-normative_schema.adoc
@@ -0,0 +1,471 @@ +// +// Copyright (c) 2020 Contributors to the Eclipse Foundation +// + +[appendix] +== Normative Binding Schema Syntax + +=== XML Binding Schema + +Online version of XML Binding Schema is available at `https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd`. + +[source,xml] +---- +<xs:schema + targetNamespace = "https://jakarta.ee/xml/ns/jaxb" + xmlns:jaxb = "https://jakarta.ee/xml/ns/jaxb" + xmlns:xs = "http://www.w3.org/2001/XMLSchema" + elementFormDefault = "qualified" + attributeFormDefault = "unqualified"> + <xs:annotation> + <xs:documentation> + This is the XML Schema for the Jakarta XML Binding binding + customization descriptor. + All binding customization descriptors must indicate + the descriptor schema by using the Jakarta XML Binding namespace: + + https://jakarta.ee/xml/ns/jaxb + + and by indicating the version of the schema by + using the version element as shown below: + + <bindings xmlns="https://jakarta.ee/xml/ns/jaxb" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://jakarta.ee/xml/ns/jaxb + https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd" + version="3.0"> + ... + </bindings> + + The instance documents may indicate the published version of + the schema using the xsi:schemaLocation attribute for Jakarta XML Binding + namespace with the following location: + + https://jakarta.ee/xml/ns/jaxb/bindingschema_3_0.xsd + </xs:documentation> + </xs:annotation> + <xs:group name = "declaration"> + <xs:annotation> + <xs:documentation> + Model group that represents a binding declaration. Each new binding + declaration added to the jaxb namespace that is not restricted to + globalBindings should be added as a child element to this model group. + </xs:documentation> + </xs:annotation> + <xs:choice> + <xs:element ref = "jaxb:globalBindings"/> + <xs:element ref = "jaxb:schemaBindings"/> + <xs:element ref = "jaxb:class"/> + <xs:element ref = "jaxb:property"/> + <xs:element ref = "jaxb:typesafeEnumClass"/> + <xs:element ref = "jaxb:typesafeEnumMember"/> + <xs:element ref = "jaxb:javaType"/> + <xs:element ref = "jaxb:dom"/> + <xs:element ref = "jaxb:inlineBinaryData"/> + <xs:any namespace = "##other" processContents = "lax"/> + </xs:choice> + </xs:group> + <xs:attribute name = "version" type="xs:token" > + <xs:annotation> + <xs:documentation> + Used to specify the version of the binding schema on the schema element for + inline annotations or jaxb:bindings for external binding. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attributeGroup name = "propertyAttributes"> + <xs:annotation><xs:documentation> + Attributes used for property customization. The attribute group can be + referenced either from the globalBindings declaration or from the + property declaration. The following defaults are defined by the JAXB + specification in global scope only. Thus they apply when the + propertyAttributes group is referenced from the globalBindings declaration + but not when referenced from the property declaration. + collectionType a class that implements java.util.List. + fixedAttributeAsConstantProperty false + enableFailFastCheck false + generateIsSetMethod false + optionalProperty wrapper + generateElementProperty false + attachmentRef default + </xs:documentation></xs:annotation> + <xs:attribute name = "collectionType" type="jaxb:referenceCollectionType"/> + <xs:attribute name = "fixedAttributeAsConstantProperty" type = "xs:boolean"/> + <xs:attribute name = "enableFailFastCheck" type = "xs:boolean"/> + <xs:attribute name = "generateIsSetMethod" type = "xs:boolean"/> + <xs:attribute name = "optionalProperty"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="wrapper"/> + <xs:enumeration value="primitive"/> + <xs:enumeration value="isSet"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "generateElementProperty" type="xs:boolean"/> + <xs:attribute name = "attachmentRef"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="resolve"/> + <xs:enumeration value="doNotResolve"/> + <xs:enumeration value="default"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + </xs:attributeGroup> + <xs:attributeGroup name = "XMLNameToJavaIdMappingDefaults"> + <xs:annotation> + <xs:documentation>Customize XMLNames to Java id mapping + </xs:documentation> + </xs:annotation> + <xs:attribute name = "underscoreBinding" default = "asWordSeparator" type = "jaxb:underscoreBindingType"/> + </xs:attributeGroup> + <xs:attributeGroup name = "typesafeEnumClassDefaults"> + <xs:attribute name = "typesafeEnumMemberName" default = "skipGeneration" type = "jaxb:typesafeEnumMemberNameType"/> + <xs:attribute name = "typesafeEnumBase" default = "xs:string" type = "jaxb:typesafeEnumBaseType"/> + <xs:attribute name = "typesafeEnumMaxMembers" type="xs:int" default="256"/> + </xs:attributeGroup> + <xs:element name = "globalBindings"> + <xs:annotation> + <xs:documentation>Customization values defined in global scope.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence minOccurs = "0"> + <xs:element ref = "jaxb:javaType" minOccurs = "0" maxOccurs = "unbounded"/> + <xs:element ref = "jaxb:serializable" minOccurs = "0"/> + <xs:any namespace = "##other" processContents = "lax"> + <xs:annotation> + <xs:documentation>allows extension binding declarations to be specified.</xs:documentation> + </xs:annotation> + </xs:any> + </xs:sequence> + <xs:attributeGroup ref = "jaxb:XMLNameToJavaIdMappingDefaults"/> + <xs:attributeGroup ref = "jaxb:typesafeEnumClassDefaults"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + <xs:attribute name="generateValueClass" type="xs:boolean" + default= "true"/> + <xs:attribute name="generateElementClass" type="xs:boolean" + default= "false"/> + <xs:attribute name="mapSimpleTypeDef" type="xs:boolean" + default= "false"/> + <xs:attribute name="localScoping" default= "nested"> + <xs:simpleType> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="nested"/> + <xs:enumeration value="toplevel"/> + </xs:restriction> + </xs:simpleType> + </xs:attribute> + <xs:attribute name = "enableJavaNamingConventions" default = "true" type = "xs:boolean"/> + <xs:attribute name = "choiceContentProperty" default = "false" type = "xs:boolean"/> + </xs:complexType> + </xs:element> + <xs:element name = "schemaBindings"> + <xs:annotation> + <xs:documentation>Customization values with schema scope</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "package" type = "jaxb:packageType" minOccurs = "0"/> + <xs:element name = "nameXmlTransform" type = "jaxb:nameXmlTransformType" minOccurs = "0"/> + </xs:all> + </xs:complexType> + </xs:element> + <xs:element name = "class"> + <xs:annotation> + <xs:documentation>Customize interface and implementation class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Java class name without package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "implClass" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>Implementation class name including package prefix.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="generateValueClass" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Default value derived from [jaxb:globalBindings]@generateValueClass.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "property"> + <xs:annotation> + <xs:documentation>Customize property.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:all> + <xs:element name = "javadoc" type = "xs:string" minOccurs="0"/> + <xs:element name = "baseType" type="jaxb:propertyBaseType" minOccurs="0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attributeGroup ref = "jaxb:propertyAttributes"/> + </xs:complexType> + </xs:element> + <xs:element name = "javaType"> + <xs:annotation> + <xs:documentation>Data type conversions; overriding builtins</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation>name of the java type to which xml type is to be bound.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "xmlType" type = "xs:QName"> + <xs:annotation> + <xs:documentation> xml type to which java datatype has to be bound.Must be present when javaType is scoped to globalBindings</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "parseMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "printMethod" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "hasNsContext" default = "false" type = "xs:boolean" > + <xs:annotation> + <xs:documentation> + If true, the parsMethod and printMethod must reference a method + signtature that has a second parameter of type NamespaceContext. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumClass"> + <xs:annotation> + <xs:documentation> Bind to a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + <xs:element ref = "jaxb:typesafeEnumMember" minOccurs = "0" maxOccurs = "unbounded"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + <xs:attribute name = "map" type = "xs:boolean" default = "true"/> + </xs:complexType> + </xs:element> + <xs:element name = "typesafeEnumMember"> + <xs:annotation> + <xs:documentation> Enumeration member name in a type safe enumeration class.</xs:documentation> + </xs:annotation> + <xs:complexType> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "value" type="xs:anySimpleType"/> + <xs:attribute name = "name" use = "required" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + </xs:element> + + <!-- TYPE DEFINITIONS --> + + <xs:complexType name = "propertyBaseType"> + <xs:all> + <xs:element ref = "jaxb:javaType" minOccurs = "0"/> + </xs:all> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"> + <xs:annotation> + <xs:documentation> + The name attribute for [baseType] enables more precise control over the actual base type for a JAXB property. This customization enables specifying a more general base type than the property's default base type. The name attribute value must be a fully qualified Java class name. Additionally, this Java class must be a super interface/class of the default Java base type for the property. When the default base type is a primitive type, consider the default Java base type to be the Java wrapper class of that primitive type.This customization is useful to enable simple type substitution for a JAXB property representing with too restrictive of a default base type. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + + <xs:complexType name = "packageType"> + <xs:sequence> + <xs:element name = "javadoc" type = "xs:string" minOccurs = "0"/> + </xs:sequence> + <xs:attribute name = "name" type = "jaxb:javaIdentifierType"/> + </xs:complexType> + <xs:simpleType name = "underscoreBindingType"> + <xs:annotation> + <xs:documentation>Treate underscore in XML Name to Java identifier mapping.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "asWordSeparator"/> + <xs:enumeration value = "asCharInWord"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumBaseType"> + <xs:annotation> + <xs:documentation> + XML types or types derived from them which have enumeration facet(s) + which are be mapped to typesafeEnumClass by default. + The following types cannot be specified in this list: + "xsd:QName", "xsd:base64Binary", "xsd:hexBinary", + "xsd:date", "xsd:time", "xsd:dateTime", "xsd:duration", + "xsd:gDay", "xsd:gMonth", "xsd:Year", "xsd:gMonthDay", "xsd:YearMonth" + </xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:QName"/> + </xs:simpleType> + <xs:simpleType name = "typesafeEnumMemberNameType"> + <xs:annotation> + <xs:documentation>Used to customize how to handle name collisions.</xs:documentation> + </xs:annotation> + <xs:restriction base = "xs:string"> + <xs:enumeration value = "generateName"/> + <xs:enumeration value = "generateError"/> + <xs:enumeration value = "skipGeneration"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType name = "javaIdentifierType"> + <xs:annotation> + <xs:documentation>Placeholder type to indicate Legal Java identifier.</xs:documentation> + </xs:annotation> + <xs:list itemType = "xs:NCName"/> + </xs:simpleType> + <xs:complexType name = "nameXmlTransformRule"> + <xs:annotation> + <xs:documentation>Rule to transform an Xml name into another Xml name</xs:documentation> + </xs:annotation> + <xs:attribute name = "prefix" type = "xs:string"> + <xs:annotation> + <xs:documentation>prepend the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "suffix" type = "xs:string"> + <xs:annotation> + <xs:documentation>Append the string to QName.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:complexType name = "nameXmlTransformType"> + <xs:annotation> + <xs:documentation>Allows transforming an xml name into another xml name. Use case UDDI 2.0 schema.</xs:documentation> + </xs:annotation> + <xs:all> + <xs:element name = "typeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for type definitions.</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "elementName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for elements</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "modelGroupName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for model group</xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "anonymousTypeName" type = "jaxb:nameXmlTransformRule" minOccurs = "0"> + <xs:annotation> + <xs:documentation>Mapping rule for class names generated for an anonymous type.</xs:documentation> + </xs:annotation> + </xs:element> + </xs:all> + </xs:complexType> + <xs:attribute name = "extensionBindingPrefixes"> + <xs:annotation> + <xs:documentation> + A binding compiler only processes this attribute when it occurs on an + an instance of xs:schema element. The value of this attribute is a + whitespace-separated list of namespace prefixes. The namespace bound + to each of the prefixes is designated as a customization declaration + namespace. + </xs:documentation> + </xs:annotation> + <xs:simpleType> + <xs:list itemType = "xs:normalizedString"/> + </xs:simpleType> + </xs:attribute> + <xs:element name = "bindings"> + <xs:annotation> + <xs:documentation> + Binding declaration(s) for a remote schema. + If attribute node is set, the binding declaraions + are associated with part of the remote schema + designated by schemaLocation attribute. The node + attribute identifies the node in the remote schema + to associate the binding declaration(s) with. + </xs:documentation> + </xs:annotation> + <!-- a <bindings> element can contain arbitrary number of binding declarations or nested <bindings> elements --> + <xs:complexType> + <xs:sequence> + <xs:choice minOccurs = "0" maxOccurs = "unbounded"> + <xs:group ref = "jaxb:declaration"/> + <xs:element ref = "jaxb:bindings"/> + </xs:choice> + </xs:sequence> + <xs:attribute name = "schemaLocation" type = "xs:anyURI"> + <xs:annotation> + <xs:documentation> + Location of the remote schema to associate binding declarations with. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "node" type = "xs:string"> + <xs:annotation> + <xs:documentation> + The value of the string is an XPATH 1.0 compliant string that + resolves to a node in a remote schema to associate + binding declarations with. The remote schema is specified + by the schemaLocation attribute occuring in the current + element or in a parent of this element. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name = "version" type = "xs:token"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this or "jaxb:version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute ref = "jaxb:version"> + <xs:annotation> + <xs:documentation> + Used to indicate the version of binding declarations. Only valid on root level bindings element. + Either this attribute or "version" attribute but not both may be specified. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:simpleType name="referenceCollectionType"> + <xs:union> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:enumeration value="indexed"/> + </xs:restriction> + </xs:simpleType> + <xs:simpleType> + <xs:restriction base="jaxb:javaIdentifierType"/> + </xs:simpleType> + </xs:union> + </xs:simpleType> + <xs:element name="dom"> + <xs:complexType> + <xs:attribute name = "type" type="xs:NCName" default="w3c"> + <xs:annotation> + <xs:documentation>Specify DOM API to bind to JAXB property to.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name="inlineBinaryData"> + <xs:annotation> + <xs:documentation> + Disable MTOM/XOP encoding for this binary data. Annotation can be placed on a type definition that + derives from a W3C XSD binary data type or on an element that has a type that is + or derives from a W3C XSD binary data type. + </xs:documentation> + </xs:annotation> + </xs:element> + <xs:element name = "serializable"> + <xs:complexType> + <xs:attribute name="uid" type="xs:long" default="1"/> + </xs:complexType> + </xs:element> +</xs:schema> +----
diff --git a/spec/src/main/asciidoc/appD-binding_xml.adoc b/spec/src/main/asciidoc/appD-binding_xml.adoc new file mode 100644 index 0000000..5d28ee2 --- /dev/null +++ b/spec/src/main/asciidoc/appD-binding_xml.adoc
@@ -0,0 +1,404 @@ +// +// Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation +// + +[appendix] +== Binding XML Names to Java Identifiers + +=== Overview + +This section provides default mappings from: + +* XML Name to Java identifier +* Model group to Java identifier +* Namespace URI to Java package name + +=== The Name to Identifier Mapping Algorithm + +Java identifiers typically follow three simple, well-known conventions: + +* Class and interface names always begin with +an upper-case letter. The remaining characters are either digits, +lower-case letters, or upper-case letters. Upper-case letters within a +multi-word name serve to identify the start of each non-initial word, or +sometimes to stand for acronyms. +* Method names and components of a package +name always begin with a lower-case letter, and otherwise are exactly +like class and interface names. +* Constant names are entirely in upper case, +with each pair of words separated by the underscore character (‘_’, +\u005F, LOW LINE). + +XML names, however, are much richer than Java +identifiers: They may include not only the standard Java identifier +characters but also various punctuation and special characters that are +not permitted in Java identifiers. Like most Java identifiers, most XML +names are in practice composed of more than one natural-language word. +Non-initial words within an XML name typically start with an upper-case +letter followed by a lower-case letter, as in Java language, or are +prefixed by punctuation characters, which is not usual in the Java +language and, for most punctuation characters, is in fact illegal. + +In order to map an arbitrary XML name into a +Java class, method, or constant identifier, the XML name is first broken +into a _word list_. For the purpose of constructing word lists from XML +names we use the following definitions: + +* A _punctuation character_ is one of the following: +* A hyphen (’-’, \u002D, HYPHEN-MINUS), +* A period (‘.’, \u002E, FULL STOP), +* A colon (’:’, \u003A, COLON), +* A dot (‘.’, \u00B7, MIDDLE DOT), +* \u0387, GREEK ANO TELEIA, +* \u06DD, ARABIC END OF AYAH, or +* \u06DE, ARABIC START OF RUB EL HIZB. +* An underscore (’\_’, \u005F, LOW LINE) with following exceptionfootnote:exc[Exception case: +Underscore is not considered a punctuation mark for schema customization +_<jaxb:globalBindings underscoreHandling="asCharInWord"/>_ specified in +<<Underscore Handling>>. For this +customization, underscore is considered a special letter that never +results in a word break as defined in <<xmlWordBreaks>> +and it is definitely not considered an uncased letter. +See example bindings in <<asCharInWord>>.] + +These are all legal characters in XML names. + +* A _letter_ is a character for which the +`Character.isLetter` method returns `true`, _i.e._ , a letter according +to the Unicode standard. Every letter is a legal Java identifier +character, both initial and non-initial. +* A _digit_ is a character for which the +`Character.isDigit` method returns `true`, _i.e._ , a digit according +to the Unicode Standard. Every digit is a legal non-initial Java +identifier character. +* A _mark_ is a character that is in none of +the previous categories but for which the +`Character.isJavaIdentifierPart` method returns `true`. This category +includes numeric letters, combining marks, non-spacing marks, and +ignorable control characters. + +Every XML name character falls into one of +the above categories. We further divide letters into three +subcategories: + +* An _upper-case letter_ is a letter for which the `Character.isUpperCase` method returns `true`, +* A _lowercase letter_ is a letter for which the `Character.isLowerCase` method returns `true`, and +* All other letters are _uncased_. + +An XML name is split into a word list by +removing any leading and trailing punctuation characters and then +searching for _word breaks_. A word break is defined by three regular +expressions: A prefix, a separator, and a suffix. The prefix matches +part of the word that precedes the break, the separator is not part of +any word, and the suffix matches part of the word that follows the +break. The word breaks are defined as: + +.XML Word Breaks +[[xmlWordBreaks]] +[cols=",,,",options="header"] +|=== +| Prefix | Separator | Suffix | Example +| `[^punct]` | `punct+` footnote:exc[] | `[^punct]` | `foo{vbar}--{vbar}bar` +| `digit` | | `[^digit]` | `foo{vbar}22{vbar}bar` +| `[^digit]` | | `digit` | `foo{vbar}22` +| `lower` | | `[^lower]` | `foo{vbar}Bar` +| `upper` | | `upper lower` | `FOO{vbar}Bar` +| `letter` | | `[^letter]` | `Foo{vbar}\u2160` +| `[^letter]` | | `letter` | `\u2160{vbar}Foo` +| `uncased` | | `[^uncased]` | +| `[^uncased]` | | `uncased` | +|=== + +(The character `\u2160` is ROMAN NUMERAL ONE, a numeric letter.) + +After splitting, if a word begins with a +lower-case character then its first character is converted to upper +case. The final result is a word list in which each word is either + +* A string of upper- and lower-case letters, +the first character of which is upper case (includes underscore, ’_’, for +exception casefootnote:exc[]). +* A string of digits, or +* A string of uncased letters and marks. + +Given an XML name in word-list form, each of +the three types of Java identifiers is constructed as follows: + +* A class or interface identifier is +constructed by concatenating the words in the list, +* A method identifier is constructed by +concatenating the words in the list. A prefix verb (`get`, `set`, +_etc._) is prepended to the result. +* A constant identifier is constructed by +converting each word in the list to upper case; the words are then +concatenated, separated by underscores. + +This algorithm will not change an XML name +that is already a legal and conventional Java class, method, or constant +identifier, except perhaps to add an initial verb in the case of a +property access method. + +To improve user experience with default +binding, the automated resolution of frequent naming collision is +specified in <<Standardized Name Collision Resolution>>. + +*_Example_* + +.XML Names and derived Java Class, Method, and Constant Names +[[jcmcn]] +[cols=",,,",options="header"] +|=== +| XML Name | Class Name | Method Name | Constant Name +| mixedCaseName | MixedCaseName | getMixedCaseName | MIXED_CASE_NAME +| Answer42 | Answer42 | getAnswer42 | ANSWER_42 +| name-with-dashes | NameWithDashes | getNameWithDashes | NAME_WITH_DASHES +| other_punct-chars | OtherPunctChars | getOtherPunctChars | OTHER_PUNCT_CHARS +|=== + +.XML Names and derived Java Class, Method, and Constant Names when <jaxb:globalBindings underscoreHandling=”asCharInWord”> +[[asCharInWord]] +[cols=",,,",options="header"] +|=== +| XML Name | Class Name | Method Name | Constant Name +| other_punct-chars | Other_punctChars | getOther_punctChars | OTHER_PUNCT_CHARS +| name_with_underscore | Name_with_underscore | name_with_underscore | NAME_WITH_UNDERSCORE +|=== + +==== Collisions and conflicts + +It is possible that the name-mapping +algorithm will map two distinct XML names to the same word list.These +cases will result in a _collision_ if, and only if, the same Java +identifier is constructed from the word list and is used to name two +distinct generated classes or two distinct methods or constants in the +same generated class. It is also possible if two or more namespaces are +customized to map to the same Java package, XML names that are unique +due to belonging to distinct namespaces could mapped to the same Java +Class identifier. Collisions are not permitted by the schema compiler +and are reported as errors; they may be repaired by revising XML name +within the source schema or by specifying a customized binding that maps +one of the two XML names to an alternative Java identifier. + +A class name must not conflict with the +generated JAXB class, `ObjectFactory`, <<Java Package>>, +that occurs in each schema-derived Java package. Method +names are forbidden to conflict with Java keywords or literals, with +methods declared in `java.lang.Object`, or with methods declared in the +binding-framework classes. Such conflicts are reported as errors and may +be repaired by revising the appropriate schema or by specifying an +appropriate customized binding that resolves the name collision. + +===== Standardized Name Collision Resolution + +Given the frequency of an XML element or +attribute with the name “class” or “Class” resulting in a naming +collision with the inherited method `java.lang.Object.getClass()`, +method name mapping automatically resolves this conflict by mapping +these XML names to the java method identifier “getClazz”. + +[NOTE] +.Design Note +==== +The likelihood of collisions, and the difficulty of working around them +when they occur, depends upon the source schema, the schema language +in which it is written, and the binding declarations. In general, however, +we expect that the combination of the identifier-construction rules given above, +together with good schema-design practices, will make collisions relatively uncommon. + +The capitalization conventions embodied in the identifier-construction +rules will tend to reduce collisions as long as names with shared mappings +are used in schema constructs that map to distinct sorts of Java constructs. +Anattribute named `foo` is unlikely to collide with an element type named `foo` +because the first maps to a set of property access methods (`getFoo`, `setFoo`, _etc._) +while the second maps to a class name (`Foo`). + +Good schema-design practices also make collisions less likely. When writing a schema +it is inadvisable to use, in identical roles, names that are distinguished only by +punctuation or case. Suppose a schema declares two attributes of a single element type, +one named `Foo` and the other named `foo`. Their generated access methods, +namely `getFoo` and `setFoo`, will collide. This situation would best be handled by +revising the source schema, which would not only eliminate the collision +but also improve the readability of the source schema and documents that use it. + +==== + +=== Deriving a legal Java identifier from an enum facet value + +Given that an enum facet’s value is not +restricted to an XML name, the XML Name to Java identifier algorithm is +not applicable to generating a Java identifier from an enum facet’s +value. The following algorithm maps an enum facet value to a valid Java +constant identifier name. + +* For each character in enum facet value, +copy the character to a string representation `javaId` when +`java.lang.Character.isJavaIdentifierPart()` is `true`. +** To follow Java constant naming convention, +each valid lower case character must be copied as its upper case +equivalent. +* There is no derived Java constant identifier when any of the following occur: +** `javaId.length() == 0` +** `java.lang.Character.isJavaIdentifierStart(javaId.get(0)) == false` + +=== Deriving an identifier for a model group + +XML Schema has the concept of a group of +element declarations. Occasionally, it is convenient to bind the +grouping as a Java content property or a Java value class. When a +semantically meaningful name for the group is not provided within the +source schema or via a binding declaration customization, it is +necessary to generate a Java identifier from the grouping. Below is an +algorithm to generate such an identifier. + +A name is computed for an unnamed model group +by concatenating together the first 3 element declarations and/or +wildcards that occur within the model group. Each XML _{name}_ is mapped +to a Java identifier for a method using the XML Name to Java Identifier +Mapping algorithm. Since wildcard does not have a _{name}_ property, it +is represented as the Java identifier `"Any"`. The Java identifiers +are concatenated together with the separator `"And"` for sequence and +all compositor and `"Or"` for choice compositors. For example, a +sequence of element `foo` and element `bar` would map to `"FooAndBar"` +and a choice of element `foo` and element `bar` maps to +`"FooOrBar"` Lastly, a sequence of wildcard and element `bar` would +map to the Java identifier `"AnyAndBar"`. + +*_Example:_* + +Given XML Schema fragment: + +[source,xml,indent="2"] +---- +<xs:choice> + <xs:sequence> + <xs:element ref="A"/> + <xs:any processContents="strict"/> + </xs:sequence> + <xs:element ref="C"/> +</xs:choice> +---- + +The generated Java identifier would be `AAndAnyOrC`. + +=== Generating a Java package name + +This section describes how to generate a +package name to hold the derived Java representation. The motivation for +specifying a default means to generate a Java package name is to +increase the chances that a schema can be processed by a schema compiler +without requiring the user to specify customizations. + +If a schema has a target namespace, the next +subsection describes how to map the URI into a Java package name. If the +schema has no target namespace, there is a section that describes an +algorithm to generate a Java package name from the schema filename. + +==== Mapping from a Namespace URI + +An XML namespace is represented by a URI. +Since XML Namespace will be mapped to a Java package, it is necessary to +specify a default mapping from a URI to a Java package name. The URI +format is described in [RFC2396]. + +The following steps describe how to map a URI +to a Java package name. The example URI, +`http://www.acme.com/go/espeak.xsd`, is used to illustrate each step. + +. Remove the scheme and `":"` part from the +beginning of the URI, if present. + +Since there is no formal syntax to identify the optional URI scheme, +restrict the schemes to be removed to case insensitive checks for +schemes `"http"`, `"https"` and `"urn"`. ++ +[source] +---- +//www.acme.com/go/espeak.xsd +---- +. Remove the trailing file type, one of `.??` or `.???` or `.html`. ++ +[source] +---- +//www.acme.com/go/espeak +---- +. Parse the remaining string into a list of +strings using `'/'` and `':'` as separators. Treat consecutive +separators as a single separator. ++ +[source] +---- +{"www.acme.com", "go", "espeak"} +---- +. For each string in the list produced by +previous step, unescape each escape sequence octet. ++ +[source] +---- +{"www.acme.com", "go", "espeak"} +---- +. If the scheme is a `"urn"`, replace all +dashes, `"-"`, occurring in the first component with +`"."`.footnote:[Sample URN +"urn:hl7-org:v3" {"h17-org", "v3"} transforms to {"h17.org", "v3"}.] +. Apply algorithm described in Section 7.7 +“Unique Package Names” in [JLS] to derive a unique package name from the +potential internet domain name contained within the first component. The +internet domain name is reversed, component by component. Note that a +leading `"www."` is not considered part of an internet domain name and +must be dropped. ++ +If the first component does not contain +either one of the top-level domain names, for example, com, gov, net, +org, edu, or one of the English two-letter codes identifying countries +as specified in ISO Standard 3166, 1981, this step must be skipped. ++ +[source] +---- +{"com", "acme", "go", "espeak"} +---- +. For each string in the list, convert each string to be all lower case. ++ +[source] +---- +{"com", "acme", "go", "espeak"} +---- +. For each string remaining, the following +conventions are adopted from [JLS] Section 7.7, “Unique Package Names.” +.. If the sting component contains a hyphen, +or any other special character not allowed in an identifier, convert it +into an underscore. +.. If any of the resulting package name +components are keywords then append underscore to them. +.. If any of the resulting package name +components start with a digit, or any other character that is not +allowed as an initial character of an identifier, have an underscore +prefixed to the component. + ++ +[source] +---- +{"com", "acme", "go", "espeak"} +---- + +. Concatenate the resultant list of strings +using `"."` as a separating character to produce a package name. ++ +[source] +---- +Final package name: "com.acme.go.espeak". +---- + +<<Collisions and conflicts>> specifies what to do when the above algorithm results in +an invalid Java package name. + +=== Conforming Java Identifier Algorithm + +This section describes how to convert a legal +Java identifier which may not conform to Java naming conventions to a +Java identifier that conforms to the standard naming conventions. +<<Customized Name Mapping>> discusses when +this algorithm is applied to customization names. + +Since a legal Java identifier is also a XML +name, this algorithm is the same as <<The Name to Identifier Mapping Algorithm>> +with the following exception: +constant names must not be mapped to a Java constant that conforms to +the Java naming convention for a constant.
diff --git a/spec/src/main/asciidoc/appE-external_binding.adoc b/spec/src/main/asciidoc/appE-external_binding.adoc new file mode 100644 index 0000000..a4ca416 --- /dev/null +++ b/spec/src/main/asciidoc/appE-external_binding.adoc
@@ -0,0 +1,168 @@ +// +// Copyright (c) 2020 Contributors to the Eclipse Foundation +// + +[appendix] +== External Binding Declaration + +=== Example + +*_Example:_* Consider the following schema and external binding file: + + +Source Schema: `A.xsd`: + +[source,xml] +---- +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:ens="http://example.com/ns" + targetNamespace="http://example.com/ns"> + <xs:complexType name="aType"> + <xs:sequence> + <xs:element name="foo" type="xs:int"/> + </xs:sequence> + <xs:attribute name="bar" type="xs:int"/> + </xs:complexType> + <xs:element name="root" type="ens:aType"/> +</xs:schema> +---- + +External binding declarations file: + +[source,xml] +---- +<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + version="3.0"> + <jaxb:bindings schemaLocation="A.xsd"> + <jaxb:bindings node="//xs:complexType[@name=’aType’]"> + <jaxb:class name="customNameType"/> + <jaxb:bindings node=".//xs:element[@name=’foo’]"> + <jaxb:property name="customFoo"/> + </jaxb:bindings> + <jaxb:bindings node="./xs:attribute[@name=’bar’]"> + <jaxb:property name="customBar"/> + </jaxb:bindings> + </jaxb:bindings> + </jaxb:bindings> +</jaxb:bindings> +---- + +Conceptually, the combination of the source +schema and external binding file above are the equivalent of the +following inline annotated schema. + +[source,xml] +---- +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:ens="http://example.com/ns" + targetNamespace="http://example.com/ns" + xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb" + jaxb:version="3.0"> + <xs:complexType name="aType"> + <xs:annotation> + <xs:appinfo> + <jaxb:class name="customNameType"/> + </xs:appinfo> + </xs:annotation> + <xs:sequence> + <xs:element name="foo" type="xs:int"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="customFoo"/> + </xs:appinfo> + </xs:annotation> + </xs:element> + </xs:sequence> + <xs:attribute name="bar" type="xs:int"> + <xs:annotation> + <xs:appinfo> + <jaxb:property name="customBar"/> + </xs:appinfo> + </xs:annotation> + </xs:attribute> + </xs:complexType> + <xs:element name="root" type="ens:aType"/> +</xs:schema> +---- + +=== Transformation + +The intent of this section is to describe the +transformation of external binding declarations and their target schemas +into a set of schemas annotated with JAXB binding declarations. ready +for processing by a JAXB compliant schema compiler. + +This transformation must be understood to +work on XML data model level. Thus, this transformation is applicable +even for those schemas which contain semantic errors. + +The transformation is applied as follows: + +. Gather all the top-most `<jaxb:bindings>` +elements from all the schema documents and all the external binding +files that participate in this process. _Top-most_ `<jaxb:bindings>` are +those `<jaxb:bindings>` elements that are either a root element in a +document or whose parent is an `<xs:appinfo>` element. We will refer to +these trees as “external binding forest.” +. Collect all the namespaces used in the +elements inside the external binding forest, except the taxi namespace, +`"https://jakarta.ee/xml/ns/jaxb"`, and the no namespace. Allocate an +unique prefix for each of them and declare the namespace binding at all +the root `<xs:schema>` elements of each schema documents. + +Then add a `jaxb:extensionBindingPrefix` attribute to each `<xs:schema>` +element with all those allocated prefixes. If an`<xs:schema>` element +already carries this attribute, prefixes are just appended to the +existing attributes. + + + +Note: The net effect is that all “foreign” namespaces used in the +external binding forest will be automatically be considered as extension +customization declaration namespaces. +. For each `<jaxb:bindings>` element, we +determine the “target element” that the binding declaration should be +associated with. This process proceeds in a top-down fashion as follows: ++ +-- +.. Let `p` be the target element of the parent +`<jaxb:bindings>`. If it is the top most `<jaxb:bindings>`, then let +`p` be the `<jaxb:bindings>` element itself. +.. Identify the “target element” using `<jaxb:bindings>` attributes. +... If the `<jaxb:bindings>` has a `@schemaLocation`, the value of the +attribute should be taken as an URI and be absolutized with the base URI +of the `<jaxb:bindings>` element. Then the target element will be the +root node of the schema document identified by the absolutized URI. If +there’s no such schema document in the current input, it is an error. +Note: the root node of the schema document is not the document element. + +... If the `<jaxb:bindings>` has `@node`, +the value of the attribute should be evaluated as an XPath 1.0 +expression. The context node in this evaluation should be _p_ as we +computed in the previous step. It is an error if this evaluation results +in something other than a node set that contains exactly one element. +Then the target element will be this element. + +... If the `<jaxb:bindings>` has neither +`@schemaLocation` nor `@node`, then the target element will be `p` as +we computed in the previous step. Note: `<jaxb:bindings>` elements can’t +have both `@schemaLocation` and `@node` at the same time. +-- ++ +We define the target element of a binding +declaration to be the target element of its parent `<jaxb:bindings>` +element. The only exception to this is `<jaxb:globalBindings>` binding +declaraiton, in which case the target element will be the document +element of any one of the schema documents being compiled (such choice +is undeterministic, but the semantics of `<jaxb:globalBindings>` is not +affected by this choice, so the end result will be the same.) It is an +error if a target element of a binding declaration doesn’t belong to the +_"http://wwww.w3.org/2001/XMLSchema"_ namespace. + +. Next, for each target element of binding +declarations, if it doesn’t have any `<xs:annotation> <xs:appinfo>` in +its children, one will be created and added as the first child of the +target. + + +After that, we move each binding declaration under the target node of +its parent `<jaxb:bindings>`. Consider the first `<xs:appinfo>` child +of the target element. The binding declaration element will be moved +under this `<xs:appinfo>` element. +
diff --git a/spec/src/main/asciidoc/appF-xml_schema.adoc b/spec/src/main/asciidoc/appF-xml_schema.adoc new file mode 100644 index 0000000..c5f212f --- /dev/null +++ b/spec/src/main/asciidoc/appF-xml_schema.adoc
@@ -0,0 +1,235 @@ +// +// Copyright (c) 2020 Contributors to the Eclipse Foundation +// + +[appendix] +== XML Schema + +=== Abstract Schema Model + +The following summarization abstract schema +component model has been extracted from [XSD Part 1] as a convenience +for those not familiar with XML Schema component model in understanding +the binding of XML Schema components to Java representation. One must +refer to [XSD Part 1] for the complete normative description for these +components. + +==== Simple Type Definition Schema Component + +.Simple Type Definition Schema Components +[cols=",,",options="header"] +|=== +| Component 2+| Description +| `{name}` 2+| Optional. An NCName as defined by [XML-Namespaces]. +| `{target namespace}` 2+| Either ·absent· or a namespace name. +| `{base type definition}` 2+| A simple type definition +| `{facets}` 2+| A set of constraining facets. +| `{fundamental facets}` 2+| A set of fundamental facets. +| `{final}` 2+| A subset of {extension, list, restriction, union}. +| `{variety}` 2+| One of {atomic, list, union}. Depending on +the value of {variety}, further properties are defined as follows: +| | atomic + +`{primitive type definition}` | A built-in primitive simple type definition. +| | list + +`{item type definition}` | A simple type definition. +| | union + +`{member type definitions}` |A non-empty sequence of simple type definitions. + +| `{annotation}` 2+| Optional. An annotation. +|=== + +==== Enumeration Facet Schema Component + +.Enumeration Facet Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{value}` | The actual value of the value. (Must be in +value space of base type definition.) +| `{annotation}` | Optional annotation. +|=== + +==== Complex Type Definition Schema Component + +.Complex Type Definition Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | Optional. An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Either `absent` or a namespace name. +| `{base type definition}` | Either a simple type definition or a complex type definition. +| `{scope}` | Either _global_ or a complex type definition +| `{derivation method}` | Either extension or _restriction_. +| `{final}` | A subset of {extension, restriction}. +| `{abstract}` | A boolean +| `{attribute uses}` | A set of attribute uses. +| `{attribute wildcard}` | Optional. A wildcard. +| `{content type}` | One of _empty_, a _simple type definition_, or a +pair consisting of a `content model` and one of _mixed_, _element-only_. +| `{prohibited substitutions}` | A subset of {extension, restriction}. +| `{substitution group affiliation}` | Optional. If exists, this element declaration +belongs to a substitution group and this specified element name is the +QName of the substitution head. +| `{annotations}` | A set of annotations. +|=== + +==== Element Declaration Schema Component + +.Element Declaration Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Either ·absent· or a namespace name +| `{type definition}` | Either a simple type definition or a complex type definition. +| `{scope}` | Optional. Either global or a complex type definition. +| `{value constraint}` | Optional. A pair consisting of a value and one of default, fixed. +| `{nillable}` | A boolean. +| `{identity-constraint definitions}` | A set of constraint definitions. +| `{substitution group affiliation}` | Optional. A top-level element definition. +| `{substitution group exclusions}` | A subset of {extension, restriction}. +| `{disallowed substitution}` | A subset of {substitution,extension,restriction}. +| `{abstract}` | A boolean. +| `{annotation}` | Optional. An annotation. +|=== + +==== Attribute Declaration Schema Component + +.Attribute Declaration Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | If form is present and is "qualified", or if +form is absent and the value of @attributeFormDefault on the <schema> +ancestor is "qualified", then the schema’s {targetNamespace}, or +`absent` if there is none, otherwise `absent` +| `{type definition}` | A simple type definition. +| `{scope}` | Optional. Either global or a complex type definition. +| `{value constraint}` | Optional. A pair consisting of a value and +one of default, fixed. +| `{annotation}` | Optional. An annotation. +|=== + +==== Model Group Definition Schema Component + +.Model Group Definition Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Either `absent` or a namespace name. +| `{model group}` | A model group. +| `{annotation}` | Optional. An annotation. +|=== + +==== Identity-constraint Definition Schema Component + +.Identity-constraint Definition Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Either ·absent· or a namespace name. +| `{identity-constraint category}` | One of key, keyref or unique. +| `{selector}` | A restricted XPath ([XPath]) expression. +| `{fields}` | A non-empty list of restricted XPath ([XPath]) expressions. +| `{referenced key}` | Required if \identity-constraint category} +is keyref, forbidden otherwise. + +An identity-constraint definition with +{identity-constraint category} equal to key or unique. + +| `{annotation}` | Optional. An annotation. +|=== + +==== Attribute Use Schema Component + +.Attribute Use Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{required}` | A boolean. +| `{attribute declaration}` | An attribute declaration. +| `{value constraint}` | Optional. A pair consisting of a value and +one of default, fixed. +|=== + +==== Particle Schema Component + +.Particle Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{min occurs}` | A non-negative integer. +| `{max occurs}` | Either a non-negative integer or unbounded. +| `{term}` | One of a model group, a wildcard, or an element declaration. +|=== + +==== Wildcard Schema Component + +.Wildcard Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{namespace constraint}` | One of any; a pair of not and a namespace +name or `absent`; or a set whose members are either namespace names or +`absent`. +| `{process contents}` | One of `skip`, `lax` or `strict`. +| `{annotation}` | Optional. An annotation. +|=== + +==== Model Group Schema Component + +.Model Group Components +[cols=",",options="header"] +|=== +| Component | Description +| `{compositor}` | One of _all, choice_ or _sequence_. +| `{particles}` | A list of particles. +| `{annotation}` | An annotation. +|=== + +==== Notation Declaration Schema Component + +.Notation Declaration Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Actual value of the targetNamespace +[attribute] of the parent schema element +| `{system identifier}` | The ·actual value· of the system [attribute], +if present, otherwise absent. +| `{public identifier}` | The ·actual value· of the public [attribute] +| `{annotation}` | Optional. An annotation. +|=== + +==== Wildcard Schema Component + +.Wildcard Components +[cols=",",options="header"] +|=== +| Component | Description +| `{namespace constraint}` | One of `any`; a pair of `no` and a +namespace name or `absent`; or a set whose members are either namespace +names or `absent`. +| `{process contents}` | One of `skip`, `lax` or `strict`. +| `{annotation}` | Optional. An annotation. +|=== + +==== Attribute Group Definition Schema Component + +.Attribute Group Definition Schema Components +[cols=",",options="header"] +|=== +| Component | Description +| `{name}` | An NCName as defined by [XML-Namespaces]. +| `{target namespace}` | Either `absent` or a namespace name. +| `{attribute uses}` | A set of attribute uses. +| `{attribute wildcard}` | Optional. A wildcard. _(part of the complete wildcard)_ +| `{annotation}` | Optional. An annotation. +|===
diff --git a/spec/src/main/asciidoc/appH-binary_data.adoc b/spec/src/main/asciidoc/appH-binary_data.adoc new file mode 100644 index 0000000..d7aa6e4 --- /dev/null +++ b/spec/src/main/asciidoc/appH-binary_data.adoc
@@ -0,0 +1,247 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +[appendix] +== Enhanced Binary Data Handling + +=== Overview + +Optimized transmission of binary data as +attachments is described by standards such as Soap [MTOM]/Xml-binary +Optimized Packaging[XOP] and WS-I Attachment Profile 1.0 [WSIAP]. To +optimally support these standards when JAXB databinding is used within a +message passing environment, <<jakarta-xml-bind-attachments>> +specifies an API that allows for an +integrated, cooperative implementation of these standards between a +MIME-based package processor and the Jakarta XML Binding unmarshal/marshal +processes. An enhanced binding of MIME content to Java representation is +specified in <<Binding MIME Binary Data>>. + +=== Binding MIME Binary Data + +==== Binary Data Schema Annotation + +As specified in [MIME], the XML Schema +annotation attribute, `xmime:expectedContentTypes`, lists the expected +MIME content-type(s) for element content whose type derives from the xsd +binary datatypes, `xs:base64Binary` or `xs:hexBinary`. + +Jakarta XML Binding databinding recognizes this schema +constraint to improve the binding of MIME type constrained binary data +to Java representation. The `xmime:expectedContentType` attribute is +allowed on type definitions deriving from binary datatypes and on +element declarations with types that derive from binary datatypes. For +Jakarta XML Binding binding purposes, the schema annotation, +`xmime:expectedContentTypes` is evaluated for binding purposes for all +cases EXCEPT when the annotation is on an element declaration with a +named complex type definition. For that case, the +`xmime:expectedContentTypes` annotation must be located directly within +the scope of the complex type definition in order to impact the binding +of the complex type definition’s simple binary content. + +===== Binding Known Media Type + +When `@xmime:expectedContentTypes` schema +annotation only refers to one MIME type, it is considered a known media +type for the binary data. [MIME] does not require an `xmime:contentType` +attribute to hold the dynamic mime type for the binary data for this +case. JAXB binding can achieve an optimal binding for this case. The +default MIME type to Java datatype are in <<a5119>>. + +.Default Binding for Known Media Type +[[a5119]] +[cols=",",options="header",] +|=== +| MIME Type | Java Type +| `image/gif` | `java.awt.Image` +| `image/jpeg` | `java.awt.Image` +| `text/xml` or `application/xml` | `javax.xml.transform.Source` +| `_any other MIME types_` | `jakarta.activation.DataHandler` +|=== + +A JAXB program annotation element, +`@XmlMimeType`, is generated to preserve the known media type for use +at marshal time. + +.schema with a known media type +[source,xml,indent="2"] +---- +<?xml version="1.0" ?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:tns="http://example.com/know-type" + xmlns:xmime="http://www.w3.org/2005/05/xmlmime" + targetNamespace="http://example.com/know-type"> + <xs:import namespace="http://www.w3.org/2005/05/xmlmime" + schemaLocation="http://www.w3.org/2005/05/xmlmime"/> + <xs:element name="JPEGPicture" + type="xs:base64binary" + xmime:expectedContentTypes="image/jpeg"/> +</xs:schema> +---- + +.Jakarta XML Binding binding of Example 8-1 +[source,java,indent="4"] +---- +import java.awt.Image; +@XmlRegistry +class ObjectFactory { + @XmlElementDecl(...) + @XmlMimeType("image/jpeg") + JAXBELement<Image> createJPEGPicture(Image value); +} +---- + +The `@XmlMimeType` annotation provides the +MIME content type needed by Jakarta XML Binding Marshaller to specify the mime type +to set `DataHandler.setContentType(String)`. + +.Schema for local element declaration annotated with known media type +[[a5140]] +[source,xml,indent="2"] +---- +<?xml version="1.0" ?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:tns="http://example.com/know-type" + xmlns:xmime="http://www.w3.org/2005/05/xmlmime" + targetNamespace="http://example.com/know-type"> + <xs:import namespace="http://www.w3.org/2005/05/xmlmime" + schemaLocation="http://www.w3.org/2005/05/xmlmime"/> + <xs:complexType name="Item"> + <xs:sequence> + <xs:element name="JPEGPicture" + type="xs:base64Binary" + xmime:expectedContentTypes="image/jpeg"/> + </xs:sequence> + </xs:complexType> +</xs:schema> +---- + +.Java Binding of <<a5140>> +[source,java,indent="4"] +---- +import java.awt.Image; +public class Item { + @XmlMimeType("image/jpeg") + Image getJPEGPicture(); + void setJPEGPicture(Image value); +} +---- + +===== Binding Preferred Media Types + +If there are more than one mime type listed +in `xmime:expectedContentTypes` or if there is one with a wildcard in +it, the annotation specifies the Preferred Media Types and recommends +that the binary data be simple content that has an attribute +`xmime:contentType` that specifies which of the +`xmime:expectedContentTypes` the binary data represents. + +Given that the exact media type is not known +for this case, a Preferred Media Type binds to +`jakarta.activation.DataHandler`. `DataHandler` has a property +`get/setContentType` that should be kept synchronized with the value of +the JAXB binding for the `xmime:contentType` attribute. + +==== Binding WS-I Attachment Profile `ref:swaRef` + +An XML element or attribute with a type +definition of `ref:swaRef` is bound to a JAXB property with base type of +`jakarta.activation.DataHandler` and annotated with `@XmlAttachmentRef`. + +=== jakarta.xml.bind.attachments + +The abstract classes `AttachmentUnmarshaller` +and `AttachmentMarshaller` in package `jakarta.xml.bind.attachments` are +intended to be implemented by a MIME-based package processor, such as +Jakarta XML Web Services implementation, and are called during JAXB unmarshal/marshal. +The JAXB unmarshal/marshal processes the root part of a MIME-based +package, delegating knowledge of the overall package and its other parts +to the `Attachment*` class implementations. + +==== AttachmentUnmarshaller + +An implementation of this abstract class by a +MIME-based package processor provides access to package-level +information that is outside the scope of the JAXB unmarshal process. A +MIME-based package processor registers its processing context with a +Jakarta XML Binding processor using the method +`setAttachmentUnmarshaller(AttachmentUnmarshaller)` of +`jakarta.xml.bind.Unmarshaller`. + +Interactions between the Unmarshaller and the +abstract class are summarized below. The javadoc specifies the details. + +[source,java,indent="4"] +---- +public abstract class AttachmentUnmarshaller { +public boolean isXOPPackage(); +public abstract DataHandler getAttachmentAsDataHandler(String cid); +public abstract byte[] getAttachmentAsByteArray(String cid); +} +---- + +The JAXB unmarshal process communicates with +a MIME-based package processor via an instance of AttachmentUnmarshaller +registered with the unmarshaller. +<<opbin>> summarizes this +processing. + +* MTOM/XOP processing during unmarshal: + +When `isXOPPackage()` returns true, the unmarshaller replaces each XOP +include element it encounters with MIME content returned by the +appropriate `getAttachment*()` method. +* WS-I AP processing: + +Each element or attribute of type definition `ref:swaRef`, a content-id +uri reference to binary data, is resolved by the unmarshal process by a +call to the appropriate `getAttachment*()` method. + +==== AttachmentMarshaller + +An `AttachmentMarshaller` instance is +registered with a `jakarta.xml.bind.Marshaller` instance using the method +`Marshaller.setAttachmentMarshaller()`. + +Interactions between the Marshaller and the +abstract class is summarized below. See the javadoc for details. + +[source,java,indent="4"] +---- +public abstract class AttachmentMarshaller { +public boolean isXOPPackage(); +public abstract String addMtomAttachment( + DataHandler data, + String elementNamespace, + String elementLocalName); +public abstract String addMtomAttachment( + byte[] data, + String elementNamespace, + String elementLocalName); +public abstract String addSwaRefAttachment(DataHandler data); +} +---- + +When an AttachmentMarshaller instance is +registered with the Marshaller, the following processing takes place. + +* MTOM/XOP processing: + +When `isXOPPackage()` is true and a JAXB property representing binary +data is being marshalled, the method `addMtomAttachment(..)` is called +to provide the MIME-based package processor the opportunity to decide to +optimize or inline the binary data. ++ +Note that the schema customization specified in +<<inlinebinarydata-declaration>> can be +used to declaratively disable XOP processing for binary data. +* WS-I AP processing: + +The `addSwaRefAttachment` method is called when marshalling content +represented by a `ref:swaRef` type definition. + + +One can declaratively customize swaRef processing within a schema using +schema customization @attachmentRef of <jaxb:property>, specified in +<<usage-4>>. + +.JAXB marshal/unmarshalling of optimized binary content. +[[opbin]] +image::xmlb-23.svg[image] +
diff --git a/spec/src/main/asciidoc/appI-changelog.adoc b/spec/src/main/asciidoc/appI-changelog.adoc new file mode 100644 index 0000000..8176909 --- /dev/null +++ b/spec/src/main/asciidoc/appI-changelog.adoc
@@ -0,0 +1,503 @@ +// +// Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation +// + +[appendix] +== Change Log + +=== Changes in Version 4 + +* fixed cross-references in the specification document +* removed deprecated `jakarta.xml.bind.Validator` +* removed constraints on using `java.beans.Introspector` +* removed deprecated steps in implementation lookup algorithm - dropped search +through `jaxb.properties` file, `jakarta.xml.bind.context.factory` and +`jakarta.xml.bind.JAXBContext` properties and `/META-INF/services/jakarta.xml.bind.JAXBContext` +resource file +* added Jakarta XML Binding implementation lookup through the properties `Map` +passed to `JAXBContext.newInstance` methods +* dropped requirement on compatibility with JAXB 1.0 + +=== Changes in Version 3 + +* Changed specification version and license. +* Package namespace changed to `jakarta.xml.bind.*`. +* Customization schema namespace changed to `https://jakarta.ee/xml/ns/jaxb`, +minimal supported version set to `3.0`. +* Relaxed requirements tight to JAXB 1.0 +* Removed inclusion in Java SE from specification goals + +=== Changes since Maintenance Release 2 + +* Section 4.2 added note related to Java Platform Module System. +* Added section 4.9 Implementation discovery. +* Added change logs for MR1 and MR2. + +=== Changes since Maintenance Release 1 + +Details can be found at: +_https://jcp.org/aboutJava/communityprocess/maintenance/jsr222/222mr2.zip_ + +* Section 8.9.1.1 @XmlElement target extended for type PARAMETER +* Section 8.9.3.1 added required annotation element to @XmlElementRef + +=== Changes since Final Draft + +Details can be found at: +https://jcp.org/aboutJava/communityprocess/maintenance/jsr222/222changes.txt + +* Section 7.1.3 External Binding Declaration @schemaLocation and @node are optional. +* Section E.2 3 and 3b updated. +* Section 3.5.2.1 constraint violation updated JAXB 2.0 implementation +delegate to the validation API in JAXP 1.3. + +=== Changes since Proposed Final Draft + +* Section 7.6.1.2, nameXmlTransform: Apply +customization [ _jaxb:nameXmlTransform]_ addition of prefix and/or +suffix after XML to Java name transformation is applied. +* Section 6.7.1-2 changed to allow generation +of element factory method for abstract element. Change was necessary to +support element substitution. The abstract element factory method is +generated so it can be annotated with JAXB program annotation that +enables element substitution, _@XmlElementDecl.substitutionHeadName_ . +* Section 7.7.3.5 fixed the example with +<class> customization. Made the corresponding change in Section 6.7.2 so +Objectfactory method creates an instance of generated class. +* Chapter 8 and appendix B: +@XmlJavaTypeAdapter on class, interface or enum type is mutually +exclusive with any other annotation. +* Chapter 8: added @XmlElement.required() for +schema generation +* Section 8.7.1.2: clarifications for no-arg +static factory method in @XmlType annotation. +* Section 8.9.13.2: Disallow use of @XmlList +on single valued property. +* Section 8.9.8.2, Table 8-30 : +@XmlAnyAttribute maps to anyAttribute with a namespace constraint with +##other. +* Section 8.9.1.2: If @XmlElement.namespace() +is different from that of the target namespace of the enclosing class, +require a global element to be generated in the namespace specified in +@XmlElement.namespace() to make the generated schema complete. +* Section 8.9.15: Allow @XmlMimeType on a +parameter. +* Section 8.9.16: Allow @XmlAttachmentRef on +a parameter. +* Chapter 8: removed constraint check that +namespace() annotation element must be a valid namespace URI from +different annotations. +* Chapter 8: Java Persistence and JAXB 2.0 +alignment related changes. + +constructor requirement: public or protected no-arg constructor + +@AccessType renamed to @XmlAccessType. + +@AccessorOrder renamed to @XmlAccessOrder. + +@XmlTransient is mutually exclusive with other annotations. + +@A property or field that is transient or marked with @XmlTransient and +specified in @XmlType.propOrder is an error. +* Chapter 8: Clarifications for generics - +type variables with type bound, bounded wildcards and java.util.Map. +* Section 8.9: reworked constraints on the +properties to handle different use cases permitted by JavaBean design +pattern. +* Section 8: Take elementFormDefault into +account when determining the namespace for @XmlElement and +@XmlElementWrapper annotations. +* Section 8: Added missing mapping +constraints for @XmlElementWrapper. Also disallow use of @XmlIDREF with +@XmlElementWrapper. +* Chapter 9, “Compatibility”: clarified +schema generator and schema compiler requirements. +* Section B.2.5: Added marshalling of null +value as xsi:nil or empty element based upon @XmlElement.required and +@XmlElement.nillable annotation elements. +* Section B.5: Added new section and moved +runtime requirements on getters/setters to here. + +=== Changes since Public Review + +* Update <<Compatibility>> for JAXB 2.0 technology. Additional requirements added +for Java Types to XML binding and the running of JAXB 1.0 application in +a JAXB 2.0 environment. +* Added external event callback mechanism, +_Unmarshaller.Listener_ and _Marshaller.Listener_ . +* Added new unmarshal method overloading, +unmarshal by declaredType, to _Unmarshaller_ and _Binder_ . Enables +unmarshalling a root element that corresponds with a local element +declaration in schema. +* Added <<modifying-schema-derived-code>> describing use of annotation +_@javax.annotation.Generated_ to distinguish between generated and +user-modified code in schema-derived class. +* Element declaration with anonymous complex +type definition binds to _@XmlRootElement_ annotated class except for +cases in Section 6.7.3.1. +* Removed <jaxb:globalBindings +nullsInCollection>. The customization <jaxb:property +generateElementProperty=”true”> can achieve same desired result. +* Added clarification that mapping two or +more target namespaces to same java package can result in naming +collision that should be detected as an error by schema compiler. +* Added <jaxb:factoryMethod> customization to +enable the resolution of name collisions between factory methods. +* First parameter to any of the overloaded +Marshaller.marshal() methods must be a JAXB element; otherwise, method +must throw MarshalException. See updated Marshaller javadoc and +<<Marshalling>> for details. +* Prepend “_”, not “Original”, to a Java +class name representing an XML Schema type definition that has been +redefined in <<Redefine>>. +* Format for class name in _jaxb.index_ file +clarified in JAXBConext.newInstance(String) method javadoc. +* Clarifications on @dom customization in +Section 7.12.. +* Chapter 8: Added support for +@XmlJavaTypeAdapter at the package level. +* Chapter 8: Added new annotation +@XmlJavaTypeAdapters as a container for defining multiple +@XmlJavaTypeAdapters at the package level. +* Chapter 8: Added support for @XmlSchemaType +at the package level. +* Chapter 8: Added @XmlSchemaTypes as a +container annotation for defining multiple @XmlSchemaType annotations at +the package level. +* Chapter 8: added lists of annotations +allowed with each annotation. +* Chapter 8: Bug fixes and clarifications +related to mapping and mapping constraints. +* Chapter 8: Expanded collection types mapped +to java.util.Map and java.util.Collection. +* Appendix B. Incorporate event call backs +into unmarshalling process. +* Appendix B: Incorporate into unmarshalling +process additional unmarshal methods: Binder.unmarshal(..), unmarshal +methods that take a declaredType as a parameter - Binder.unmarshal(..., +declaredType) and Unmarshaller.unmarshal(...,declaredType). + +=== Changes since Early Draft 2 + +* Simple type substitution support added in +Section 6.7.4.2. +* Updates to enum type binding. (Section +7.5.1, 7.5.5, 7.10, Appendix D.3) +* Optimized binary data.(Appendix H) and +schema customizations. (Section 7.13 and 7.10.5) +* Clarification for _<jaxb:globalBindings +underscoreHandling=”asCharInWord”>_ (Appendix D.2) +* Added Unmarshal and Marshal Callback Events +(Section 4.4.1,4.5.1) +* Clarification: xs:ID and xs:IDREF can not +bind to an enum type. (Section 6.2.3,7.10.5) +* Added schema customization: + +<jaxb:globalBinding localScoping=”nested”|”toplevel”> (Section 7.5.1) + +<jaxb:inlineBinaryData> (Section 7.13) + +<jaxb:property @attachmentRef/> (Section 7.8.1) +* Updated Section 6 and 7 with mapping +annotations that are generated on schema-derived JAXB +classes/properties/fields. +* Added jakarta.xml.bind.Binder class to +Section 4.8.2. +* Runtime generation of schema from JAXB +mapping annotations: JAXBContext.generateSchema(). +* Chapter 8: added @XmlList: bind +property/field to simple list type +* Chapter 8: added @XmlAnyElement: bind +property/field to xs:any +* Chapter 8: added @XmlAnyAttribute - bind +property/field to xs:anyAttribute +* Chapter 8. added @XmlMixed - for mixed +content +* Chapter 8, added annotations for +attachment/MTOM support: @XmlMimeType, @XmlAttachmentRef +* Chapter 8: added @XmlAccessorOrder - to +specify default ordering. +* Chapter 8: added @XmlSchemaType mainly for +use in mapping XMLGregorianCalendar. +* Chapter 8: map java.lang.Object to +xs:anyType +* Chapter 8: added mapping of +XMLGregorianCalendar +* Chapter 8: added mapping of generics - type +variables, wildcardType +* Chapter 8: added mapping of binary data +types. +* Chapter 8: default mappings changed for +class, enum type. +* Chapter 8: default mapping of propOrder +specified. +* Chapter 8: mapping of classes - zero arg +constructor, factory method. +* Chapter 8: added Runtime schema generation +requirement. +* Chapter 8: Clarified mapping constraints +and other bug fixes. +* Added Appendix B new: Added Runtime +Processing Model to specify the marshalling/unmarshalling for dealing +with invalid XML content and schema evolution. +* Updated Appendix C to JAXB 2.0 binding +schema. + +=== Changes since Early Draft + +* Updated goals in Introduction. +* Update to Section 3 “Architecture” +introducing Java to Schema binding. +* section on portable annotation-driven +architecture. +* section on handling of invalid XML content +* Binding Framework +* Replaced _IXmlElement<T>_ interface with +_JAXBElement<T>_ class. (JAXBElement is used for schema to java binding) +* _JAXBIntrospector_ introduced _._ +* Add flexible (by-name) unmarshal and +describe JAXB 1.0 structural unmarshalling. +* Moved deprecated on-demand validation, +accessible via jakarta.xml.bind.Validator, to Appendix H. +* XSD to Java Binding +* Bind complex type definition to value class +by default. +* Schema-derived code is annotated with JAXB +java annotations. +* Bind XSD simpleType with enum facet to J2SE +5.0 enum type. Change default for jaxb:globalBinding @typeEnumBase from +xs:NCName to xs:string. +* _ObjectFactory_ factory methods no longer +throws _JAXBException_ . +* Added customizations + +[jaxb:globalBindings] @generateValueClass, @generateElementClass, +@serializable, @optionalProperty, @nullInCollection + +[jaxb:property] @generateElementProperty +* Add binding support for redefine +* Simplified following bindings: + +- union by binding to String rather than Object. + +- Attribute Wildcard binds to portable abstraction of a +java.util.Map<QName, String>, not jakarta.xml.bind.AttributeMap. + +- bind xsd:anyType to java.lang.Object in JAXB property method +signatures and element factory method(support element/type substitution) +* Changes required for default and customized +binding in order to support flexible unmarshalling described in Section +4.4.3. +* Java to XSD Binding +* Added @XmlAccessorType for controlling +whether fields or properties are mapped by default. +* Added @XmlEnum and @XmlEnumValue for +mapping of enum types. +* Collections has been redesigned to allow +them to be used in annotation of schema derived code: + + - removed @XmlCollectionItem and +@XmlCollection + +- Added annotations parameters to @XmlElement + +- added @XmlElementRef + +- added @XmlElements and @XmlElementRefs as +containers for collections of @XmlElements or @XmlElementRefs. + +- added @XmlElementWrapper for wrapping of +collections. + +* Added mapping of anonymous types. +* Added mapping of nested classes to schema +* Added @XmlRootElement for annotating +classes. @XmlElement can now only be used to annotate properties/fields. +* Added @XmlElementRef for supporting schema +derived code as well as mapping of existing object model to XML +representation. javadoc for @XmlElementRef contains an example +* Added @XmlElementDecl on object factory +methods for supporting mapping of substitution groups for schema -> java +binding. +* Redesigned Adapter support for mapping of +non Java Beans. + + - new package +jakarta.xml.bind.annotation.adapters for adapters. + +- Added XmlAdapter base abstract class for +all adapters. + +- redesigned and moved XmlJavaTypeAdapter to +the package. + +* Moved default mapping from each section to +“Default Mapping” section. +* Consistent treatment of defaults +“##default” +* Removed JAX-RPC 1.1 Alignment. JAX-WS 2.0 +is deferring its databinding to JAXB 2.0. + +=== Changes for 2.0 + +Early Draft v0.4 + +* Updated <<Introduction>>. +* Added <<Requirements>> +* Added <<Java Types To XML>> for Java Source to XML Schema mapping. +* XML Schema to schema-derived Java Binding +changes +* Element handling changes to support element +and type substitution in <<Java Element Representation Summary>>, +<<Element Declaration>> and <<Element Property>>. +* Added <<Attribute Wildcard>> binding +* Support binding all wildcard content in +<<Bind wildcard schema component>>. +* Addition/changes in +<<Java Mapping for XML Schema Built-in Types>>. +* XML Schema to Java Customization +* Added ability to doable databinding for an +XML Schema fragment in <<dom-declaration>>. + +=== Changes for 1.0 Final + +* Added method +_jakarta.xml.bind.Marshaller.getNode(Object)_ which returns a DOM view of +the Java content tree. See method's javadoc for details. + +=== Changes for Proposed Final + +* Added <<Compatibility>>. +* Section 5.9.2, “General Content Property,” +removed value content list since it would not be tractable to support +when type and group substitution are supported by JAXB technology. +* Added the ability to associate +implementation specific property/value pairs to the unmarshal, +validation and JAXB instance creation. Changes impact Section 3.4 +“Unmarshalling,” Section 3.5 “Validator” and the ObjectFactory +description in Section 4.2 “Java Package.” +* Section 6.12.10.1, “Bind a Top Level Choice +Model Group” was updated to handle Collection properties occurring +within a Choice value class. +* Section 6.12.11, “Model Group binding +algorithm” changed step 4(a) to bind to choice value class rather than +choice content property. +* <<List Property>> and <<isset-property-modifier>> +updated so one can discard set value for a List property via calling +unset method. +* At end of Section 4, added an UML diagram +of the JAXB Java representation of XML content. +* Updated default binding handling in +<<Model Group Definition>>. Specifically, +value class, element classes and enum types are derived from the content +model of a model group definition are only bound once, not once per time +the group is referenced. +* Change <<Bind wildcard schema component>>, to bind to a JAXB property with a +basetype of _java.lang.Object,_ not _jakarta.xml.bind.Element._ Strict and +lax wildcard validation processing allows for contents constrained only +by _xsi:type_ attribute. Current APIs should allow for future support of +_xsi:type_ . +* Simplify anonymous simple type definition +binding to typesafe enum class. Replace incomplete approach to derive a +name with the requirement that the @name attribute for element +typesafeEnumClass is mandatory when associated with an anonymous simple +type definition. +* Changed <<Deriving Class Names for Named Model Group Descendants>> +to state that all classes and interfaces generated for XML Schema component that +directly compose the content model for a model group, that these +classes/interfaces should be generated once as top-level interface/class +in a package, not in every content model that references the model +group. +* Current <<globalbindings-declaration>>: +* Replaced _modelGroupAsClass_ with +_bindingStyle_ . +* Specified schema types that cannot be +listed in _typesafeEnumBase_ . +* <<property-declaration>>: +* Clarified the customization of model groups +with respect to _choiceContentProperty, elementBinding and +modelGroupBinding._ Dropped _choiceContentProperty_ from the +_<property>_ declaration. +* Added _<baseType>_ element and clarified +semantics. +* Added support for customization of simple +content. +* Added customization of simple types at +point of reference. +* Clarified restrictions and relationships +between different customizations. +* <<javatype-declaration>>: +* Added +_jakarta.xml.bind.DatatypeConverterInterface_ interface. +* Added _jakarta.xml.bind.DatatypeConverter_ +class for use by user specified parse and print methods. +* Added +_javax.xml.namespace.NamespaceContext_ class for processing of QNames. +* Clarified print and parse method +requirements. +* Added narrowing and widening conversion +requirements. +* Throughout <<Customizing XML Schema to Java Representation Binding>>, +clarified the handling of invalid customizations. + +=== Changes for Public Draft 2 + +Many changes were prompted by inconsistencies +detected within the specification by the reference implementation +effort. Change bars indicate what has changed since Public Draft. + +* Section 4.5.4, “isSetProperty Modifier,” +describes the customization required to enable its methods to he +generated. +* Section 5.7.2, “Binding of an anonymous +type definition,” clarifies the generation of value class and typesafe +enum classes from an anonymous type definition. +* Section 5.2.4, “List” Simple Type +Definition and the handling of list members within a union were added +since public draft. +* Clarification on typesafe enum global +customization “generateName” in Section 5.2.3.4, “XML Enumvalue +To Java Identifier Mapping.” +* Clarification of handling binding of +wildcard content in Section 5.9.4. +* Chapter6, “Customization,” resolved binding +declaration naming inconsistencies between specification and normative +binding schema. +* removed _enableValidation_ attribute (a +duplicate of _enableFailFastCheck)_ from < _globalBindings>_ +declaration. +* Added default values for < +_globalBindings>_ declaration attributes. +* Changed _typesafeEnumBase_ to a list of +QNames. Clarified the binding to typesafe enum class. +* Clarified the usage and support for +_implClass_ attribute in _<class>_ declaration. +* Clarified the usage and support for +_enableFailFastCheck_ in the _<property>_ declaration. +* Added _<javadoc>_ to typesafe enum class, +member and property declarations. +* Mention that embedded HTML tags in +_<javadoc>_ declaration must be escaped. +* Fixed mistakes in derived Java code +throughout document. +* Added Section 7. Compatibility and updated +Appendix E.2 “Non required XML Schema Concepts” accordingly. + +=== Changes for Public Draft + +* <<Bind single occurrence choice group to a choice content property>>, +replaced overloading of choice content property setter method with a single +setter method with a value parameter with the common type of all members +of the choice. Since the resolution of overloaded method invocation is +performed using compile-time typing, not runtime typing, this +overloading was problematic. Same change was made to binding of union +types. +* Added details on how to construct factory +method signature for nested content and element classes. +* Section 3.3, default validation handler +does not fail on first warning, only on first error or fatal error. +* Add ID/IDREF handling in section 5. +* Updated name mapping in appendix C. +* <<Indexed Property>>, added getIDLenth() to indexed property. +* Removed ObjectFactory.setImplementation +method from <<Java Package>>. The negative +impact on implementation provided to be greater than the benefit it +provided the user. +* Introduced external binding declaration +format. +* Introduced a method to introduce extension +binding declarations. +* Added an appendix section describing JAXB +custom bindings that align JAXB binding with JAX-RPC binding from XML to +Java representation. +* Generate isID() accessor for boolean +property. +* Section 6, Customization has been +substantially rewritten.
diff --git a/spec/src/main/asciidoc/ch01-introduction.adoc b/spec/src/main/asciidoc/ch01-introduction.adoc new file mode 100644 index 0000000..2679e0e --- /dev/null +++ b/spec/src/main/asciidoc/ch01-introduction.adoc
@@ -0,0 +1,535 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +== [[a2]]Introduction + +XML is, essentially, a platform-independent +means of structuring information. An XML document is a tree of +_elements_ . An element may have a set of _attributes_ , in the form of +key-value pairs, and may contain other elements, text, or a mixture +thereof. An element may refer to other elements via _identifier_ +attributes or other types via _type_ attributes, thereby allowing +arbitrary graph structures to be represented. + +An XML document need not follow any rules +beyond the well-formedness criteria laid out in the XML 1.0 +specification. To exchange documents in a meaningful way, however, +requires that their structure and content be described and constrained +so that the various parties involved will interpret them correctly and +consistently. This can be accomplished through the use of a _schema_ . A +schema contains a set of rules that constrains the structure and content +of a document’s components, _i.e._ , its elements, attributes, and text. +A schema also describes, at least informally and often implicitly, the +intended conceptual meaning of a document’s components. A schema is, in +other words, a specification of the syntax and semantics of a +(potentially infinite) set of XML documents. A document is said to be +_valid_ with respect to a schema if, and only if, it satisfies the +constraints specified in the schema. + +In what language is a schema defined? The XML +specification itself describes a sublanguage for writing _document-type +definitions_ , or DTDs. As schemas go, however, DTDs are fairly weak. +They support the definition of simple constraints on structure and +content, but provide no real facility for expressing datatypes or +complex structural relationships. They have also prompted the creation +of more sophisticated schema languages such as XDR, SOX, RELAX, TREX, +and, most significantly, the XML Schema language defined by the World +Wide Web Consortium. The XML Schema language has gained widespread +acceptance. It is the schema language of choice for many of the XML +related specifications authored by industry standard working groups. + +Therefore, the design center for this specification is W3C XML Schema +language. + +=== Data binding + +Any nontrivial application of XML will, then, +be based upon one or more schemas and will involve one or more programs +that create, consume, and manipulate documents whose syntax and +semantics are governed by those schemas. While it is certainly possible +to write such programs using the low-level SAX parser API or the +somewhat higher-level DOM parse-tree API, doing so is not easy. The +resulting code is also difficult to maintain as the schemas evolve. +While useful to some, many applications access and manipulate XML +content within a document; its document structure is less relevant. + +It would be much easier to write XML-enabled +programs if we could simply map the components of an XML document to +in-memory objects that represent, in an obvious and useful way, the +document’s intended meaning according to its schema. Of what classes +should these objects be instances? In some cases there will be an +obvious mapping from schema components to existing classes, especially +for common types such as String, Date, Vector, and so forth. In +general, however, classes specific to the schema being used will be +required. + +Classes specific to a schema may be derived or +may already exist. In some application scenarios e.g. web services, a +data model composed using user authored classes may already exist. A +schema is derived from existing classes. In-memory objects are instances +of existing classes. In other application scenarios, a data model is +composed by authoring a schema. In such cases, rather than burden +developers with having to write classes specific to schema, we can +generate the classes directly from the schema. In all application +scenarios, we create a Java object-level _binding_ of the schema. + +But even applications manipulating documents +at conceptual object level, may desire to access or manipulate +structural information in a document, e.g. element names. Therefore, the +ability for an application to relate between the XML document +representation and the Java object-level binding enables the use of XML +operations over the XML document representation, e.g. Xpath.to bind XML +content to an object model such as DOM is useful. + +An _XML data-binding facility_ therefore +contains a _schema compiler and a schema generator_. A schema compiler +can consume a schema and generate schema derived classes specific to the +schema. A schema generator consumes a set of existing classes and +generates a schema. + +A schema compiler binds components of a +_source schema_ to schema-derived Java _value classes_. Each value class +provides access to the content of the corresponding schema component via +a set of JavaBeans-style access (_i.e._, `get` and `set`) methods. +_Binding declarations_ provides a capability to customize the binding +from schema components to Java representation. + +A schema generator binds existing classes to +schema components. Each class containing Java Beans-style access +(_i.e._, `get` and `set`) methods is bound to a corresponding schema +component. Program annotations provide a capability to customize the +binding from existing classes to derived schema components. + +Access to content is through in-memory representation of existing classes. + +Such a facility also provides a _binding +framework_ , a runtime API that, in conjunction with the derived or +existing classes, supports three primary operations: + +. The _unmarshalling_ of an XML document into +a tree of interrelated instances of both existing and schema-derived +classes, +. The _marshalling_ of such _content trees_ +back into XML documents, and +. The _binding,_ maintained by a _binder,_ +between an XML document representation and _content tree_. + +The unmarshalling process has the capability +to check incoming XML documents for validity with respect to the +schema. + + +.Binding XML to Java objects +image::xmlb-2.svg[image] + +To sum up: Schemas describe the structure and +meaning of an XML document, in much the same way that a class describes +an object in a program. To work with an XML document in a program we +would like to map its components directly to a set of objects that +reflect the document’s meaning according to its schema. We can achieve +this by compiling the schema into a set of derived content classes or by +compiling a set of existing classes into a schema and marshalling, +unmarshalling and validating XML documents that follow the schema. Data +binding thus allows XML-enabled programs to be written at the same +conceptual level as the documents they manipulate, rather than at the +more primitive level of parser events or parse trees. + +Schema evolution in response to changing +application requirements, is inevitable. A document therefore might not +always necessarily follow the complete schema, rather a part of a +versioned schema. Dealing with schema evolution requires both a +versioning strategy as well as more flexible marshalling, unmarshalling +and validation operations. + +XML applications, such as workflow +applications, consist of distributed, cooperative components +interoperating using XML documents for data exchange. Each distributed +component may need to access and update only a part of the XML document +relevant to itself, while retaining the fidelity of the rest of the XML +document. This is also more robust in the face of schema evolution, +since the changes in schema may not impact the part of the document +relevant to the application. The _binder_ enables _partial binding_ of +the relevant parts of the XML document to a content tree and +_marshalling_ updates back to the original XML document. + +=== Goals + +The Jakarta XML Binding architecture is designed with the +goals outlined here in mind. + +* [[a25,Full W3C XML Schema support]]Full W3C XML Schema support + + + +Support for XML Schema features not required +to be supported in JAXB 1.0 has been added in this version. + +* [[a27,Binding existing Java classes to generated XML schema]]Binding existing Java classes to generated XML schema + + + +This addresses application scenarios where +design begins with Java classes rather than an XML schema. One such +example is an application that exports itself as a web service that +communicates using SOAP and XML as a transport mechanism. The +marshalling of Java object graph is according to program annotations, +either explicit or defaulted, on the existing Java classes. + +* Meet data binding requirements for Jakarta XML Web Services + + + +Jakarta XML Web Services will use the XML data binding +facility defined by Jakarta XML Binding. Hence, +Jakarta XML Binding will meet all data binding +requirements of Jakarta XML Web Services. + +* Ease of Development: Leverage J2SE 5.0 Language Extensions + + + +For ease of development, J2SE 5.0 introduces +additional language language extensions.The language extensions include +generics (JSR 14), typesafe enums (JSR201), annotations (JSR 175). Use +of the language extensions in binding of XML schema components to Java +representation will result in a better and simpler binding, thus making +the application development easier. + +* Container Managed Environments + + + +A container managed environment separates +development from the deployment phases. This enables choice of +generation of artifacts such as derived classes or derived schema at +either development or deployment time. +Any requirements related to the deployment of +components using Jakarta XML Binding in a container managed environment +will be addressed. + +* Schema evolution + + + +Schema evolution is a complex and difficult +area; it is also an important area. It is particularly important in data +centric applications such as Web services, where distributed +applications interact using XML as a data interchange format but are +designed with different versions of the schema. It is also important in +document centric applications where schemas are designed for +extensibility. Strategies to address both application scenarios will be +investigated and support added accordingly. + +* Application specific behavior + + + +There should be a way to associate application +specific behavior with schema derived code in a portable manner. + +* Partial mapping of XML document relevant to application + + + +In some application scenarios, only a subset +of the data within a XML document may be relevant to the application. + +* Integration with other Java technologies + + + +Integration or relationship with the following +Java technologies will be clarified. + +** Streaming API For XML (JSR 173) (StAX) + +* Relationship to XML related specifications + + + +XML related specifications will be surveyed to +determine their relationship to Jakarta XML Binding. + +* Portability of Jakarta XML Binding mapped classes + + + +An architecture that provides for a fully +portable Jakarta XML Binding applications written to the Java SE platform +will be defined. + + + +Jakarta XML Binding annotated classes must be source level +and binary compatible with any other Jakarta XML Binding binding framework +implementation. Schema-derived interfaces/implementation +classes are only required to be source code compatible with other +Jakarta XML Binding implementations of the same version. + +* Preserving equivalence - Round tripping (Java to XML to Java) + + + +Transforming a Java content tree to XML +content and back to Java content again should result in an equivalent +Java content tree before and after the transformation. + +* Preserving equivalence - Round tripping (XML to Java to XML) + + + +While JAXB 1.0 specification did not require +the preservation of the XML information set when round tripping from XML +document to Java representation and back to XML document again, it did +not forbid the preservation either. The same applies to Jakarta XML Binding +specification. + +* Unmarshalling invalid XML content + + + +Unmarshalling of invalid content was out of +scope for JAXB 1.0. Simple binding rules and unmarshalling mechanisms +that specify the handling of invalid content will be defined. + +* Ease of Use - Manipulation of XML documents in Java + + + +Lower the barrier to entry to manipulating XML +documents within Java programs. Programmers should be able to access and +modify XML documents via a Java binding of the data, not via SAX or DOM. +It should be possible for a developer who knows little about XML to +compile a simple schema and immediately start making use of the classes +that are produced. + + + +Rather than not supporting XML Schema extensibility concepts that can +not be statically bound, such as unconstrained wildcard content, these +concepts should be exposed directly as DOM or some other XML infoset +preserving representation since there is no other satisfactory static +Java binding representation for them. + +* Customization + + + +Applications sometimes require customization +to meet their data binding requirements. Customization support will +include: + +** XML to Java: + + + +A standard way to customize the binding of +existing XML schema components to Java representation will be provided. +JAXB 1.0 provided customization mechanisms for the subset of XML Schema +components supported in JAXB 1.0. Customization support will be extended +to additional XML Schema features to be supported in this version of the +specification, see <<a25>>. + +** Java to XML: + + + +A standard way to customize the binding of +existing Java classes to XML schema will be added, see <<a27>>. + +* Schema derived classes should be natural + + + +Insofar as possible, derived classes should +observe standard Java API design guidelines and naming conventions. If +new conventions are required then they should mesh well with existing +conventions. A developer should not be astonished when trying to use a +derived class. + +* Schema derived classes should match conceptual level of source schema + + + +It should be straightforward to examine any +content-bearing component of the source schema and identify the +corresponding Java language construct in the derived classes. + + +=== Non-Goals + +* Support for Java versions prior to J2SE 5.0 + + + +Jakarta XML Binding relies on many of the Java language +features added in J2SE 5.0. It is not a goal to support Jakarta XML Binding +on Java versions prior to J2SE 5.0. + +* Explicit support for specifying the binding of DTD to a Java representation. + + + +While it was desired to explicitly support +binding DTD to a Java representation, it became impractical to describe +both XML Schema binding and DTD binding. The existence of several +conversion tools that automate the conversion of a DTD to XML Schema +allows DTD users to be able to take advantage of Jakarta XML Binding +technology by converting their existing DTDs to XML Schema. + +* XML Schema Extensions + + + +XML Schema specification allows the annotation +of schemas and schema components with appinfo elements. JAXB 1.0 +specifies the use of appinfo elements to customize the generated code. +For Jakarta XML Binding specification, use of appinfo elements for +customization of generated code continues to be in scope. However, use +of appinfo element to introduce validation constraints beyond those +already described in XML Schema 1.0 specification is out of scope. + +* Support for SOAP Encoding + + + +SOAP Encoding is out of scope. Use of the SOAP +encoding is essentially deprecated in the web services community, e.g. +the WS-I Basic Profile[WSIBP] excludes SOAP encoding. + +* Support for validation on demand by schema derived classes + + + +While working with a content tree +corresponding to an XML document it is often necessary to validate the +tree against the constraints in the source schema. It is a non goal +in Jakarta XML Binding specification, which leverages the JAXP validation API, +to make the validation possible to do at any time, without the user +having to first marshal the tree into XML. + +* Object graph traversal + + + +Portable mechanisms to traverse a graph of +JavaBean objects will not be addressed in Jakarta XML Binding specification. + +* Mapping any existing Java classes to any existing XML schema + + + +The Jakarta XML Binding annotation mechanism is not +sophisticated enough to enable mapping an arbitrary class to all XML +schema concepts. + +=== Conventions + +Within normative prose in this specification, +the words _should_ and _must_ are defined as follows: + +* __should__ + +Conforming implementations are permitted to but need not behave as +described. +* __must__ + +Conforming implementations are required to behave as described; +otherwise they are in error. + +Throughout the document, references to JAXB refer to the Jakarta XML Binding +unless otherwise noted. The XML namespace +prefix `xs:` and `xsd:` refers to schema components in W3C XML Schema +namespace as specified in [XSD Part 1] and [XSD Part 2]. The XML +namespace prefix `xsi:` refers to the XML instance namespace defined in +[XSD Part 1]. Additionally, the XML namespace prefix `jaxb:` refers to +the Jakarta XML Binding namespace, `https://jakarta.ee/xml/ns/jaxb`. The XML +namespace prefix `ref:` refers to the namespace +`http://ws-i.org/profiles/basic/1.1/xsd` as defined in [WSIBP] and +[WSIAP]. + +All examples in the specification are for +illustrative purposes to assist in understanding concepts and are +non-normative. If an example conflicts with the normative prose, the +normative prose always takes precedence over the example. + +=== Expert Group Members + +The following people have contributed to this +specification. + +[cols=",",] +|=== +|Chavdar Baikov |SAP +AG + +|David Bau | + +|Arnaud Blandin | + +|Stephen Brodsky +|IBM + +|Russell Butek |IBM + +|Jongjin Choi |TMAX + +|Glen Daniels |Sonic +Software + +|Blaise Doughan +|Oracle + +|Christopher Fry +|BEA Systems + +|Stanley Guan +|Oracle + +|Mette Hedin | + +|Kohsuke Kawaguchi +|Sun Microsystems, Inc. + +|Sravan Kumar +|Pramati Technologies + +|Changshin Lee |Tmax +Soft, Inc. + +|Anjana Manian +|Oracle + +|Ed Merks |IBM + +|Steve Perry +|Fidelity Information Services + +|Radu Preotiuc-Pietro +|BEA + +|Srividya Rajagopalan +|Nokia Corporation + +|Yann Raoul | + +|Bjarne Rasmussen +|Novell, Inc. + +|Adinarayana Sakala +|IONA Technologies PLC + +|Dennis M. Sosnoski +| + +|Keith Visco | + +|Stefan Wachter | + +|Umit Yalcinalp | + +|Scott Ziegler |BEA +Systems + +|Zulfi Umrani +|Novell, Inc. +|=== + +=== Acknowledgements + +This document is a derivative work of concepts +and an initial draft initially led by Mark Reinhold of Sun Microsystems. +Our thanks to all who were involved in pioneering that initial effort. +The feedback from the Java User community on the initial Jakarta XML Binding +technology prototype greatly assisted in identifying requirements and directions. + +The data binding experiences of the expert +group members have been instrumental in identifying the proper blend of +the countless data binding techniques that we have considered in the +course of writing this specification. We thank them for their +contributions and their review feedback. + +Kohsuke Kawaguchi and Ryan Shoemaker have +directly contributed content to the specification and wrote the +companion javadoc. The following Jakarta XML Binding technology team members +have been invaluable in keeping the specification effort on the right track: +Tom Amiro, Leonid Arbouzov, Evgueni Astigueevitch, Jennifer Ball, Carla +Carlson, Patrick Curran, Scott Fordin, Omar Fung, Peter Kacandes, Dmitry +Khukhro, Tom Kincaid, K. Ari Krupnikov, Ramesh Mandava, Bhakti Mehta, Ed +Mooney, Ilya Neverov, Oleg Oleinik, Brian Ogata, Vivek Pandey, Cecilia +Peltier, Evgueni Rouban and Leslie Schwenk. The following people, all +from Sun Microsystems, have provided valuable input to this effort: +Roberto Chinnici, Chris Ferris, Mark Hapner, Eve Maler, Farrukh Najmi, +Eduardo Pelegri-llopart, Bill Shannon and Rahul Sharma. + +The Jakarta XML Binding TCK software team would like to +acknowledge that the NIST XML Schema test suite [NIST] has greatly +assisted the conformance testing of this specification. + +=== Acknowledgements for Jakarta XML Binding + +Original version of this specification was created +under the Java Community Process as JSR-222. This specification is +shaped by valuable input from expert group members, people with Sun, and +Java User community feedback based on their experience with JAXB 1.0. + +The data binding experience of the expert +group has been very instrumental in identifying usage scenarios +(including those from web services),design and evaluation of different +databinding techniques. We thank them for their contributions and review +feedback. + +The following people, all from Sun +Microsystems, have provided valuable input. The experiences of the +reference implementation team, led by Kohsuke Kawaguchi, has been +influential in identifying data binding solutions. Kohsuke Kawaguchi and +Ryan Shoemaker have directly contributed content to the companion +javadoc.Addtional feedback was provided by the following JAXB technology +team members: Bhakti Mehta, Ed Mooney, Ryan Shoemaker, Karthikeyan +Krishnamurthy, Tom Amiro, Leonid Arbouzov, Leonid Kuskov, Dmitry +Fazunenko, Dmitry Lepekhin, Alexey Vishentsev, Omar Fung, and Anita +Jindal. Valuable input was provided by the following people from Sun: +Eduardo Pelegri-Llopart, Graham Hamilton, Mark Hapner, Bill Shannon. + + +The Jakarta XML Binding TCK software team would like to +acknowledge that the NIST XML Schema test suite [NIST] has greatly +assisted the conformance testing of this specification. +
diff --git a/spec/src/main/asciidoc/ch02-requirements.adoc b/spec/src/main/asciidoc/ch02-requirements.adoc new file mode 100644 index 0000000..59fd749 --- /dev/null +++ b/spec/src/main/asciidoc/ch02-requirements.adoc
@@ -0,0 +1,147 @@ +// +// Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation +// + +== Requirements + +This chapter specifies the scope and requirements for this version of the specification. + +=== XML Schema to Java + +==== W3C XML Schema support + +The mapping of the following XML Schema +components must be specified. + +* type substitution ( _@xsi:type_ ) +* element substitution group ( _<xs:element +@substitutionGroup_ >) +* wildcard support( _xs:any_ and +_xs:anyAttribute_ ) +* identity constraints ( _xs:key_ , +_xs:keyref_ and _xs:unique_ ) +* redefinition of declaration ( _xs:redefine_ +) +* NOTATION + +For binding builtin XML Schema datatypes which +do not map naturally to Java datatypes, Java datatypes specified by JAXP +1.3 (JSR 206) must be used. + +==== Default Bindings + +There must be a detailed, unambiguous +description of the default mapping of schema components to Java +representations in order to satisfy the portability goal. + +==== Customized Binding Schema + +A binding schema language and its formats must +be specified. There must be a means to describe the binding without +requiring modification to the original schema. Additionally, the same +XML Schema language must be used for the two different mechanisms for +expressing a binding declaration. + +==== Overriding default binding behavior + +Given the diverse styles that can be used to +design a schema, it is daunting to identify a single ideal default +binding solution. For situations where several equally good binding +alternatives exist, the specification will describe the alternatives and +select one to be the default (see <<Customized Binding Schema>>). + +The binding schema must provide a means to +specify an alternative binding for the scope of an entire schema. This +mechanism ensures that if the default binding is not sufficient, it can +easily be overridden in a portable manner. + +==== Jakarta XML Web Services + +===== Backward Compatibility + +Mapping of XML Schema to schema derived Java +classes as specified in versions of Jakarta XML-RPC either by default or by +customization is out of scope. + +===== Binding XML Schema to schema derived classes + +A binding of XML Schema constructs to schema +derived classes must be specified. + +===== Accessing MIME content stored as an attachment + +The W3C XMLP MTOM/XOP document and WS-I AP +1.0[WSIAP] both provide mechanisms for embedding references to SOAP +attachments in SOAP messages. It is desirable to bind these to suitable +Java types (e.g. Image or DataHandler) rather than just provide URI +refs. + +===== Serializable + +A customization must be specified to enable +schema derived classes to implement the `java.io.Serializable` +interface. This capability enables the schema derived instance to be +passed as EJB method parameter and to any other API that requires +Serializable instances. + +===== Disabling Databinding + +A customization to disable databinding must be +specified. When databinding is disabled, an XML Schema component is +bound to an XML fragment representation rather than a strongly typed +datatype determined by mapping rules. Binding to XML fragment allows the +use of alternative binding technologies for example to perform XML +operations. + +=== Java to XML Schema + +==== Default Mapping + +A default mapping Java constructs to XML +Schema must be specified. The default mapping may be overridden by +customizations described in <<Customized Mapping>>. + +==== Customized Mapping + +A customization mechanism to override default +mapping of Java constructs to XML Schema constructs must be specified. +Since XML Schema provides a much richer feature set than Java language +for defining data models, the scope of customizations will be restricted +to enable mapping to commonly used XML Schema constructs. + +Support for the following mechanism must be +specified: + +* customization mechanism using the JSR175 +program annotation facility. + +==== Jakarta XML Web Services + +===== WSDL <types> + +The WSDL <types> is generated using Java +constructs to XML Schema mapping. The latter should therefore define +customizations that enable mapping to XML Schema constructs commonly +used in web services, subject to the requirements in +<<Customized Mapping>> and <<Default Mapping>>. + +===== Backward Compatibility + +Mapping of existing Java constructs to XML +Schema constructs as specified in Jakarta XML-RPC, either by +default or through customization, is out of scope. + +=== Binding Framework + +==== Disabling schema validation + +The specification will provide an ability to +disable schema validation for unmarshal and marshal operations. + +There exist a significant number of scenarios +that do not require validation and/or can not afford the overhead of +schema validation. An application must be allowed to disable schema +validation checking during unmarshal and marshal operations. The goal of +this requirement is to provide the same flexibility and functionality +that a SAX or DOM parser allows for. +
diff --git a/spec/src/main/asciidoc/ch03-architecture.adoc b/spec/src/main/asciidoc/ch03-architecture.adoc new file mode 100644 index 0000000..8d02ade --- /dev/null +++ b/spec/src/main/asciidoc/ch03-architecture.adoc
@@ -0,0 +1,532 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +== Architecture + +=== Introduction + +This chapter describes the architectural +components, comprising the XML-databinding facility, that realize the +goals outlined in <<Goals>>. The scope of +this version of specification covers many additional goals beyond those +in JAXB 1.0. As a result, JAXB 1.0 architecture has been revised +significantly. + +=== Overview + +The XML data-binding facility consists of the +following architectural components: + +* *_schema compiler_*: A schema compiler binds a +_source schema_ to a set of _schema derived program elements_. The binding +is described by an XML-based language, *_binding language_*. +* *_schema generator_*: A schema generator maps a +set of existing program elements to a _derived schema_. The mapping is +described by *_program annotations_*. +* *_binding runtime framework_* that provides two +primary operations for accessing, manipulating and validating XML +content using either schema derived or existing program elements: + +** _Unmarshalling_ is the process of reading +an XML document and constructing a tree of _content objects_. Each content +object is an instance of either a schema derived or an existing program +element mapped by the schema generator and corresponds to an instance in +the XML document. Thus, the content tree reflects the document’s +content. + +Validation can optionally be enabled as part of the +unmarshalling process. _Validation_ is the process of verifying that an +xml document meets all the constraints expressed in the schema. +** _Marshalling_ is the inverse of +unmarshalling, i.e., it is the process of traversing a content tree and +writing an XML document that reflects the tree’s content. Validation can +optionally be enabled as part of the marshalling process. + +As used in this specification, the term +_schema_ includes the W3C XML Schema as defined in the XML Schema 1.0 +Recommendation[XSD Part 1][XSD Part 2]. <<a210>> illustrates relationships +between concepts introduced in this section. + +.Non-Normative Jakarta XML Binding Architecture diagram +[[a210]] +image::xmlb-3.svg[image] + +JAXB-annotated classes are common to both +binding schemes. They are either generated by a schema compiler or the +result of a programmer adding JAXB annotations to existing Java classes. +The universal unmarshal/marshal process is driven by the JAXB +annotations on the portable JAXB-annotated classes. + +Note that the binding declarations object in +the above diagram is logical. Binding declarations can either be inlined +within the schema or they can appear in an external binding file that is +associated with the source schema. + +.JAXB 1.0 style binding of schema to interface/implementation classes. +image::xmlb-4.svg[image] + +Note that the application accesses only the +schema-derived interfaces, factory methods and `jakarta.xml.bind` APIs +directly. This convention is necessary to enable switching between JAXB +implementations. + +=== Java Representation + +The content tree contains instances of _bound types_, +types that bind and provide access to XML content. Each bound +type corresponds to one or more schema components. As much as possible, +for type safety and ease of use, a bound type that constrains the values +to match the schema constraints of the schema components. The different +bound types, which may be either schema derived or authored by a user, +are described below. + +*_Value Class_* A coarse grained schema +component, such as a complex type definition, is bound to a Value class. +The Java class hierarchy is used to preserve XML Schema’s “derived by +extension” type definition hierarchy. JAXB-annotated classes are +portable and in comparison to schema derived interfaces/implementation +classes, result in a smaller number of classes. + +*_Property_* A fine-grained schema component, +such as an attribute declaration or an element declaration with a simple +type, is bound directly to a _property_ or a _field_ within a value class. + +A property is _realized_ in a value class by +a set of JavaBeans-style _access methods_. These methods include the +usual `get` and `set` methods for retrieving and modifying a property’s +value; they also provide for the deletion and, if appropriate, the +re-initialization of a property’s value. + +Properties are also used for references from +one content instance to another. If an instance of a schema component +_X_ can occur within, or be referenced from, an instance of some other +component _Y_ then the content class derived from _Y_ will define a +property that can contain instances of _X_. + +Binding a fine-grained schema component to a +field is useful when a bound type does not follow the JavaBeans +patterns. It makes it possible to map such types to a schema without the +need to refactor them. + +*_Interface_* JAXB 1.0 bound schema components +(XML content) to schema derived content interfaces and implementation +classes. The interface/implementation classes tightly couple the schema +derived implementation classes to the Jakarta XML Binding implementation +runtime framework and are thus not portable. The binding of schema components to +schema derived interfaces continues to be supported in Jakarta XML Binding. + +[NOTE] +.Note +==== +The mapping of existing Java interfaces to schema constructs is not +supported. Since an existing class can implement multiple interfaces, +there is no obvious mapping of existing interfaces to XML schema constructs. + +==== + +*_Enum type_* J2SE 5.0 platform introduced +linguistic support for type safe enumeration types. Enum type are used +to represent values of schema types with enumeration values. + +*_Collection type_* Collections are used to +represent content models. Where possible, for type safety, parametric +lists are used for homogeneous collections. For e.g. a repeating element +in content model is bound to a parametric list. + +*_DOM node_* In some cases, binding XML content +to a DOM or DOM like representation rather than a collection of types is +more natural to a programmer. One example is an open content model that +allows elements whose types are not statically constrained by the +schema. + +Content tree can be created by unmarshalling +of an XML document or by programmatic construction. Each bound type in +the content tree is created as follows: + +* schema derived implementation classes that +implement schema derived interfaces can be created using factory methods +generated by the schema compiler. +* schema derived value classes can be created +using a constructor or a factory method generated by the schema +compiler. +* existing types, authored by users, are +required to provide a no arg constructor. The no arg constructor is used +by an unmarshaller during unmarshalling to create an instance of the +type. + +==== Binding Declarations + +A particular binding of a given source schema +is defined by a set of _binding declarations_ . Binding declarations are +written in a _binding language_ , which is itself an application of XML. +A binding declaration can occur within the annotation `appinfo` of each +XML Schema component. Alternatively, binding declarations can occur in +an auxiliary file. Each binding declaration within the auxiliary file is +associated to a schema component in the source schema. It was necessary +to support binding declarations external to the source schema in order +to allow for customization of an XML Schemas that one prefers not to +modify. The schema compiler hence actually requires two inputs, a source +schema and a set of binding declarations. + +Binding declarations enable one to override +default binding rules, thereby allowing for user customization of the +schema-derived value class. Additionally, binding declarations allow for +further refinements to be introduced into the binding to Java +representation that could not be derived from the schema alone. + +The binding declarations need not define +every last detail of a binding. The schema compiler assumes _default +binding declarations_ for those components of the source schema that are +not mentioned explicitly by binding declarations. Default declarations +both reduce the verbosity of the customization and make it more robust +to the evolution of the source schema. The defaulting rules are +sufficiently powerful that in many cases a usable binding can be +produced with no binding declarations at all. By defining a standardized +format for the binding declarations, it is envisioned that tools will be +built to greatly aid the process of customizing the binding from schema +components to a Java representation. + +==== Mapping Annotations + +A mapping annotation defines the mapping of a +program element to one or more schema components. A mapping annotation +typically contains one or more annotation members to allow customized +binding. An annotation member can be required or optional. A mapping +annotation can be collocated with the program element in the source. The +schema generator hence actually requires both inputs: a set of classes +and a set of mapping annotations. + +Defaults make it easy to use the mapping +annotations. In the absence of a mapping annotation on a program +element, the schema generator assumes, when required by a mapping rule, +a _default mapping annotation_. This, together with an appropriate choice +of default values for optional annotation members makes it possible to +produce in many cases a usable mapping with minimal mapping annotations. +Thus mapping annotations provide a powerful yet easy to use +customization mechanism. + +=== Annotations + +Many of the architectural components are driven by program +annotations defined by this specification, _mapping annotations_. + +*_Java to Schema Mapping_* Mapping annotations +provide meta data that describe or customize the mapping of existing +classes to a derived schema. + +*_Portable Value Classes_* Mapping annotations +provide information for unmarshalling and marshalling of an XML instance +into a content tree representing the XML content without the need for a +schema at run time. Thus schema derived code annotated with mapping +annotations are portable i.e. they are capable of being marshalled and +unmarshalled by a universal marshaller and unmarshaller written by a +JAXB vendor implementation. + +*_Adding application specific behavior and data_* +Applications can choose to add either behavior or data to schema derived +code. Section <<Modifying Schema-Derived Code>> +specifies how the mapping annotation, `@jakarta.annotation.Generated`, +should be used by a developer to denote developer added/modified code +from schema-derived code. This information can be utilized by tools to +preserve application specific code across regenerations of schema +derived code. + +=== Binding Framework + +The binding framework has been revised +significantly since JAXB 1.0. Significant changes include: + +* support for unmarshalling of invalid XML +content. +* removal of on-demand validation. +* unmarshal/marshal time validation deferring +to JAXP validation. + +==== Unmarshalling + +===== Invalid XML Content + +*_Rationale:_* Invalid XML content can arise for +many reasons: + +* When the cost of validation needs to be avoided. +* When the schema for the XML has evolved. +* When the XML is from a non-schema-aware processor. +* When the schema is not authoritative. + +Support for invalid XML content required +changes to JAXB 1.0 schema to java binding rules as well as the +introduction of a flexible unmarshalling mode. These changes are +described in <<Unmarshalling Modes>>. + +==== Validation + +The constraints expressed in a schema fall +into three general categories: + +* A _type_ constraint imposes requirements +upon the values that may be provided by constraint facets in simple type +definitions. +* A _local structural_ constraint imposes +requirements upon every instance of a given element type, e.g., that +required attributes are given values and that a complex element’s +content matches its content specification. +* A _global structural_ constraint imposes +requirements upon an entire document, e.g., that `ID` values are unique +and that for every `IDREF` attribute value there exists an element with +the corresponding `ID` attribute value. + +A _document_ is valid if, and only if, all of +the constraints expressed in its schema are satisfied. The manner in +which constraints are enforced in a set of derived classes has a +significant impact upon the usability of those classes. All constraints +could, in principle, be checked only during unmarshalling. This approach +would, however, yield classes that violate the _fail-fast_ principle of +API design: errors should, if feasible, be reported as soon as they are +detected. In the context of schema-derived classes, this principle +ensures that violations of schema constraints are signalled when they +occur rather than later on when they may be more difficult to diagnose. + +With this principle in mind we see that schema +constraints can, in general, be enforced in three ways: + +* _Static_ enforcement leverages the type +system of the Java programming language to ensure that a schema +constraint is checked at application’s compilation time. Type +constraints are often good candidates for static enforcement. If an +attribute is constrained by a schema to have a boolean value, e.g., then +the access methods for that attribute’s property can simply accept and +return values of type `boolean`. +* _Simple dynamic_ enforcement performs a +trivial run-time check and throws an appropriate exception upon failure. +Type constraints that do not easily map directly to Java classes or +primitive types are best enforced in this way. If an attribute is +constrained to have an integer value between zero and 100, e.g., then +the corresponding property’s access methods can accept and return `int` +values and its mutation method can throw a run-time exception if its +argument is out of range. +* _Complex dynamic_ enforcement performs a +potentially costly run-time check, usually involving more than one +content object, and throwing an appropriate exception upon failure. +Local structural constraints are usually enforced in this way: the +structure of a complex element’s content, e.g., can in general only be +checked by examining the types of its children and ensuring that they +match the schema’s content model for that element. Global structural +constraints must be enforced in this way: the uniqueness of `ID` values, +e.g., can only be checked by examining the entire content tree. + +It is straightforward to implement both static +and simple dynamic checks so as to satisfy the fail-fast principle. +Constraints that require complex dynamic checks could, in theory, also +be implemented so as to fail as soon as possible. The resulting classes +would be rather clumsy to use, however, because it is often convenient +to violate structural constraints on a temporary basis while +constructing or manipulating a content tree. + +Consider, e.g., a complex type definition +whose content specification is very complex. Suppose that an instance of +the corresponding value class is to be modified, and that the only way +to achieve the desired result involves a sequence of changes during +which the content specification would be violated. If the content +instance were to check continuously that its content is valid, then the +only way to modify the content would be to copy it, modify the copy, and +then install the new copy in place of the old content. It would be much +more convenient to be able to modify the content in place. + +A similar analysis applies to most other sorts +of structural constraints, and especially to global structural +constraints. Schema-derived classes have the ability to enable or +disable a mode that verifies type constraints. JAXB mapped classes can +optionally be validated at unmarshal and marshal time. + +===== Validation Re architecture + +The detection of complex schema constraint +violations has been redesigned to have a Jakarta XML Binding implementation to +delegate to the validation API in JAXP. JAXP defines a standard +validation API (`javax.xml.validation` package) for validating XML +content against constraints within a schema. Furthermore, JAXP has +been incorporated into J2SE 5.0 platform. Any Jakarta XML Binding implementation +that takes advantage of the validation API will result in a smaller +footprint. + +===== Unmarshal validation + +When the unmarshalling process incorporates +validation and it successfully completes without any validation errors, +both the input document and the resulting content tree are guaranteed to +be valid. + +However, always requiring validation during +unmarshalling proves to be too rigid and restrictive a requirement. +Since existing XML parsers allow schema validation to be disabled, there +exist a significant number of XML processing uses that disable schema +validation to improve processing speed and/or to be able to process +documents containing invalid or incomplete content. To enable the JAXB +architecture to be used in these processing scenarios, the binding +framework makes validation optional. + +===== Marshal Validation + +Validation may also be optionally performed +at marshal time. This is new for Jakarta XML Binding. Validation of object graph +while marshalling is useful in web services where the marshalled output +must conform to schema constraints specified in a WSDL document. This +could provide a valuable debugging aid for dealing with any +interoperability problems + +===== Handling Validation Failures + +While it would be possible to notify a JAXB +application that a validation error has occurred by throwing a +`JAXBException` when the error is detected, this means of communicating +a validation error results in only one failure at a time being handled. +Potentially, the validation operation would have to be called as many +times as there are validation errors. Both in terms of validation +processing and for the application’s benefit, it is better to detect as +many errors and warnings as possible during a single validation pass. To +allow for multiple validation errors to be processed in one pass, each +validation error is mapped to a validation error event. A validation +error event relates the validation error or warning encountered to the +location of the text or object(s) involved with the error. The stream of +potential validation error events can be communicated to the application +either through a registered validation event handler at the time the +validation error is encountered, or via a collection of validation +failure events that the application can request after the operation has +completed. + +Unmarshalling and marshalling are the two +operations that can result in multiple validation failures. The same +mechanism is used to handle both failure scenarios. See +<<General Validation Processing>> for further details. + +=== An example + +Throughout this specification we will refer +and build upon the familiar schema from [XSD Part 0], which describes a +purchase order, as a running example to illustrate various binding +concepts as they are defined. Note that all schema name attributes with +values in *this font* are bound by JAXB technology to either a Java +interface or JavaBean-like property. Please note that the derived Java +code in the example only approximates the default binding of the +schema-to-Java representation. + +[source,xml,subs="specialcharacters,quotes"] +---- +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:element name=*"purchaseOrder"* type=*"PurchaseOrderType"*/> + <xsd:element name=*"comment"* type=*"xsd:string"*/> + <xsd:complexType name=*"PurchaseOrderType"*> + <xsd:sequence> + <xsd:element name=*"shipTo"* type="USAddress"/> + <xsd:element name=*"billTo"* type="USAddress"/> + <xsd:element ref=*"comment"* minOccurs="0"/> + <xsd:element name=*"items"* type="Items"/> + </xsd:sequence> + <xsd:attribute name=*"orderDate"* type="xsd:date"/> + </xsd:complexType> + + <xsd:complexType name=*"USAddress"*> + <xsd:sequence> + <xsd:element name=*"name"* type="xsd:string"/> + <xsd:element name=*"street"* type="xsd:string"/> + <xsd:element name=*"city"* type="xsd:string"/> + <xsd:element name=*"state"* type="xsd:string"/> + <xsd:element name=*"zip"* type="xsd:decimal"/> + </xsd:sequence> + <xsd:attribute name=*"country"* type="xsd:NMTOKEN" fixed="US"/> + </xsd:complexType> + + <xsd:complexType name=*"Items"* > + <xsd:sequence> + <xsd:element name=*"item"* minOccurs="1" maxOccurs="unbounded"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name=*"productName"* type="xsd:string"/> + <xsd:element name=*"quantity"* > + <xsd:simpleType> + <xsd:restriction base="xsd:positiveInteger"> + <xsd:maxExclusive value="100"/> + </xsd:restriction> + </xsd:simpleType> + </xsd:element> + <xsd:element name=*"USPrice"* type="xsd:decimal"/> + <xsd:element ref=*"comment"* minOccurs="0"/> + <xsd:element name=*"shipDate"* type="xsd:date" minOccurs="0"/> + </xsd:sequence> + <xsd:attribute name=*"partNum"* type="SKU" use="required"/> + </xsd:complexType> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <!-- Stock Keeping Unit, a code for identifying products --> + <xsd:simpleType name=*"SKU"* > + <xsd:restriction base="xsd:string"> + <xsd:pattern value="\d{3}-[A-Z]{2}"/> + </xsd:restriction + </xsd:simpleType> +</xsd:schema> +---- + +Binding of purchase order schema to a Java +representationfootnote:[In the interest of +terseness, Jakarta XML Binding program annotations have been ommitted.]: + +[source,java,subs="+macros"] +---- +import javax.xml.datatype.XMLGregorianCalendar; import java.util.List; +public class PurchaseOrderType { + USAddress getShipTo() {...} void setShipTo(USAddress) {...} + USAddress getBillTo() {...} void setBillTo(USAddress) {...} + /** Optional to set Comment property. */ + String getComment() {...} void setComment(String) {...} + Items getItems() {...} void setItems(Items) {...} + XMLGregorianCalendar getOrderDate() void setOrderDate(XMLGregorianCalendar) +}; +public class USAddress { + String getName() {...} void setName(String) {...} + String getStreet() {...} void setStreet(String) {...} + String getCity() {...} void setCity(String) {...} + String getState() {...} void setState(String) {...} + int getZip() {...} void setZip(int) {...} + static final String COUNTRY=”USA”;footnote:creq[Appropriate +customization required to bind a fixed attribute to a constant value.] +}; +public class Items { + public class ItemType { + String getProductName() {...} void setProductName(String) {...} + /** Type constraint on Quantity setter value 0..99.footnote:[Type constraint +checking only performed if customization enables it and implementation supports fail-fast checking] */ + int getQuantity() {...} void setQuantity(int) {...} + float getUSPrice() {...} void setUSPrice(float) {...} + /** Optional to set Comment property. */ + String getComment() {...} void setComment(String) {...} + XMLGregorianCalendar getShipDate(); void setShipDate(XMLGregorianCalendar); + /** Type constraint on PartNum setter value "\d{3}-[A-Z]{2}".footnote:creq[] */ + String getPartNum() {...} void setPartNum(String) {...} + }; + + /** Local structural constraint 1 or more instances of Items.ItemType */ + List<Items.ItemType> getItem() {...} +} +public class ObjectFactory { + // type factories + Object newInstance(Class javaInterface) {...} + PurchaseOrderType createPurchaseOrderType() {...} + USAddress create USAddress() {...} + Items createItems() {...} + Items.ItemType createItemsItemType() {...} + // element factories + JAXBElement<PurchaseOrderType> createPurchaseOrder(PurchaseOrderType) {...} + JAXBElement<String> createComment(String value) {...} +} +---- + +The purchase order schema does not describe +any global structural constraints. + +The coming chapters will identify how these +XML Schema concepts were bound to a Java representation. Just as in [XSD +Part 0], additions will be made to the schema example to illustrate the +binding concepts being discussed. +
diff --git a/spec/src/main/asciidoc/ch04-binding_framework.adoc b/spec/src/main/asciidoc/ch04-binding_framework.adoc new file mode 100644 index 0000000..26359f5 --- /dev/null +++ b/spec/src/main/asciidoc/ch04-binding_framework.adoc
@@ -0,0 +1,813 @@ +// +// Copyright (c) 2020, 2022 Contributors to the Eclipse Foundation +// + +== The Binding Framework + +The _binding framework_ defines APIs to +access unmarshalling, validation and marshalling operations for +manipulating XML data and JAXB mapped objects. The framework is +presented here in overview; its full specification is available in the +javadoc for the package `jakarta.xml.bind`. + +The binding framework resides in two main +packages. The `jakarta.xml.bind` package defines abstract classes and +interfaces that are used directly with content classes. The +`jakarta.xml.bind` package defines the +`Unmarshaller`, `Marshaller` and `Binder` classes, which are auxiliary +objects for providing their respective operations. + +The `JAXBContext` class is the entry point +for a Java application into the JAXB framework. A `JAXBContext` instance +manages the binding relationship between XML element names to Java value +class for a JAXB implementation to be used by the unmarshal, marshal and +binder operations. The `jakarta.xml.bind.helper` package provides partial +default implementations for some of the `jakarta.xml.bind` interfaces. +Implementations of JAXB technology can extend these classes and +implement the abstract methods. These APIs are not intended to be used +directly by applications using the JAXB architecture. A third package, +`jakarta.xml.bind.util`, contains utility classes that may be used +directly by client applications. + +The binding framework defines a hierarchy of +exception and validation event classes for use when +marshalling/unmarshalling errors occur, when constraints are violated, +and when other types of errors are detected. + + + +=== Annotation-driven Binding Framework + +The portability of JAXB annotated classes is +achieved via an annotation-driven architecture. The program annotations, +specified in Section 8, describe the mapping from the Java program +elements to XML Schema components. This information is used by the +binding framework to unmarshal and marshal to XML content into/from +JAXB-annotated classes. All JAXB schema binding compilers must be able +to generate portable schema-derived JAXB-annotated classes following the +constraints described in <<Binding XML Schema to Java Representations>>. +All binding runtime frameworks are required +to be able to marshal and unmarshal portable JAXB-annotated classes +generated by other Jakarta XML Binding schema binding compiler. + +It is not possible to require portability of +the interface/implementation binding from JAXB 1.0. For backwards +compatibility with existing implementations, that binding remains a +tight coupling between the schema-derived implementation classes and the +JAXB implementation’s runtime framework. Users are required to +regenerate the schema-derived implementation classes when changing JAXB +implementations. + +=== JAXBContext + +The `JAXBContext` class provides the client’s +entry point to the JAXB API. It provides an abstraction for managing the +XML/Java binding information necessary to implement the JAXB binding +framework operations: unmarshal and marshal. + +The following summarizes the `JAXBContext` class defined in package `jakarta.xml.bind`. + +[source,java] +---- +public abstract class JAXBContext { + static final String JAXB_CONTEXT_FACTORY; + static JAXBContext newInstance(String contextPath); + static JAXBContext newInstance(String contextPath, + ClassLoader contextPathCL); + static JAXBContext newInstance(Class... classesToBeBound); + abstract Unmarshaller createUnmarshaller(); + abstract Marshaller createMarshaller(); + abstract JAXBIntrospector createJAXBIntrospector(); + <T> Binder<T> createBinder(Class<T> domType); + Binder<org.w3c.dom.Node> createBinder(); + void generateSchema(SchemaOutputResolver); +} +---- + +To avoid the overhead involved in creating a +JAXBContext instance, a JAXB application is encouraged to reuse a +JAXBContext instance. An implementation of abstract class JAXBContext is +required to be thread-safe, thus, multiple threads in an application can +share the same JAXBContext instance. + +A client application configures a JAXBContext +using the `JAXBContext.newInstance(String contextPath)` factory method. + +[source,java,indent=8] +---- +JAXBContext jc = + JAXBContext.newInstance( "com.acme.foo:com.acme.bar" ); +---- + +The above example initializes a `JAXBContext` +with the schema-derived Java packages `com.acme.foo` and `com.acme.bar`. +A `jaxb.index` resource file, described in more detail in the javadoc, +list the non-schema-derived classes, namely the java to schema binding, +in a package to register with `JAXBContext`. Additionally, in each +specified directory, if an optional resource filefootnote:pkginfo[Section 7.4.1.1 +“Package Annotations” in [JLS\] recommends that file-system-based +implementations have the annotated package declaration in a file called +`package-info.java`.] +containing package level mapping annotations exist, it is incorporated +into the JAXBContext representation. + +An alternative mechanism that could be more +convenient when binding Java classes to Schema is to initialize +JAXBContext by passing JAXB-annotated class objects. + +[source,java,indent=8] +---- +JAXBContext jc = + JAXBContext.newInstance( POElement.class ); +---- + +The classes specified as parameters to +`newInstance` and all classes that are directly/indirectly referenced +statically from the specified classes are included into the returned +`JAXBContext` instance. For each directory of all the classes imported +into JAXBContext, if an optional resource filefootnote:pkginfo[] containing package level +mapping annotations exists, it is incorporated into the JAXBContext +representation. + +For example, given the following Java classes: + +[source,java,indent=4,subs="+macros"] +---- +@XmlRootElement class Foo { Bar b; }footnote:[Program annotations @XmlRootElement and @XmlType are specified in Section 8.0.] +@XmlType class Bar { FooBar fb; } +@XmlType class FooBar { int x; } +---- + +The invocation of +`JAXBContext.newInstance(Foo.class)` registers Foo and the statically +referenced classes, `Bar` and `FooBar`. + +Note that the jaxb.index resource file is not +necessary when an application uses +`JAXBContenxt.newInstances(Class...classesToBeBound)`. + +For either scenario, the values of these +parameters initialize the JAXBContext object so that it is capable of +managing the JAXB mapped classes. + +See the javadoc for `JAXBContext` for more details on using this class. + +[NOTE] +.Design Note +==== +JAXBContext class is designed to be immutable and thus thread-safe. +Given the amount of dynamic processing that potentially could take place +when creating a new instance of JAXBContxt, it is recommended +that a JAXBContext instance be shared across threads and reused +as much as possible to improve application performance. + +==== + +[NOTE] +.Note +==== +If JAXB-annotated classes or packages referenced in context path +are defined in a Java Platform Module System (JSR 376) module, +they must be open (as specified in javadoc of `java.lang.Module#isOpen()`) +to at least `jakarta.xml.bind` module. + +==== + + +=== General Validation Processing + +Three identifiable forms of validation exist +within the JAXB architecture include: + +* *Unmarshal-time validation* + +This form of validation enables a client +application to be notified of validation errors and warnings detected +while unmarshalling XML data into a Java content tree and is completely +orthogonal to the other types of validation. See +jakarta.xml.bind.Unmarshaller javadoc for a description on how to enable +this feature. + +* *On-demand validation* + +This mode of validation is not defined in Jakarta XML Binding Specification. + +* *Fail-fast validation* + +This form of validation enables a client +application to receive immediate feedback about a modification to the +Java content tree that violates a type constraint of a Java property. An +unchecked exception is thrown if the value provided to a set method is +invalid based on the constraint facets specified for the basetype of the +property. This style of validation is optional in this version of the +specification. Of the JAXB implementations that do support this type of +validation, it is customization-time decision to enable or disable +fail-fast validation when setting a property. + +Unmarshal-time uses an event-driven mechanism +to enable multiple validation errors and warnings to be processed during +a single operation invocation. If the validation or unmarshal operation +terminates with an exception upon encountering the first validation +warning or error, subsequent validation errors and warnings would not be +discovered until the first reported error is corrected. Thus, the +validation event notification mechanism provides the application a more +powerful means to evaluate validation warnings and errors as they occur +and gives the application the ability to determine when a validation +warning or error should abort the current operation (such as a value +outside of the legal value space). Thus, an application could allow +locally constrained validation problems to not terminate validation +processing. + +If the client application does not set an +event handler on a `Unmarshaller` or `Marshaller` instance prior to +invoking the `unmarshal` or `marshal` operations, then a default event +handler will receive notification of any errors or fatal errors +encountered and stop processing the XML data. In other words, the +default event handler will fail on the first error that is encountered. + +There are three ways to handle validation +events encountered during the unmarshal and marshal operations: + +* *Rely on the default validation event handler* + +The default handler will fail on the first error or fatal error +encountered. +* *Implement and register a custom validation event handler* + +Client applications that require sophisticated event processing can +implement the `ValidationEventHandler` interface and register it with +the Validator or Unmarshaller instance respectively. +* *Request an error/warning event list after the operation completes* + +By registering the `ValidationEventCollector` helper, a specialized +event handler, with the `setEventHandler` method, the `ValidationEvent` +objects created during the unmarshal and marshal operations are +collected. The client application can then request the list after the +operation completes. + +Validation events are handled differently +depending on how the client application is configured to process them as +described previously. However, there are certain cases where a JAXB +implementation may need to indicate that it is no longer able to +reliably detect and report errors. In these cases, the JAXB +implementation will set the severity of the `ValidationEvent` to +`FATAL_ERROR` to indicate that the `unmarshal` or `validate` operation +should be terminated. The default event handler and +`ValidationEventCollector` helper class must terminate processing after +being notified of a fatal error. Client applications that supply their +own `ValidationEventHandler` should also terminate processing after +being notified of a fatal error. If not, unexpected behavior may occur. + +=== Unmarshalling + +The `Unmarshaller` class governs the process +of deserializing XML data into a Java content tree, capable of +validating the XML data as it is unmarshalled. It provides the basic +unmarshalling methods: + +[source,java] +---- +public interface Unmarshaller { + ValidationEventHandler getEventHandler() + void setEventHandler(ValidationEventHandler) + + java.lang.Object getProperty(java.lang.String name) + void setProperty(java.lang.String name, java.lang.Object value) + + void setSchema(javax.xml.validation.Schema schema) + javax.xml.validation.Schema getSchema() + + UnmarshallerHandler getUnmarshallerHandler() + + void setListener(Unmarshaller.Listener) + Unmarshaller.Listener getListener() + + java.lang.Object unmarshal(java.io.File) + java.lang.Object unmarshal(java.net.URL) + java.lang.Object unmarshal(java.io.InputStream) + java.lang.Object unmarshal(org.xml.sax.InputSource) + java.lang.Object unmarshal(org.w3c.dom.Node) + + java.lang.Object unmarshal(javax.xml.transform.Source) + java.lang.Object unmarshal(javax.xml.stream.XMLStreamReader) + java.lang.Object unmarshal(javax.xml.stream.XMLEventReader) + + <T> JAXBElement<T> unmarshal(org.w3c.dom.Node, + Class<T> declaredType) + <T> JAXBElement<T> unmarshal(javax.xml.transform.Source, + Class<T> declaredType) + <T> JAXBElement<T> unmarshal(javax.xml.stream.XMLStreamReader, + Class<T> declaredType) + <T> JAXBElement<T> unmarshal(javax.xml.stream.XMLEventReader, + Class<T> declaredType) +} +---- + +The `JAXBContext` class contains a factory to +create an `Unmarshaller` instance. The `JAXBContext` instance manages +the XML/Java binding data that is used by unmarshalling. If the +`JAXBContext` object that was used to create an `Unmarshaller` does not +know how to unmarshal the XML content from a specified input source, +then the `unmarshal` operation will abort immediately by throwing an +`UnmarshalException`. There are six convenience methods for +unmarshalling from various input sources. + +An application can enable or disable +unmarshal-time validation by enabling JAXP validation via the +`setSchema(javax.xml.validation.Schema)` method. The application has the +option to customize validation error handling by overriding the default +event handler using the `setEventHandler(ValidationEventHandler)`. The +default event handler aborts the unmarshalling process when the first +validation error event is encountered. Validation processing options are +presented in more detail in <<General Validation Processing>>. + +An application has the ability to specify a +SAX 2.0 parser to be used by the `unmarshal` operation using the +`unmarshal(javax.xml.transform.Source)` method. Even though the JAXB +provider’s default parser is not required to be SAX2.0 compliant, all +providers are required to allow an application to specify their own +SAX2.0 parser. Some providers may require the application to specify the +SAX2.0 parser at binding compile time. See the method javadoc +`unmarshal(Source)` for more detail on how an application can specify +its own SAX 2.0 parser. + +The `getProperty`/`setProperty` methods +introduce a mechanism to associate implementation specific +property/value pairs to the unmarshalling process. At this time there +are no standard JAXB properties specified for the unmarshalling process. + +==== Unmarshal event callbacks + +The `Unmarshaller` provides two styles of +callback mechanisms that allow application specific processing during +key points in the unmarshalling process. In 'class-defined' event +callbacks, application specific code placed in JAXB mapped classes is +triggered during unmarshalling. External listeners allow for centralized +processing of unmarshal events in one callback method rather than by +type event callbacks. The 'class defined' and external listener event +callback methods are independent of each other, both can be called for +one event. The invocation ordering when both listener callback methods +exist is defined in `jakarta.xml.bind.Unmarshaller.Listener` javadoc. + +Event callback methods should be written with +following considerations. Each event callback invocation contributes to +the overall unmarshal time. An event callback method throwing an +exception terminates the current unmarshal process. + +===== Class-defined + +A JAXB mapped class can optionally implement +the following unmarshal event callback methods. + +* `private void beforeUnmarshal(Unmarshaller, Object parent)` + + + +This method is called immediately after the +object is created and before the unmarshalling of this object begins.The +callback provides an opportunity to initialize JavaBean properties prior +to unmarshalling. + +** *Parameters:* + +`unmarshaller` - unmarshal context. + +`parent` - points to the parent object to which +this object will be set. Parent is null when this object is the root +object. + +* `private void afterUnmarshal(Unmarshaller, Object parent)` + + + +This method is called after all the +properties (except IDREF) are unmarshalled for this object, but before +this object is set to the parent object. + +** *Parameters:* + +`unmarshaller` - unmarshal context. + +`parent` - points to the parent object to which +this object will be set. Parent is null when this object is the root +object. + +These callback methods allow an object to +perform additional processing at certain key point in the unmarshalling +operation. + +===== External Listener + +The external listener callback mechanism +enables the registration of a `Unmarshaller.Listener` instance with an +`Unmarshaller.setListener(Unmarshaller.Listener)`. The external +listener receives all callback events, allowing for more centralized +processing than per class defined callback methods. The external +listener receives events when unmarshalling to a JAXB element or to JAXB +mapped class. + +==== Unmarshalling Modes + +There exist numerous use cases requiring the +ability to unmarshal invalid XML content. A flexible unmarshalling mode +is described in this version of the specification to enable predictable +unmarshalling of invalid content. The previous unmarshalling mode +implied by JAXB 1.0 specification is named structural unmarshalling. +This unmarshalling mode was well defined for the unmarshalling of valid +XML content and allowed an implementation to handle invalid XML content +in anyway that it choose to. + +Both of these modes have benefits and +drawbacks based on an application’s xml processing needs. + +==== Structural Unmarshalling + +Some of the XML Schema to Java bindings in +JAXB 1.0 implied that an unmarshaller had to maintain a state machine, +implying that the order of elements had to match up exactly as described +by the schema or unmarshaller would work unpredictably. When this +unmarshalling process detects a structural inconsistency that it is +unable to recover from, it should abort the unmarshal process by +throwing `UnmarshalException`. + +For example, it was valid for a Jakarta XML Binding +implementation to rigidly give up unmarshalling an invalid XML document +once it came across an unexpected element/attribute or missed a required +element or attribute. This mode appeals to users who prefer to be +notified that an xml document is deviating from the schema. + +XML Schema to Java binding for interfaces and +implementation classes, <<Java Content Interface>>, can implement either structural unmarshalling or flexible +unmarshalling. + +==== Flexible Unmarshalling + +To address the rigidness of structural +unmarshalling, flexible unmarshalling mode is specified to enable +greater predictability in unmarshalling invalid XML content. It +unmarshals xml content by element name, rather than strictly on the +position of the element within a content model. This allows this mode to +handle the following cases: + +* elements being out of order in a content +model +* recovering from required +elements/attributes missing from an xml document +* ignoring unexpected elements/attributes in +an xml document + +In order to enable this mode, the following +JAXB 1.0 customized bindings that required state-driven unmarshalling +have been removed from this specification. + +* Binding a model group or model group +definition to a Java class. + +Since there is no XML infoset information denoting these schema +components, a model group can only be inferred by applying positional +schema constraints to a valid XML document, tracking position within a +valid content model. +* Multiple occurrences of an element name in +a content model can no longer be mapped to different JAXB properties. +Instead the entire content model is bound to a general content model. + +The removal of these bindings greatly assists +the error recovery for structural unmarshalling mode. + +Flexible unmarshalling appeals to those who +need to be able to perform best match unmarshalling of invalid xml +documents. + +The flexible unmarshalling process is +annotation driven. This process is specified in +<<Runtime Processing>>. Flexible +unmarshalling is required for Jakarta XML Binding annotated classes. + +=== Marshalling + +The `Marshaller` class is responsible for +governing the process of serializing a Java content tree into XML data. +It provides the basic marshalling methods: + +[source,java] +---- +interface Marshaller { + string JAXB_ENCODING; + string JAXB_FORMATTED_OUTPUT; + string JAXB_SCHEMA_LOCATION; + string JAXB_NO_NAMESPACE_SCHEMA_LOCATION; + string JAXB_FRAGMENT; + + <PROTENTIALLY MORE PROPERTIES...> + + java.lang.Object getProperty(java.lang.String name) + void setProperty(java.lang.String name, java.lang.Object value) + + void setEventHandler(ValidationEventHandler handler) + ValidationEventHandler getEventHandler() + + void setSchema(javax.xml.validation.Schema schema) + javax.xml.validation.Schema getSchema() + + void setListener(Unmarshaller.Listener) + Unmarshaller.Listener getListener() + + void marshal(java.lang.Object e, java.io.Writer writer) + void marshal(java.lang.Object e, java.io.OutputStream os) + void marshal(java.lang.Object e, org.xml.sax.ContentHandler) + void marshal(java.lang.Object e, javax.xml.transform.Result) + void marshal(java.lang.Object e, org.w3c.dom.Node) + void marshal(java.lang.Object e, + javax.xml.stream.XMLStreamWriter writer) + + org.w3c.dom.Node getNode(java.lang.Object contentTree) +} +---- + +The `JAXBContext` class contains a factory to +create a `Marshaller` instance. Convenience method overloading of the +`marshal()` method allow for marshalling a content tree to common Java +output targets and to common XML output targets of a stream of SAX2 +events or a DOM parse tree. + +Although each of the marshal methods accepts +a `java.lang.Object` as its first parameter, JAXB implementations are +not required to be able to marshal any arbitrary `java.lang.Object`. If +the first parameter is not a JAXB element, as determined by +`JAXBIntrospector.isElement()` method, the marshal operation must throw +a `MarshalException`. There exist two mechanisms to enable marshalling +an instance that is not a JAXB element. One method is to wrap the +instance as the value of a `jakarta.xml.bind.JAXBElement` instance, and +pass the wrapper element as the first parameter to a `marshal` method. +For java to schema binding, it is also possible to simply annotate the +instance's class with the appropriate program annotation, +`@XmlElementRoot`, specified in Section 8. + +The marshalling process can optionally be +configured to validate the content tree being marshalled. An application +can enable or disable marshal-time validation by enabling JAXP +validation via the `setSchema(javax.xml.validation.Schema)` method. The +application has the option to customize validation error handling by +overriding the default event handler using the +`setEventHandler(ValidationEventHandler)`. The default event handler +aborts the marshalling process when the first validation error event is +encountered. Validation processing options are presented in more detail +in <<General Validation Processing>>. + +There is no requirement that the Java content +tree be valid with respect to its original schema in order to marshal it +back into XML data. If the marshalling process detects a structural +inconsistency during its process that it is unable to recover from, it +should abort the marshal process by throwing `MarshalException`. The +marshalling process of a JAXB-annotated class is annotation driven. This +process is specified in <<Runtime Processing>>. + +==== Marshal event callbacks + +The Marshaller provides two styles of +callback mechanisms that allow application specific processing during +key points in the marshalling process. In class-defined event callbacks, +application specific code placed in JAXB mapped classes is triggered +during marshalling. External listeners allow for centralized processing +of marshal events in one callback method rather than by type event +callbacks. The invocation ordering when both listener callback methods +exist is defined in `jakarta.xml.bind.Marshaller.Listener` javadoc. + +Event callback methods should be written with +following considerations. Each event callback invocation contributes to +the overall marshal time. An event callback method throwing an exception +terminates the current marshal process. + +===== Class-defined + +A JAXB mapped class can optionally implement +the following marshal event callback methods. + +* `private void beforeMarshal(Marshaller)` + + + +This method is called before the marshalling +of this object starts. + +** *Parameters:* + +`marshaller` - marshal context. + +* `private void afterMarshal(Marshaller)` + + + +This method is called after the marshalling +of this object (and all its descendants) has finished. + +** *Parameters:* + +`marshaller` - marshal context. + +These callback methods allow the +customization of an JAXB mapped class to perform additional processing +at certain key point in the marshalling operation. The 'class defined' +and external listener event callback methods are independent of each +other, both can be called for one event. + +An event callback method throwing an +exception terminates the current marshal process. + +===== External Listener + +The external listener callback mechanism +enables the registration of a `Marshaller.Listener` instance with a +`Marshaller.setListener(Marshaller.Listener)`. The external listener +receives all callback events, allowing for more centralized processing +than per class-defined callback methods. + +==== Marshalling Properties + +The following subsection highlights +properties that can be used to control the marshalling process. These +properties must be set prior to the start of a marshalling operation: +the behavior is undefined if these attributes are altered in the middle +of a marshalling operation. The following standard properties have been +identified: + +* `jaxb.encoding` + +output character +encoding. If the property is not specified, it defaults to "UTF-8". +* `jaxb.formatted.output` + +`true` - human readable indented xml data + +`false` - unformatted xml data + +If the property is not specified, it defaults to `false`. +* `jaxb.schemaLocation` + +This property allows the client application to specify an +`xsi:schemaLocation` attribute in the generated XML data. +* `jaxb.noNamespaceSchemaLocation` + +This property allows the client application to specify an +`xsi:noNamespaceSchemaLocation` attribute in the generated XML data. +* `jaxb.fragment` + +Its value must be a java.lang.Boolean. This property determines +whether or not document level events will be generated by the +Marshaller. If this property is not defined, it defaults to `false`. + +=== JAXBIntrospector + +This class provides access to key XML mapping +information of a JAXB mapped instance. + +[source,java] +---- +public abstract class JAXBIntrospector { + public boolean isElement(Object jaxbObj); + public QName getElementName(Object jaxbElement); + public static Object getValue(Object jaxbElement); +} +---- + +The Jakarta XML Binding architecture has two uniquely +different ways to represent an XML element.The XML Schema to Java +binding for an XML element declaration is described in +<<Java Element Representation>>. The Java +to XML Schema binding for an XML element declaration is described in +<<xmlrootelement>>. + +Use JAXBInstrospector.isElement(Object) +method to determine if an instance of a JAXB mapped class represents an +XML element. One can get the xml element tag name associated with a JAXB +element using `JAXBIntrospector.getElementName` method. One can an xml +element’s value using getValue method. The getValue method normalizes +access of JAXB element, hiding whether the JAXB element is an instance +of jakarta.xml.bind.JAXBElement or if it is an JAXB element via an +@XmlRootElement class annotation. + +=== Validation Handling + +Methods defined in the binding framework can +cause validation events to be delivered to the client application’s +`ValidationEventHandler.Setter` methods generated in schema-derived +classes are capable of throwing `TypeConstraintExceptions`, all of +which are defined in the binding framework. + +The following list describes the primary +event and constraint-exception classes: + +* An instance of a `TypeConstraintException` +subclass is thrown when a violation of a dynamically-checked type +constraint is detected. Such exceptions will be thrown by property-set +methods, for which it would be inconvenient to have to handle checked +exceptions; type-constraint exceptions are therefore unchecked, _i.e_, +this class extends `java.lang.RuntimeException`. The constraint check +is always performed prior to the property-set method updating the value +of the property, thus if the exception is thrown, the property is +guaranteed to retain the value it had prior to the invocation of the +property-set method with an invalid value. This functionality is +optional to implement in this version of the specification. +Additionally, a customization mechanism is provided to control enabling +and disabling this feature. +* An instance of a `ValidationEvent` is +delivered whenever a violation is detected during optionally enabled +unmarshal/marshal validation. Additionally, `ValidationEvents` can be +discovered during marshalling such as ID/IDREF violations and print +conversion failures. These violations may indicate local and global +structural constraint violations, type conversion violations, type +constraint violations, etc. +* Since the unmarshal operation involves +reading an input document, lexical well-formedness errors may be +detected or an I/O error may occur. In these cases, an +`UnmarshalException` will be thrown to indicate that the JAXB provider +is unable to continue the unmarshal operation. +* During the marshal operation, the JAXB +provider may encounter errors in the Java content tree that prevent it +from being able to complete. In these cases, a `MarshalException` will +be thrown to indicate that the marshal operation can not be completed. + +=== DOM and Java representation Binding + +The Binder class is responsible for +maintaining the relationship between a infoset preserving view of an XML +document with a possibly partial binding of the XML document to a JAXB +representation. Modifications can be made to either the infoset +preserving view or the JAXB representation of the document while the +other view remains unmodified. The binder is able to synchronize the +changes made in the modified view back into the read-only view. When +synchronizing changes to JAXB view back to related xml infoset +preserving view, every effort is made to preserve XML concepts that are +not bound to JAXB objects, such as XML infoset comments, processing +instructions, namespace prefix mappings, etc. + +==== Use Cases + +* Read-only partial binding. + + + +Application only needs to manipulate a small part of a rather large XML +document. It suffices to only map the small of the large document to the +JAXB Java representation. + +* Updateable partial binding + + + +The application receives an XML document that follows a later version of +the schema than the application is aware of. The parts of the schema +that the application needs to read and/or modify have not changed. Thus, +the document can be read into an infoset preserving representation, such +as DOM, only bind the part of the document that it does still have the +correct schema for into the JAXB Java representation of the fragment of +the document using Binder.unmarshal from the DOM to the JAXB view. +Modify the partial Java representation of the document and then +synchronize the modified parts of the Java representation back to the +DOM view using `Binder.updateXML` method. +* XPATH navigation + + + +Given that binder maintains a relationship between XML infoset view of +document and JAXB representation, one can use JAXP XPATH on the XML +infoset view and use the binder’s associative mapping to get from the +infoset node to JAXB representation. + +==== jakarta.xml.bind.Binder + +The class `jakarta.xml.bind.Binder` associates +an infoset preserving representation of the entire XML document with a +potentially partial binding to a Java representation. The binder +provides operations to synchronize between the two views that it is +binding. + +[source,java] +---- +public abstract class Binder<XmlNode> { + // Create two views of XML content, infoset view and JAXB view. + public abstract Object unmarshal(XmlNode xmlNode) + <T> JAXBElement<T> unmarshal(XmlNode xmlNode, + Class<T> declaredType) + public abstract void marshal(Object jaxbObject, XmlNode xmlNode) + + // Navigation between xml infoset view and JAXB view. + public abstract XmlNode getXMLNode(Object jaxbObject); + public abstract Object getJAXBNode(XmlNode xmlNode); + + // Synchronization methods + public abstract XmlNode updateXML(Object jaxbObject) + public abstract XmlNode updateXML(Object jaxbObject, XmlNode xmlNode) + throws JAXBException; + public abstract Object updateJAXB(XmlNode xmlNode) + throws JAXBException; + + // Enable optional validation + public abstract void setSchema(Schema schema); + public abstract Schema getSchema(); + public abstract void setEventHandler(ValidationEventHandler handler) + throws JAXBException; + public abstract ValidationEventHandler getEventHandler() + throws JAXBException; + + // Marshal/Unmarshal properties + public abstract void setProperty(String name, Object value) + throws PropertyException; + public abstract Object getProperty(String name) + throws PropertyException; +} +---- + +=== Implementation discovery + +To create an instance of JAXBContext, +one of `JAXBContext.newInstance` methods is invoked. JAXB implementation +discovery happens each time `JAXBContext.newInstance` is invoked. + +Implementation discovery consists of following steps in the order +specified (first successful resolution applies): + +. If the system property `jakarta.xml.bind.JAXBContextFactory` exists, +then its value is assumed to be the provider factory class. This phase +of the look up enables per-JVM override of the Jakarta XML Binding implementation. + +. If the property `jakarta.xml.bind.JAXBContextFactory` exists in the `Map<String, ?>` +passed to `JAXBContext.newInstance(Class[], Map)` or to `JAXBContext.newInstance(String, ClassLoader, Map)`, +then its value is assumed to be the fully qualified provider factory class name. +This phase of the look up enables context sensitive selection of the Jakarta XML Binding implementation. + +. Provider of `jakarta.xml.bind.JAXBContextFactory` is loaded +using the service-provider loading facilities, as defined by +Java SE Platform, to attempt to locate and load +an implementation of the service. + + . Finally, if all of the steps above fail, + then the rest of the look up is unspecified. + +Once the provider factory class is discovered, context creation +is delegated to one of its createContext(...) methods.
diff --git a/spec/src/main/asciidoc/ch05-java_representation.adoc b/spec/src/main/asciidoc/ch05-java_representation.adoc new file mode 100644 index 0000000..72a42b7 --- /dev/null +++ b/spec/src/main/asciidoc/ch05-java_representation.adoc
@@ -0,0 +1,912 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +== Java Representation of XML Content + +This section defines the basic binding +representation of package, value class, element classes, properties and +enum type within the Java programming language. Each section briefly +states the XML Schema components that could be bound to the Java +representation. A more rigorous and thorough description of possible +bindings and default bindings occurs in +<<Binding XML Schema to Java Representations>> and in +<<Customizing XML Schema to Java Representation Binding>>. + +=== Mapping between XML Names and Java Identifiers + +XML schema languages use _XML names_, _i.e._, +strings that match the Name production defined in XML 1.0 (Second +Edition) to label schema components. This set of strings is much larger +than the set of valid Java class, method, and constant identifiers. +<<Binding XML Names to Java Identifiers>>, +specifies an algorithm for mapping XML names to Java +identifiers in a way that adheres to standard Java API design +guidelines, generates identifiers that retain obvious connections to the +corresponding schema, and results in as few collisions as possible. It +is necessary to rigorously define a standard way to perform this mapping +so all implementations of this specification perform the mapping in the +same compatible manner. + +=== Java Package + +Just as the target XML namespace provides a +naming context for the named type definitions, named model groups, +global element declarations and global attribute declarations for a +schema vocabulary, the Java package provides a naming context for Java +interfaces and classes. Therefore, it is natural to map the target +namespace of a schema to be the package that contains the Java value +class representing the structural content model of the document. + +A package consists of: + +* A _name_ , which is either derived directly +from the XML namespace URI as specified in +<<Generating a Java package name>> or +specified by a binding customization of the XML namespace URI as +described in <<Package>>. +* A set of Java value classes representing the +content models declared within the schema. +* A set of Java element classes representing +element declarations occurring within the schema. +<<Java Element Representation>> describes +this binding in more detail. +* A public class `ObjectFactory` contains: +** An instance factory method signature for +each Java content within the package. + + + +Given Java value class named Foo, here is the derived factory method: + + public Foo createFoo(); + +** An element instance factory method +signature for each bound element declaration. + + public JAXBElement<T> createFoo(T elementValue); + +** Dynamic instance factory allocator method signature: + + public Object newInstance(Class javaContentInterface); + +** Property setter/getter + +Provide the ability to associate implementation specific property/value +pairs with the instance creation process. + + java.lang.Object getProperty(String name); + void setProperty(String name, Object value); + +* A set of enum types. +* Package javadoc. + +*_Example:_* + +Purchase Order Schema fragment with `targetNamespace`: + +[source,xml] +---- +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:po="http://www.example.com/PO1" + targetNamespace="http://www.example.com/PO1"> + <xs:element name="purchaseOrder" type="po:PurchaseOrderType"/> + <xs:element name="comment" type="xs:string"/> + <xs:complexType name="PurchaseOrderType"/> + ... +</xs:schema> +---- + +Default derived Java code: + +[source,java] +---- +package com.example.PO1; +import jakarta.xml.bind.JAXBElement; +public class PurchaseOrderType {...}; +public Comment { String getValue() {...} void setValue(String) {...} } +... +public class ObjectFactory { + PurchaseOrderType createPurchaseOrderType(); + JAXBElement<PurchaseOrderType> createPurchaseOrder(PurchaseOrderType elementValue); + Comment createComment(String value); + ... +} +---- + +=== Enum Type + +A simple type definition whose value space is +constrained by enumeration facets can be bound to a Java enum type. Enum +type was introduced in J2SE 5.0 and is described in Section 8.9 of +[JLS]. Enum type is a significant enhancement over the typesafe enum +design pattern that it was designed to replace. If an application wishes +to refer to the values of a class by descriptive constants and +manipulate those constants in a type safe manner, it should consider +binding the XML component containing enumeration facets to an enum type. + +An enum type consists of: + +* A _name_ , which is either computed +directly from an XML name or specified by a binding customization for +the schema component. +* A _package name_, which is either computed +from the target namespace of the schema component or specified within a +binding declaration as a customization of the target namespace or a +specified package name for components that are scoped to no target +namespace. +* Outer Class Names is “_._” separated list of outer class names. + + + +By default, if the XML component containing a +typesafe enum class to be generated is scoped within a complex type as +opposed to a global scope, the typesafe enum class should occur as a +nested class within the Java value class representing the complex type +scope. + +Absolute class name is PackageName.[OuterClassNames.]Name. + +Note: Outer Class Name is null if class is a top-level class. + + + +The schema customization <jaxb:globalBindings localScoping=”toplevel”/>, +specified in Section <<Usage>>, disables +the generation of schema-derived nested classes and can be used to +override the default binding of a nested schema component binding to +nested Java class. + +* A set of _enum constants_. +* Class javadoc is a combination of a documentation annotation +from the schema component and/or javadoc specified by customization. + +An _enum constant_ consists of: + +* A _name_, which is either computed from the +enumeration facet value or specified by customization. +* A _value_ for the constant. Optimally, the +_name_ is the same as the _value_. This optimization is not possible +when the enumeration facet value is not a valid Java identifier. +* A datatype for the constant’s value. +* _Javadoc for the constant field_ is a +combination of a documentation annotation for an enumeration value facet +and/or javadoc specified by customization. + +=== Content Representation + +A complex type definition is bound to either +a Java value class or a content interface, depending on the value of the +global binding customization *[jaxb:globalBinding]* +`@generateValueClass`, specified in <<Usage>>. +Value classes are generated by default. The attributes and +children element content of a complex type definition are represented as +properties of the Java content representation. Property representations +are introduced in <<Properties>>. + +==== Value Class + +A value class consists of: + +* A _name_ , which is either computed +directly from an XML name or specified by a binding customization for +the schema component. +* A package name, which is either computed +from the target namespace of the schema component or specified by a +binding customization of the target namespace or a specified package +name for components that are scoped to no target namespace. +* The _outer class name_ context, a dot-separated list of Java class names. + + + +By default, if the XML schema component for +which a Java value class is to be generated is scoped within a complex +type as opposed to globally, the complex class should occur as a nested +class within the Java value class representing the complex type scope. +The schema customization <jaxb:globalBindings localScoping=”toplevel”/>, +specified in Section <<Usage>>, disables +the generation of schema-derived nested classes and all classes are +generated as toplevel classes. + + + +The absolute class name is PackageName.[OuterClassNames.]Name. + +Note: The OuterClassNames is null if the class is a top-level class. + +* A base class that this class extends. See +<<Complex Type Definition>> for further +details. +* A set of Java properties providing access +and modification to the complex type definition’s attributes and content +model represented by the value class. +* Class-level javadoc is a combination of a +documentation annotation from the schema component and/or javadoc +specified within customization. +* Creation + ** A value class supports creation via a +public constructor, either an explicit one or the default no-arg +constructor. + ** A factory method in the package’s +`ObjectFactory` class (introduced in <<Java Package>>). +The factory method returns the type of the Java value +class. The name of the factory method is generated by concatenating the +following components: ++ +-- + *** The string constant `create`. + *** If the Java value class is nested within another value class, +then the concatenation of all outer Java class names. + *** The _name_ of the Java value class. +-- ++ +For example, a Java value class named `Foo` +that is nested within Java value class `Bar` would have the following +factory method signature generated in the containing Java package’s +`ObjectFactory` class: + + Bar.Foo createBarFoo() {...} + +==== Java Content Interface + +This binding is similar to the value class binding +with the following differences. + +* A content interface is a public interface +while a value class is a public class. +* A content interface can only be created +with an ObjectFactory method whereas a value class can be created using +a public constructor. The factory method signature is the same for both +value class and content interface binding to ease switching between the +two binding styles. +* A content interface contains the method +signatures for the set of properties it contains, while a value class +contains method implementations. + +=== Properties + +The schema compiler binds local schema +components to _properties_ within a Java value class. + +A property is defined by: + +* A _name_, which is either computed from the XML name +or specified by a binding customization for the schema component. +* A _base type_, which may be a Java +primitive type (_e.g._, `int`) or a reference type. +* An optional _predicate_ , which is a +mechanism that tests values of the base type for validity and throws a +`TypeConstraintException` if a type constraint expressed in the source +schema is violated.footnote:constraint[Note that it is optional for a JAXB +implementation to support type constraint checks +when setting a property in this version of the specification.] +* An optional _collection type_ , which is +used for properties whose values may be composed of more than one value. +* A _default value_ . Schema component has a +schema specified default value which is used when property’s value is +not set and not nil. +* Is _nillable_ . A property is nillable when +it represents a nillable element declaration. + +A property is _realized_ by a set of _access methods_. +Several property models are identified in the following +subsections; each adds additional functionally to the basic set of +access methods. + +A property’s access methods are named in the +standard JavaBeans style: the name-mapping algorithm is applied to the +property name and then each method name is constructed by prefixing the +appropriate verb (`get`, `set`, etc.). + +[[a552]]A property is +said to have a _set value_ if that value was assigned to it during +unmarshallingfootnote:[An unmarshalling +implementation should distinguish between a value from an XML instance +document and a schema specified defaulted value when possible. A +property should only be considered to have a _set value_ when there exists +a corresponding value in the XML content being unmarshalled. +Unfortunately, unmarshalling implementation paths do exist that can not +identify schema specified default values, this situation is considered a +one-time transformation for the property and the defaulted value will be +treated as a _set value_.] or by invoking its mutation method. +The _value_ of a property is its _set value_, if defined; otherwise, it is +the property’s schema specified _default value_, if any; otherwise, it is +the default initial value for the property’s base type as it would be +assigned for an uninitialized field within a Java +classfootnote:[Namely, a `boolean` field type defaults to `false`, +`integer` field type defaults to `0`, object reference field type +defaults to `null`, floating point field +type defaults to `+0.0f`.]. <<a623>> +illustrates the states of a JAXB property and the invocations that +result in state changes. + +==== Simple Property + +A non-collection property `prop` with a base +type _Type_ is realized by the two methods + +[source,java,indent=8] +---- +public Type getId(); +public void setId(Type value); +---- + +where _Id_ is a metavariable that represents +the Java method identifier computed by applying the name mapping +algorithm described in <<The Name to Identifier Mapping Algorithm>> +to prop. There is one exception to this +general rule in order to support the boolean property described in +[BEANS]. When _Type_ is boolean, the `get__Id__` method specified above is +replaced by the method signature, _boolean_ `is__Id__()`. + +* The `get` or `is` method returns the +property’s value as specified in the previous subsection. If _null_ is +returned, the property is considered to be absent from the XML content +that it represents. +* The `set` method defines the property’s _set value_ +to be the argument `value`. If the argument value is `null`, the +property’s _set value_ is discarded. Prior to setting the property’s value +when TypeConstraint validation is enabledfootnote:[Note that it is +optional for a JAXB implementation to support type constraint checks +when setting a property in this version of the specification.], +a non-`null` value is validated by applying the property’s predicate. If +`TypeConstraintException` is thrown, the property retains the value it +had prior to the `set` method invocation. + + +When the base type for a property is a +primitive non-reference type and the property’s value is optional, the +corresponding Java wrapper class can be used as the base type to enable +discarding the property’s set value by invoking the set method with a +null parameter. <<isset-property-modifier>> describes an alternative to using a wrapper class for this +purpose. The *[jaxb:globalBinding]* customization `@optionalProperty` +controls the binding of an optional primitive property as described in +<<Usage>>. + +*_Example:_* + +In the purchase order schema, the _partNum_ +attribute of the _item_ element definition is declared: + +[source,xml,indent=4] +---- +<xs:attribute name="partNum" type="SKU" use="required"/> +---- + +This element declaration is bound to a simple +property with the base type `java.lang.String`: + +[source,java,indent=4] +---- +public String getPartNum(); +public void setPartNum(String x); +---- + +The `setPartNum` method could apply a +predicate to its argument to ensure that the new value is legal, _i.e._, +that it is a string value that complies with the constraints for the +simple type definition, SKU, and that derives by restriction from +`xs:string` and restricts the string value to match the regular +expression pattern `"\d{3}-[A-Z]{2}"`. + +It is legal to pass `null` to the +`setPartNum` method even though the `partNum` attribute declaration’s +attribute `use` is specified as required. The determination if `partNum` +content actually has a value is a local structural constraint rather +than a type constraint, so it is checked during validation rather than +during mutation. + +==== Collection Property + +A collection property may take the form of an +_indexed property_ or a _list property_. The base type of an indexed +property may be either a primitive type or a reference type, while that +of a list property must be a reference type. + +A collection consists of a group of +collection items. If one of the collection items can represent a +nillable element declaration, setting a collection item to `null` is +semantically equivalent to inserting a nil element, `xsi:nil="true"` , +into the collection property. If none of the collection items can ever +represent a nillable element declaration, setting a collection item to +`null` is the semantic equivalent of removing an optional element from +the collection property. + +===== Indexed Property + +This property follows the indexed property +design pattern for a multi-valued property from the JavaBean +specification. An indexed property `prop` with base type _Type_ is +realized by the five methods + +[source,java,indent=8] +---- +public Type[] getId(); +public void setId(Type[] value); +public void setId(int index, Type value); +public Type getId(int index); +public int getIdLength(); +---- + +regardless of whether _Type_ is a primitive +type or a reference type. _Id_ is computed from `prop` as it was defined +in simple property. An array item is a specialization of the collection +item abstraction introduced in the collection property overview. + +* `get__Id__()` + +The array `getter` method returns an array containing the property’s +value. If the property’s value has not set, then `null` is returned. +* `set__Id__(_Type_ [])` + +The `array setter` method defines the property’s set value. If the +argument itself is `null` then the property’s set value, if any, is +discarded. If the argument is not `null` and `TypeConstraint` validation +is enabledfootnote:constraint[] then the sequence of values in the +array are first validated by applying the property’s predicate, which +may throw a `TypeConstraintException`. If the `TypeConstraintException` +is thrown, the property retains the value it had prior to the `set` +method invocation. The property’s value is only modified after the +`TypeConstraint` validation step. +* `set__Id__(int, _Type_)` + +The indexed `setter` method allows one to set a value within the array. +The runtime exception `java.lang.ArrayIndexOutOfBoundsException` may be +thrown if the index is used outside the current array bounds. If the +value argument is non-null and TypeConstraint validation is enabledfootnote:constraint[], +the value is validated against the property’s predicate, which may throw +an unchecked `TypeConstraintException`. If `TypeConstraintException` is +thrown, the array index remains set to the same value it had before the +invocation of the indexed `setter` method. When the array item +represents a nillable element declaration and the indexed setter value +parameter is null, it is semantically equivalent to inserting a nil +element into the array. +* `get__Id__(int)` + +The indexed `getter` method returns a single element from the array. +The runtime exception `java.lang.ArrayIndexOutOfBoundsException` may be +thrown if the index is used outside the current array bounds. In order +to change the size of the array, you must use the array set method to +set a new (or updated) array. +* `get__Id__Length()` + +The indexed length method returns the length of the array. This method +enables you to iterate over all the items within the indexed property +using the indexed mutators exclusively. Exclusive use of indexed +mutators and this method enable you to avoid the allocation overhead +associated with array `getter` and `setter` methods. + +The arrays returned and taken by these +methods are not part of the content object’s state. When an array +`getter` method is invoked, it creates a new array to hold the returned +values. Similarly, when the corresponding array `setter` method is +invoked, it copies the values from the argument array. + +To test whether an indexed property has a set +value, invoke its `array getter` method and check that the result is not +`null`. To discard an indexed property’s set value, invoke its array +`setter` method with an argument of `null`. + +See the customization attribute +`collectionType` in <<globalbindings-declaration>> +and <<property-declaration>> on how to enable the generation of indexed property +methods for a collection property. + +*_Example:_* + +In the purchase order schema, we have the +following repeating element occurrence of element _item_ within +`complexType` _Items_. + +[source,xml,indent=4] +---- +<xs:complexType name="Items"> + <xs:sequence> + <xs:element name="item" minOccurs="1" maxOccurs="unbounded"> + <xs:complexType>...</xs:complexType> + </xs:element> +</xs:complexType> +---- + +The content specification of this element +type could be bound to an array property realized by these five methods: + +[source,java,indent=4] +---- +public Items.ItemType[] getItem(); +public void setItem(Items.ItemType[] value); +public void setItem(int index, Items.ItemType value); +public Items.ItemType getItem(int index); +public int getItemLength(); +---- + +===== List Property + +A list property `prop` with base type _Type_ +is realized by the method where `List` +[source,java,indent=8] +---- +public List<Type> getId(); +---- +is the interface `java.util.List`, +_Id_ is defined as above. If base type is a primitive type, the +appropriate wrapper class is used in its place. + +* The `get` method returns an object that +implements the `List<Type>` interface, is mutable, and contains the +values of type _Type_ that constitute the property’s value. If the +property does not have a set value or a schema default value, a zero +length `java.util.List` instance is returned. + +The `List` returned by the `get` method is a +component of the content object’s state. Modifications made to this list +will, in effect, be modifications to the content object. If +`TypeConstraint` validation is enabled, the list’s mutation methods +apply the property’s predicate to any non-`null` value before adding +that value to the list or replacing an existing element’s value with +that value; the predicate may throw a `TypeConstraintException`. The +collection property overview discussion on setting a collection item to +null specifies the meaning of inserting a null into a List. + +The `unset` method introduced in +<<isset-property-modifier>> enables one to +discard the set value for a List property. + +[NOTE] +.Design Note +==== +There is no setter method for a List property. The getter returns +the List by reference. An item can be added to the List returned by +the getter method using an appropriate method defined on `java.util.List`. +Rationale for this design in JAXB 1.0 was to enable the implementation +to wrapper the list and be able to perform checks as content was added +or removed from the List. + +==== + +*_Example:_* + +The content specification of the _item_ +element type could alternatively be bound to a list property realized by +one method: + +[source,java,indent=4] +---- +public List<Item> getItem(); +---- + +The list returned by the `getItem` method +would be guaranteed only to contain instances of the `Item` class. As +before, its length would be checked only during validation, since the +requirement that there be at least one `item` in an element instance of +complex type definition `Items` is a structural constraint rather than a +type constraint. + +==== Constant Property + +An attribute use named _prop_ with a schema +specified fixed value can be bound to a Java constant value. _Id_ is +computed from _prop_ as it was defined in simple property. The value of +the fixed attribute of the attribute use provides the `_<fixedValue>_` +constant value. + +[source,java,indent=8] +---- +public static final Type ID = <fixedValue>; +---- + +The binding customization attribute +`fixedAttributeToConstantProperty` enables this binding style. +<<globalbindings-declaration>> and <<property-declaration>> +describe how to use this attribute. + +==== `isSet` Property Modifier + +This optional modifier augments a modifiable +property to enable the manipulation of the property’s value as +a _set value_ or a _defaulted value_. Since this functionality +is above and beyond the typical JavaBean pattern for a property, +the method(s) associated with this modifier are not generated by default. +<<Customizing XML Schema to Java Representation Binding>> +describes how to enable this customization +using the `generateIsSetMethod` attribute. + +The method signatures for the `isSet` +property modifier are the following: + +[source,java,indent=8] +---- +public boolean isSetId(); +---- + +where `_Id_` is defined as it was for simple and collection property. + +* The `isSet` method returns `true` if the +property has been set during unmarshalling or by invocation of the +mutation method `setId` with a non-`null` value.footnote:[A Java application +usually does not need to distinguish between the absence of a element +from the infoset and when the element occurred with nil content. Thus, +in the interest of simplifying the generated API, methods were not +provided to distinguish between the two. Two annotation elements +@XmlElement.required and @XmlElement.nillable allow a null value to be +marshalled as an empty or nillable element.] + +To aid the understanding of what `isSet` method implies, +note that the unmarshalling process only unmarshals _set values_ +into XML content. + +A list property and a simple property with a +non-reference base type require an additional method to enable you to +discard the _set value_ for a property: + +[source,java,indent=8] +---- +public void unsetId(); +---- + +* The `unset` method marks the property as +having no _set value_. A subsequent call to `getId` method returns the +schema-specified default if it existed; otherwise, it returns the Java +default initial value for `Type`. + +All other property kinds rely on the +invocation of their set method with a value of null to discard the set +value of its property. Since this is not possible for primitive types or +a List property, the additional method is generated for these +cases illustrate the +method invocations that result in transitions between the possible +states of a JAXB property +value. + +.States of a Property Value +[[a623]] +image::xmlb-8.svg[image] + +*_Example:_* + +In the purchase order schema, the `partNum` +attribute of the element `item`’s anonymous complex type is declared: + +[source,xml,indent=4] +---- +<xs:attribute name="partNum" type = "SKU" use="required"/> +---- + +This attribute could be bound to a `isSet` +simple property realized by these four methods: + +[source,java,indent=8] +---- +public String getPartNum(); +public void setPartNum(String skuValue); +public boolean isSetPartNum(); +public void unsetPartNum(); +---- + +It is legal to invoke the `unsetPartNum` +method even though the attribute’s `use` is `"required"` in the XML +Schema. That the attribute actually has a value is a local structural +constraint rather than a type constraint, so it is checked during +validation rather than during mutation. + +==== Element Property + +This property pattern enables the dynamic +association of an element name for a JAXB property. Typically, the +element name is statically associated with a JAXB property based on the +schema’s element name. Element substitution groups and wildcard content +allow an XML document author to use Element names that were not +statically specified in the content model of the schema. To support +these extensibility features, an application uses element property +setters/getters to dynamically introduce element names at runtime. + +The method signatures for the `Element` +property pattern are the following: + +[source,java,indent=8] +---- +public void setId(JAXBElement<? extends Type> value); +public JAXBElement<? extends Type> getId(); +---- + +where `_Id_` and `_Type_` are defined as they +were for simple and collection property. The fully qualified Java name +for `_JAXBElement<T>_` is `_jakarta.xml.bind.JAXBElement<T>_`. The generic +types in the method signatures are expressed as a bounded wildcard to +support element substitution group, see details in +<<Element Declaration>>. + +==== Property Summary + +The following core properties have been defined: + +* Simple property - JavaBean design pattern for single value property +* Indexed property - JavaBean design pattern for multi-valued property +* List property - Leverages java.util.Collection +* Constant property + +The methods generated for these four core +property kinds are sufficient for most applications. Configuration-level +binding schema declarations enable an application to request finer +control than provided by the core properties. For example, the `isSet` +property modifier enables an application to determine if a property’s +value is set or not. + +=== Java Element Representation + +Based on rationale and criteria described in +<<Element Declaration>>, the schema +compiler binds an element declaration to a Java instance that implements +`jakarta.xml.bind.JAXBElement<T>`. `JAXBElement<T>` class provides access +to the basic properties of an XML element: its name, the value of the +element’s datatype, and whether the element’s content model is set to +nil, i.e. `xsi:nil="true"`. Optional properties for an Xml element that +corresponds to an element declaration from a known schema include the +element declaration’s declared type and scope. + +The enhanced, default binding for an element +declaration only generates a element instance factory method and is +described in <<Named Java Element instance>>.footnote:[The exception case is +that an element declaration with an anonymous type definition is bound +to a schema-derived value class by default as described in +<<Binding of an anonymous complex type definition>>.] +The customized binding that generates +a schema-dervied Element class for an element declaration is described +in <<Java Element Class>>. + +==== Named Java Element instance + +Based on the normative binding details +described in <<bind-to-jaxbelementt-instance>>, +the schema compiler binds an element declaration to an +element instance factory method. + +The following is a generic element factory signature. + +[source,java,indent=8] +---- +package elementDeclarationTargetNamespace; +class ObjectFactory { + jakarta.xml.bind.JAXBElement<ElementType> + createElementName(ElementType value); +} +---- + +The element factory method enables an +application to work with elements without having to directly know the +precise `javax.xml.namespace.QName`. The element factory method +abstraction sets the Xml element name with the Java representation of +the element, thus shielding the JAXB user from the complexities of +manipulating namespaces and QNames. + +.Binding of global element declaration to element factory +[source,xml+java,indent=4] +---- +<xs:schema targetNamespace=”a” xmlns:a=”a”/> +<xs:element name=”Foo” type=”xsd:int”/> + +class ObjectFactory { + // returns JAXBElement with its name set to QName(“a”, “Foo”). + JAXBElement<Integer> createFoo(Integer value); +} +---- + +==== Java Element Class + +Based on criteria to be identified in +<<Bind to Element Class>>, the schema +compiler binds an element declaration to a Java element class. An +element class is defined in terms of the properties of the +<<Element Declaration Schema Component>> +as follows: + +* An element class name is generated from the +element declaration’s name using the XML Name to Java identifier name +mapping algorithm specified in <<The Name to Identifier Mapping Algorithm>>. +* Scope of element class +** Global element declarations are declared in +package scope. +** By default, local element declarations +occur in the scope of the first ancestor complex type definition that +contains the declaration. The schema customization <jaxb:globalBindings +localScoping=”toplevel”/>, specified in <<Usage>>, disables the generation of +schema-derived nested classes and all classes are generated as toplevel +classes. +* Each generated Element class must extend +the Java class `jakarta.xml.bind.JAXBElement<T>`. The type T of the +`JAXBElement<T>` is derived from the element declaration’s type. +Anonymous type definition binding is a special case that is specified in +<<Binding of an anonymous complex type definition>>. +* A factory method is generated in the +package’s `ObjectFactory` class introduced in +<<Java Package>>. The factory method +returns `JAXBElement<T>`. The factory method has one parameter that is +of type `T`. The name of the factory method is generated by +concatenating the following components: ++ +-- +** The string constant `create`. +** If the Java element class is nested within +a value class, then the concatenation of all outer Java class names. +** The _name_ of the Java value class. +-- ++ +The returned instance has the Xml Element +name property set to the QName representing the element declaration’s +name. + +For example, a Java element class named `Foo` +that is nested within Java value class `Bar` would have the following +factory method generated in the containing Java package’s +`ObjectFactory` class: + + JAXBElement<Integer> createBarFoo(Integer value) + +* A public no-arg constructor is generated. + +The constructor must set the appropriate Xml element name, just as the +element factory method does. +* The Java element representation extends +`JAXBElement<T>` class, its properties provide the capability to +manipulate +** the value of the element’s content + +Xml Schema’s type substitution capability is enabled by this property. +** whether the element’s content model is `nil` + +*_Example:_* + +Given a complex type definition with mixed contentfootnote:[Bind mixed +content describes why <ASimpleElement> element is bound to a Java +Element representation.]footnote:[Assume a +customization that binds this local element declaration to an element +class. By default, this local declaration binds to a element instance +factory returning JAXBElement<Integer>]: + +[source,xml,indent=4] +---- +<xs:complexType name="AComplexType" mixed="true"> + <xs:sequence> + <xs:element name="ASimpleElement" type="xs:int"/> + </xs:sequence> +</xs:complexType> +---- + +Its Java representation: + +[source,java,indent=4] +---- +public value class AComplexType { + public class ASimpleElement extends + jakarta.xml.bind.JAXBElement<Integer> { + } + ... +}; +class ObjectFactory { + AComplexType createAComplexType(); + JAXBElement<Integer> + createAComplexTypeASimpleElement(Integer value); + ... +} +---- + +==== Java Element Representation Summary + +Element declaration binding evolved inJakarta XML Binding +to support XML Schema type substitution. The following diagrams +illustrate the binding changes for the following schema fragment: + +[source,xml,indent=8] +---- +<xs:element name=”foo” type=”fooType”/> +---- + +.JAXB 1.0: isA Relationship between generated element interface and its type +image::xmlb-9.svg[image] + +.Jakarta XML Binding: hasA Relationship between element instance and its type as described in <<Named Java Element instance>> +image::xmlb-10.svg[image] + +.Jakarta XML Binding: hasA Relationship between generated element class and its type as described in <<Java Element Class>> +image::xmlb-11.svg[image] + +While a JAXB 1.0 Element interface implemented its type’s interface, +a Jakarta XML Binding Element instance has a +composition relationship to the value of the element declaration’s type, +accessible via the `jakarta.xml.bind.JAXBElement<T>` property `Value` . +This change reflects the relationship that type substitution allows an +element declaration to be associated with many different datatypes, not +just the datatype that was defined statically within the schema. + +An added benefit to the default binding +change is to reduce the overhead associated with always generating Java +Element classes for every global element declaration. A value class +is generated for every complex type definition and only a factory +method needs to be generated for each global element declaration. + +=== Summary + +The composition and relationships between the +Java components introduced in this section are reflected in the +following diagram. + +.UML diagram of Java Representationfootnote:[See next figure fordefault binding for anonymous type definition.] +image::xmlb-12.svg[image] + +.UML diagram when xs:element is bound to schema-derived Element class +image::xmlb-13.svg[image] + +See also <<table614>>. + +
diff --git a/spec/src/main/asciidoc/ch06-binding_xml_schema.adoc b/spec/src/main/asciidoc/ch06-binding_xml_schema.adoc new file mode 100644 index 0000000..281e26e --- /dev/null +++ b/spec/src/main/asciidoc/ch06-binding_xml_schema.adoc
@@ -0,0 +1,3380 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +== Binding XML Schema to Java Representations + +This chapter describes binding of XML schema +components to Java representations. The default binding is identified in +this chapter and the next chapter specifies the customizations that +override default binding. + +=== Overview + +The abstract model described in [XSD Part 1] +is used to discuss the default binding of each schema component type. +Each schema component is described as a list of properties and their +semantics. References to properties of a schema component as defined in +[XSD Part 1] are denoted using the notation _{schema property}_ +throughout this section. References to properties of information items +as defined in [XML-Infoset] are denoted by the notation *[property]*. + +All JAXB implementations are required to +implement the default bindings specified in this chapter. However, users +and JAXB implementors can use the global configuration capabilities of +the custom binding mechanism to override the defaults in a portable +manner. + +For each binding of a schema component to its +Java representation, there is a description of Java mapping +annotation(s), described in <<Java Types To XML>>, +to be generated with the Java representation. The +standardization of these mapping annotations assist in specifying the +portability of a schema-derived JAXB-annotated classes. All JAXB +implementations are required to be able to unmarshal/marshal another +implementation’s schema-derived Java value classes by interpreting the +specified mapping annotations. Note that each mapping annotation is +described independent of whether it is the default mapping or a +customized mapping, JAXB implementations are allowed to optimize away +redundant mapping annotations that are the default mapping annotation. + +[NOTE] +.Design Note +==== +Note that the mapping annotations generated on the schema derived +classes do not capture all aspects from the original schema. +A schema generated from the mapping annotations of the schema derived +classes differs from the original schema used to generate +the schema-derived classes. The original schema is more precise +for validation purposes than the one generated from the schema-derived classes. + +==== + +All examples are non-normative. Note that in +the examples, the schema-derived code does not list all required mapping +annotations. In the interest of being terse, only the mapping +annotations directly connected to the schema component being discussed +are listed in its example. + +=== Simple Type Definition + +A schema component using a simple type +definition typically binds to a Java property. Since there are different +kinds of such schema components, the following Java property attributes +(common to the schema components) are specified here and include: + +* base type +* collection type if any +* predicate + +The rest of the Java property attributes are +specified in the schema component using the simple type definition. + +While not necessary to perform by default, +this section illustrates how a simple type definition is bound to a JAXB +mapped class. This binding is necessary to preserve a simple type +definition referred to by `xsi:type` attribute in an Xml instance +document. See <<Usage>> for the +customization that enables this binding. + +==== Type Categorization + +The simple type definitions can be categorized as: + +* schema built-in datatypes [XSD PART2] +* user-derived datatypes + +Conceptually, there is no difference between +the two. A schema built-in datatype can be a primitive datatype. But it +can also, like a user-derived datatype, be derived from a schema +built-in datatype. Hence no distinction is made between the schema +built-in and user-derived datatypes. + +The specification of simple type definitions +is based on the abstract model described in Section 4.1, “Simple Type +Definition” [XSD PART2]. The abstract model defines three varieties of +simple type definitions: atomic, list, union. The Java property +attributes for each of these are described next. + +==== Atomic Datatype + +If an atomic datatype has been derived by +restriction using an “enumeration” facet, the Java property attributes +are defined by <<Enum Type>>. Otherwise +they are defined as described here. + +The base type is derived upon the XML +built-in type hierarchy [XSD PART2, Section 3] reproduced below. + +.XML Built-In Type Hierarchy +image::xmlb-15.png[image] + + +The above diagram is the same as the one in +[XSD PART2] except for the following: + +* Only schema built-in atomic datatypes derived by restriction have been shown. +* The schema built-in atomic datatypes have been annotated with Java data types +from the <<a725>> table below. + +[NOTE] +.Design Note +==== +xs:anyURI is not bound to java.net.URI by default since not all +possible values of xs:anyURI can be passed to the java.net.URI constructor. +Using a global JAXB customization described in <<javatype-declaration>>, +a JAXB user can override the default mapping to map xs:anyURI to java.net.URI. + +==== + + +The following is a mapping for subset of the +XML schema built-in data types to Java data types. This table is used to +specify the base type later. + +.Java Mapping for XML Schema Built-in Types +[[a725]] +[cols="2*",options="header"] +|=== +|XML Schema Datatype |Java Datatype +| *xsd:string* | *java.lang.String* +| *xsd:integer* | *java.math.BigInteger* +| *xsd:int* | *int* +| *xsd:long* | *long* +| *xsd:short* | *short* +| *xsd:decimal* | *java.math.BigDecimal* +| *xsd:float* | *float* +| *xsd:double* | *double* +| *xsd:boolean* | *boolean* +| *xsd:byte* | *byte* +| *xsd:QName* | *javax.xml.namespace.QName* footnote:jaxp[JAXP defines package +`javax.xml.datatype` and `javax.xml.namespace`] +| xsd:dateTime |javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] +| *xsd:base64Binary* | *byte[]* +| *xsd:hexBinary* | *byte[]* +| xsd:unsignedInt | long +| xsd:unsignedShort | int +| xsd:unsignedByte | short +| xsd:time | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] +| xsd:date | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] +| xsd:g* | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] +| xsd:anySimpleType + +(for xsd:element of this type)footnote:[enable type substitution for element of xsd:anySimpleType] | java.lang.Object +| xsd:anySimpleType + +(for xsd:attribute of this type) | java.lang.String +| xsd:duration | javax.xml.datatype.Duration footnote:jaxp[] +| xsd:NOTATION | javax.xml.namespace.QName footnote:jaxp[] +|=== + +The base type is determined as follows: + +. Map by value space bounding facets + +If the simple type derives from or is `xsd:integer` and has either a +constraining lower and/or upper bounds facet(s) or totalDigits facet, +check if the following optimized binding is possible: +* If the simple type derives from or is +`xsd:short`, `xsd:byte` or `xsd:unsignedByte`, go to step 2. +* If the value space for the simple type is +representable in the range of `java.lang.Integer.MIN_VALUE` and +`java.lang.Integer.MAX_VALUE`, map to java primitive type, `int`. +* If the value space for the simple type is +representable in the range of `java.lang.Long.MIN_VALUE` and +`java.lang.Long.MAX_VALUE`, map to java primitive type, `long`. +* Else go to step 2. +. Map by datatype + +If a mapping is defined for the simple type in Table 6.1, the base type +defaults to its defined Java datatype. +. Map by base datatype + +Otherwise, the base type must be the result obtained by repeating the +step 1 and 2 using the _{base type definition}_. For schema datatypes +derived by restriction, the _{base type definition}_ represents the +simple type definition from which it is derived. Therefore, repeating +step 1 with _{base type definition}_ essentially walks up the XML Schema +built-in type hierarchy until a simple type definition which is mapped +to a Java datatype is found. + +The Java property predicate must be as +specified in “Simple Type Definition Validation Rules,” Section +4.1.4[XSD PART2]. + +*_Example:_* + +The following schema fragment (taken from +Section 4.3.1, “Length” [XSD PART2]): + +[source,xml,indent=4] +---- +<xs:simpleType name="productCode"> + <xs:restriction base="xs:string"> + <xs:length value="8" fixed="true"/> + </xs:restriction> +</xs:simpleType> +---- + +The facet “length” constrains the length of a +product code (represented by `productCode`) to 8 characters (see +section 4.3.1 [XSD PART2] for details). + +The Java property attributes corresponding to +the above schema fragment are: + +* There is no Java datatype mapping for `productCode`. +So the Java datatype is determined by walking up the +built-in type hierarchy. +* The `{base type definition}` of `productCode` +is `xs:string`. `xs:string` is mapped to `java.lang.String` +(as indicated in the table, and assuming no customization). Therefore, +`productCode` is mapped to the Java datatype `java.lang.String`. +* The predicate enforces the constraints on the length. + +===== Notation + +Given that the value space of `xsd:NOTATION` +is the set of `xsd:QName`, bind `xsd:NOTATION` type to +`javax.xml.namespace.QName`. + +For example, the following schema: + +[source,xml] +---- +<xs:schema targetNamespace="http://e.org" xmlns:e="http://e.org" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:notation name="jpeg" public="image/jpeg" system="jpeg.exe"/> + <xs:notation name="png" public="image/png" system="png.exe"/> + <xs:simpleType name="pictureType"> + <xs:restriction base="xs:NOTATION"> + <xs:enumeration value="e:jpeg"/> + <xs:enumeration value="e:png"/> + </xs:restriction> + </xs:simpleType> + <xs:complexType name="Picture"> + <xs:simpleContent> + <xs:extension base="xs:hexBinary"> + <xs:attribute name="format" type="e:pictureType"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> +</xs:schema> +---- + +is mapped to the following Java code: + +[source,java] +---- +package org.e; +import javax.xml.namespace.QName; +public class Picture { + void setValue(byte[] value) {...} + byte[] getValue() {...} + void setFormat(QName value)\{...} + QName getFormat() {...} +} +---- + +With the following usage scenario: + +[source,java,indent=4] +---- +Picture pic = ...; +pic.setFormat(new QName("http://e.org","jpeg")); +---- + +===== Bind to a JAXB mapped class + +By default, a named simple type definition is +not bound to a Java class. This binding is only necessary to enable the +precise type of an `xsi:type` substitution to be preserved as described +in <<Type Substitution of a Simple Type Definition>>. +This binding is enabled via the global binding +customization attribute _@mapSimpleTypeDef_ specified in +<<Usage>>. + +The binding of a named simple type definition +to a Java value class is based on the abstract model properties in +<<Simple Type Definition Schema Component>>. +The Java value class must be defined as specified here, +unless the ref attribute is specified on the `<jaxb:class>` declaration, +in which case the schema compiler will simply assume that the nominated +class is already bound to this simple type. + +* *name*: name is the Java identifier +obtained by mapping the XML name _{name}_ using the name mapping +algorithm, specified in <<The Name to Identifier Mapping Algorithm>>. +Note that anonymous simple type +definition’s are never bound to a Java value class. +* *package*: The schema-derived Java value class is generated +into the Java package that represents the binding of _{target namespace}_ +* *outer class name*: There is no outer class name for a global +simple type definition. +* *base class*: Due to a constraint specified for @XmlValue +in Section 8, this class can not extend any other class. The derivation +by restriction hierarchy for simple type definitions can not be captured +in the schema-derived Java value class. +* *value property*: Same as the binding of simple content in +<<Simple Content Binding>> to an @XmlValue +annotated JAXB property. + +The next two examples illustrate the binding +of a simple type definition to a Java value class when the appropriate +JAXB schema customization is enabled. + +[#a816] +.Simple type definition +[source,xml,indent=4] +---- +<xs:simpleType name="productCode"> + <xs:restriction base="xs:string"> + <xs:length value="8" fixed="true"/> + </xs:restriction> +</xs:simpleType> +---- + +.Binding of <<a816>> +[source,java,indent=4] +---- +@XmlType(name="productCode") +public class ProductCode { + @XmlValue + String getValue(); + void setValue(String value); +} +---- + +===== Annotations for standard XML datatypes + +By default, a schema-derived JAXB property +bound from one of the following standard XML datatypes is annotated with +the specified mapping annotation. + +[cols="2*",options="header"] +|=== +| `*Schema Type*` | `*JAXB Property Annotation*` +| `xsd:ID` | `@XmlID` +| `xsd:IDREF` | `@XmlIDREF` +| `ref:swaRef` | `@XmlAttachmentRef` +|=== + +Note that JAXB schema customizations could +override these default binding. + +==== Enum Type + +The default mapping for a named atomic type +that is derived by restriction with enumeration facet(s) and whose +restriction base type (represented by _{base type definition}_) is +`xs:String` footnote:[Exception cases that +do not bind to enum type: when the base type is or derives from `xs:ID` +and `xs:IDREF`. Rationale for not binding these type definitions to an +enum type is in <<Customizable Schema Elements>>.] or derived from it is mapped to an +enum type. The *[typesafeEnumBase]* attribute customization described in +<<globalbindings-declaration>>, enables +global configuration to alter what Xml built-in datatypes are bound by +default to an enum type. An anonymous simple type definition is never +bound to an enum class by default, but it can be customized as described +in <<typesafeenum-declaration>> to bind to an enum type. + +===== Example binding + +An example is provided first followed by a +more formal specification. + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:simpleType name="USState"> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="AK"/> + <xs:enumeration value="AL"/> + </xs:restriction> +</xs:simpleType> +---- + +The corresponding enum type binding is: + +[source,java,indent=4] +---- +public enum USState { + AK, AL; + public String value() { return name(); } + public static USState fromValue(String value) {...} +}; +---- + +===== Enum type binding + +The characteristics of an _enum type_ are +derived in terms of the properties of the +<<Simple Type Definition Schema Component>> as follows: + +The enum type binding is defined as follows: + +* *name*: The default name of the enum type, +_enumType_, is computed by applying the XML Name to Java identifier +mapping algorithm to the _{name}_ of the simple type definition. There +is no mechanism to derive a name for an anonymous simple type +definition, the customization must provide the *name*. +* *package name*: The package name is +determined from the _{targetnamespace}_ of the schema that directly +contains the simple type definition. +* *outer class name*: +** There is no *outer class name* for a global +simple type definition. +** There is no *outer class name* when schema +customization, *[jaxb:globalBindings]* _@localScoping_ , specified in +Section <<Usage>>, has a value of +_toplevel_. +** The *outer class name* for an anonymous +simple type definition is computed by traversing up the anonymous simple +type definition’s ancestor tree until the first ancestor is found that +is: +*** an XML component that is mapped to a Java value class, the *outer +class name* is composed of the concatenation of this Java value class’s +*outer class name*, "**.**", and its *name*. +*** a global declaration or definition is reached. There is no *outer +class name* for this case. +* *enum constants*: Specified in next section. + +Note that since a Java enum type is +essentially a final class, it is not possible for it to be subclassed. +Thus, any derivations of a simple type definition bound to an enum type +can not be captured by an equivalent Java inheritance relationship. + +The schema-derived enum is annotated, either +explicitly or by default mapping annotations, with the mapping +annotation @XmlEnum, specified in Section 8. The @XmlEnum annotation +elements are derived in terms of the abstract model properties for a +simple type definition summarized in +<<Simple Type Definition Schema Component>> as follows: + +.Annotate enum type with @XmlEnum element-value pairs +[cols="2*",options="header"] +|=== +| @XmlEnum element | @XmlEnum value +| name | simple type definition's {name} +| namespace | {target namespace} +| value | the java type binding of the simple type definition’s _{base type definition}_ +|=== + +===== Enum Constant + +An enum constant is derived for each +enumeration facet of the atomic type definition. The characteristics of +an _enum constant_ of the enum type are derived in terms of the properties +of the <<Enumeration Facet Schema Component>> as follows: + +* *name*: The name is either specified via +customization, `jaxb:typesafeEnumMember` described in +<<usage-7>>, or the name is computed as +specified in <<xml-enumvalue-to-java-identifier-mapping>>. +* *type*: The Java type binding of the simple +type definition’s _{base_type_definition}_. +* *value* : The conversion of string +_{value}_ to *type*. *Value* is manipulated via the following +generated enum type methods: + + public type value(); + public static enumTypeName fromValue(type value); + +To assist an application in manipulating the +enum constants that comprise an enum type, all enum types have the +following two implicitly declared static methods as specified in Section +8.9 in [JLS3]. The enum type’s static method `values()` returns an array +of all enum constants. The static method `valueOf(String name)` returns +the enum constant represented by the name parameter. + +===== XML Enumvalue-[[a863]]to-Java Identifier Mapping + +The default name for the enum constant is +based on mapping of the XML enumeration value to a Java identifier as +described below. + +The XML enumeration value _{value}_ is +mapped to a Java Identifier using the algorithm specified in +<<Deriving a legal Java identifier from an enum facet value>>. +If there is a collision among the generated +constant fields *name* or if it is not possible to generate a legal Java +identifier for one or more of the generated constant field names, see +<<typesafeenummembername>> for customization options to resolve this error case. + +===== Enum Constant Name differs from its Value + +For all cases where there exist at least one +enumeration constant name that is not the same as the enumeration +constant’s value, the generated enum type must have a final value field +that is set by the enum type’s constructor. The code generation template +is the following: + +.At least one enum constant name differs from its value. +[source,java] +---- +public enum enumType { + EnumConstantName1(EnumConstantValue1), + ... + EnumConstantNameX(EnumConstantValueX); + public EnumConstantValueType value() { return value; } + public static enumType fromValue(EnumConstantValueType val) + {...} + + final private EnumConstantValueType value; + private enumType(EnumConstantValueType value) { + this.value = value; + } +} +---- + +.Code template when enum constant name is same as its enum constant value. +[source,java,subs="+quotes,+macros"] +---- +public enum enumType { + EnumConstantName1, ..., EnumConstantNameX; + public Stringfootnote:[Note for this case, the _enumConstantValueType_ is always `java.lang.String`.] value() { return name(); } + public static enumType fromValue(String value) {...} +} +---- + +The schema-derived enum constant is +annotated, either explicitly or by default mapping annotations, with the +mapping annotation specified in Section 8. The `@XmlEnumValue` +annotation elements are derived in terms of the abstract model +properties for a enumerated facet summarized in +<<Enumeration Facet Schema Component>> as +follows: + +.Annotate enum constant with @XmlEnumValue element-value pairs +[cols="2*",options="header"] +|=== +| @XmlEnumValue element | @XmlEnumValue value +| value | Enumeration facet’s {value} +|=== + + +Given following schema fragment: + +.Schema-derived enum type when enumeration facet’s value does not match enum constant name. + +[source,xml,indent=4] +---- +<xs:simpleType name="Coin"> + <!-- Assume jaxb customization that binds Coin to an enumType --> + <xs:restriction base="xs:int"> + + <!-- Assume jaxb customization specifying enumConstantName --> + <xs:enumeration value="1"/> <!-- name="penny"--> + <xs:enumeration value="5"/> <!-- name="nickel"--> + <xs:enumeration value="10"/><!-- name="dime"--> + <xs:enumeration value="25"/><!-- name="quarter--> + </xs:restriction> +</xs:simpleType> +---- + +Schema-derived enum type: + +[source,java,indent=4] +---- +@XmlEnum(value="java.lang.Integer.class") +public enum Coin { + @XmlEnumValue("1") PENNY(1), + @XmlEnumValue("5") NICKEL(5), + @XmlEnumValue("10") DIME(10), + @XmlEnumValue("25") QUARTER(25); + + public int value() { return value; } + public static Coin fromValue(int value) {...} + + private final Integer value; + Coin(int value) { this.value = value; } +} +---- + +==== List + +A list simple type definition can only +contain list items of atomic or union datatypes. The item type within +the list is represented by the schema property _{item type definition}_. + +The Java property attributes for a list +simple type definition are: + +* The _base type_ is derived from the _{item type definition}_ as follows. +If the Java datatype for _{item type definition}_ is a Java primitive type, +then the base type is the wrapper +class for the Java primitive type. Otherwise, the Java datatype is +derived from the XML datatype as specified in +<<Atomic Datatype>> and <<Enum Type>>. +* The _collection type_ defaults to an +implementation of `java.util.List`. Note that this specification does +not specify the default implementation for the interface +`java.util.List`, it is implementation dependent. +* The _predicate_ is derived from the “Simple +Type Definition Validation Rules,” in section 4.1.4,[XSD PART2]. + +*_Example:_* + +For the following schema fragment: + +[source,xml,indent=4] +---- +<xs:simpleType name="xs:USStateList"> + <xs:list itemType="xs:string"/> +</xs:simpleType> +---- + +The corresponding Java property attributes +are: + +* The _base type_ is derived from _{item type definition}_ +which is XML datatype, `_"xs:string"_` , thus the Java +datatype is `java.util.String` as specified in <<a725>>. +* The _collection type_ defaults to an implementation of `java.util.List`. +* The _predicate_ only allows instances of +_base type_ to be inserted into the list. When failfast check is being +performedfootnote:[<<Usage>> +describes the `enableFailFastCheck` customization and +<<Validation>> defines fail-fast +checking.], the list’s mutation methods apply the +property’s predicate to any non-`null` value before adding that value +to the list or replacing an existing element’s value with that value; +the predicate may throw a `TypeConstraintException`. + +The schema-derived property is annotated, +either explicitly or by default mapping annotations, with the mapping +annotation @XmlList, specified in Section 8. + +==== Union Property + +A union property _prop_ is used to bind a +union simple type definition schema component. A union simple type +definition schema component consists of union members which are schema +datatypes. A union property, is therefore, realized by: + +[source,java,indent=8] +---- +public Type getId(); +public void setId(Type value); +---- + +where `_Id_` is a metavariable that represents +the Java method identifier computed by applying the name mapping +algorithm described in <<The Name to Identifier Mapping Algorithm>> to _prop_ . + +The _base type_ is String. If one of the +member types is derived by list, then the Union property is represented +as the appropriate collection property as specified by the customization +`<jaxb:globalBindings>` *@collectionType* value, specified in +<<Usage>>. + +* The `getId` method returns the set value. +If the property has no set value then the value `null` is returned. The +value returned is Type. +* The `setId` method sets the set value. + +If value is `null`, the property’s _set value_ is discarded. Prior to +setting the property’s value when TypeConstraint validation is enabled, +a non-`null` value is validated by applying the property’s predicate, +which may throw a `TypeConstraintException`. No setter is generated if +the union is represented as a collection property. + +*_Example: Default Binding: Union_* + +The following schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="CTType"> + <xs:attribute name="state" type="ZipOrName"/> +</xs:complexType> +<xs:simpleType name="ZipOrName" + memberTypes="xs:integer xs:string"/> +---- + +is bound to the following Java representation. + +[source,java] +---- +public class CTType { + String getState() {...} + void setState(String value) {...} +} +---- + +==== Union + +A simple type definition derived by a union +is bound using the union property with the following Java property +attributes: + +* the _base type_ as specified in +<<Union Property>>. +* if one of the member types is derived by `<xs:list>`, +then the union is bound as a Collection property. +* The _predicate_ is the schema constraints +specified in “Simple Type Definition Validation Rules,” Section 4.1.4 +[XSD PART2]. + +=== Complex Type Definition + +==== Aggregation of Java Representation + +A Java representation for the entire schema +is built based on aggregation. A schema component aggregates the Java +representation of all the schema components that it references. This +process is done until all the Java representation for the entire schema +is built. Hence a general model for aggregation is specified here once +and referred to in different parts of the specification. + +The model assumes that there is a schema +component _SP_ which references another schema component _SC_. The Java +representation of _SP_ needs to aggregate the Java representation of +_SC_. There are two possibilities: + +* _SC_ is bound to a property set. +* _SC_ is bound to a Java datatype or a Java value class. + +Each of these is described below. + +===== Aggregation of Datatype/Class + +If a schema component _SC_ is bound to a Java +datatype or a Java value class, then _SP_ aggregates _SC’s_ Java +representation as a simple property defined by: + +* *name*: the name is the class/interface +name or the Java datatype or a name determined by SP. The name of the +property is therefore defined by the schema component which is +performing the aggregation. +* *base type*: If SC is bound to a Java +datatype, the base type is the Java datatype. If SC is bound to a Java +value class, then the base type is the class name, including a dot +separated list of class names within which SC is nested. +* *collection type*: There is no collection type. +* *predicate*: There is no predicate. + +===== Aggregation of Property Set + +If _SC_ is bound to a property set, then _SP_ +aggregates by adding _SC’s_ property set to its own property set. + +Aggregation of property sets can result in +name collisions. A name collision can arise if two property names are +identical. A binding compiler must generate an error on name collision. +Name collisions can be resolved by using customization to change a +property name. + +==== Java value class + +The binding of a complex type +definition to a Java value class is based on the abstract model +properties in <<Complex Type Definition Schema Component>>. The Java value class must be defined as specified +here, unless the ref attribute is specified on the _<jaxb:class>_ +customization, in which case the schema compiler will simply assume that +the nominated class is already bound to this complex +type.footnote:[Note that +<<Binding of an anonymous complex type definition>> defines the name and package property for anonymous type +definitions occurring within an element declaration.] + +* *name*: name is the Java identifier +obtained by mapping the XML name _{name}_ using the name mapping +algorithm, specified in <<The Name to Identifier Mapping Algorithm>>. +For the handling of an anonymous complex +type definition, see <<Binding of an anonymous complex type definition>> +for how a *name* value is derived +from its parent element declaration. +* *package*: +** For a global complex type definition, the +derived Java value class is generated into the Java package that +represents the binding of _{target namespace}_ +** For the value of *package* for an anonymous +complex type definition, see <<Binding of an anonymous complex type definition>>. +* *outer class name*: +** There is no outer class name for a global +complex type definition. +** <<Binding of an anonymous complex type definition>> defines how to derive this +property from the element declaration that contains the anonymous +complex type definition. +* *base class*: A complex type definition +can derive by restriction or extension (i.e. _{derivation method}_ is +either "extension" or "restriction"). However, since there is no concept +in Java programming similar to restriction, both are handled the same. +If the _{base type definition}_ is itself mapped to a Java value class +(Ci2), then the base class must be Ci2. This must be realized as: ++ +-- +[source,java] +---- +public class Ci1 extends Ci2 { + ..... +} +---- +-- ++ +See example of derivation by extension at the +end of this section. + +* *abstract*: The generated Java class is +abstract when the complex type definition’s _{abstract}_ property is +`true`. +* *property set*: The Java representation of +each of the following must be aggregated into Java value class’s +property set (<<Aggregation of Java Representation>>). +** A subset of _{attribute uses}_ is +constructed. The subset must include the schema attributes corresponding +to the `<xs:attribute>` children and the _{attribute uses}_ of the +schema attribute groups resolved by the <ref> attribute. Every +attribute’s Java representation (<<Attribute use>>) +in the set of attributes computed above must be aggregated. +** If the optional _{attribute wildcard}_ is +present, either directly or indirectly, a property defined by +<<Attribute Wildcard>> is generated. +** The Java representation for _{content type}_ must be aggregated. ++ +For a “Complex Type Definition with complex +content,” the Java representation for _{content type}_ is specified in +<<content-model-particle-model-group-wildcard>>. ++ +For a complex type definition which is a “Simple Type Definition with +simple content,” the Java representation for _{content type}_ is +specified in <<Simple Content Binding>>. +** If a complex type derives by restriction, +there is no requirement that Java properties representing the attributes +or elements removed by the restriction to be disabled. This is because +(as noted earlier), derivation by restriction is handled the same as +derivation by extension. +* When the complex type definition’s +_{abstract}_ property is `false`, a factory method is generated in the +package’s `ObjectFactory` class introduced in +<<Java Package>>. The factory method +returns the type of the Java value class. The name of the factory method +is generated by concatenating the following components: +** The string constant `create`. +** The _name_ of the Java value class. + +The schema-derived Java value class is +annotated, either explicitly or by default mapping annotations, with the +mapping annotation @XmlType, specified in <<xmltype-3>>. The @XmlType annotation +elements are derived in terms of the abstract model properties for a +complex type definition summarized in +<<Complex Type Definition Schema Component>> as follows: + +.Annotate Java value class with @XmlType element-value pairs +[[a956]] +[width="100%",cols="50%,50%",options="header",] +|=== +| @XmlType element | @XmlType value +| name | complex type definition's {name} +| namespace | {target namespace} +| propOrder a | When \{content type} is element-only +{content model} and top-level {compositor} is xs:sequence, ordered +list of JAXB property names representing order of xs:elements in +{content model}. + + + +All other cases do not need to set propOrder. + +|=== + +*_Example:_* Complex Type: Derivation by Extension + +XML Schema Fragment (from XSD PART 0 primer): + +[source,xml,indent=4] +---- +<xs:complexType name="Address"> + <xs:sequence> + <xs:element name="name" type="xs:string"/> + <xs:element name="street" type="xs:string"/> + <xs:element name="city" type="xs:string"/> + </xs:sequence> +</xs:complexType> +<xs:complexType name="USAddress"> + <xs:complexContent> + <xs:extension base="ipo:Address"> + <xs:sequence> + <xs:element name="state" type="xs:string"/> + <xs:element name="zip" type="xs:integer"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> +</xs:complexType> +---- + +Default Java binding: + +[source,java,indent=4] +---- +public class Address { + String getName() {...} + void setName(String) {...} + String getStreet() {...} + void setStreet(String) {...} + void getCity() {...} + void setCity(String) {...} +} + +import java.math.BigInteger; + +public class USAdress extends Address { + String getState() {...} + void setState(String) {...} { + BigInteger getZip() {...} + void setZip(BigInteger) {...} +} + +class ObjectFactory { + Address createAddress() {...} + USAddress createUSAddress() {...} +} +---- + +===== Simple Content Binding + +====== Binding to Property + +By default, a complex type definition with +simple content is bound to a Java property defined by: + +* *name*: The property name must be `value`. +* *base type, predicate, collection type*: +As specified in [XSD Part 1], when a complex type has simple content, +the content type (_{content type}_) is always a simple type schema +component. And a simple type component always maps to a Java datatype +(<<Simple Type Definition>>). Values of +the following three properties are copied from that Java type: +** base type +** predicate +** collection type + +The schema-derived JAXB property representing +simple content is annotated, either explicitly or by default mapping +annotations, with the mapping annotation @XmlValue, specified in <<xmlvalue>>. + +*_Example:_* Simple Content: Binding To Property + +XML Schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="internationalPrice"> + <xs:simpleContent> + <xs:extension base="xs:decimal"> + <xs:attribute name="currency" type="xs:string"/> + </xs:extension> + </xs:simpleContent> +</xs:complexType> +---- + +Default Java binding: + +[source,java,indent=4] +---- +class InternationalPrice { + /** Java property for simple content */ + @XmlValue + java.math.BigDecimal getValue() {...} + void setValue(java.math.BigDecimal value) {...} + + /** Java property for attribute */ + String getCurrency() {...} + void setCurrency(String) {...} +} +---- + +==== xsd:anyType + +`xsd:anyType` is the root of the type +definition hierarchy for a schema. All complex type definitions in a +schema implicitly derive from `xsd:anyType`. Given that the JAXB +architecture does not define a common base class for all JAXB class +bindings of complex type definitions, the only possible binding property +base type binding for `xsd:anyType` is to `java.lang.Object`. This +binding enables all possible type and element substitutions for an +element of type `xsd:anyType`. + +.Binding of element with type _xsd:anyType_ +[source,xml,indent=4] +---- +<xs:element name="anyContent/> <!-- @type defaults to xs:anyType --> +<xs:complexType name="base"> + <xs:sequence> + <xs:element ref="anyContent/> + <xs:element name="anyContentAgain" type="xs:anyType"/> + </xs:sequence> +</xs:complexType> +---- +[source,java,indent=4] +---- +public class Base { + void setAnyContent(Object obj); + Object getAnyContent(); + void setAnyContentAgain(Object obj); + Object getAnyContentAgain(); +} +---- + +A schema author defines an element to be of +type `xs:anyType` to defer constraining an element to a particular type +to the xml document author. Through the use of `xsi:type` attribute or +element substitution, an xml document author provides constraints for an +element defined as `xs:anyType`. The JAXB unmarshaller is able to +unmarshal a schema defined `xsd:anyType` element that has been +constrained within the xml document to an easy to access JAXB mapped +class. However, when the xml document does not constrain the +`xs:anyType` element, JAXB unmarshals the unconstrained content to an +element node instance of a supported DOM API. + +Type substitution is covered in more detail +in <<Type Substitution of a Complex Type Definition>> +and <<Type Substitution of a Simple Type Definition>>. +Element substitution is covered in more detail in +<<Bind to a Simple Element property>>. + +=== Attribute Group Definition + +There is no default mapping for an attribute +group definition. When an attribute group is referenced, each attribute +in the attribute group definition becomes a part of the _[attribute uses]_ +property of the referencing complex type definition. Each attribute is +mapped to a Java property as described in +<<Attribute use>>. If the attribute group +definition contains an attribute wildcard, denoted by the +`xs:anyAttribute` element, then the referencing complex type definition +will contain a property providing access to wildcard attributes as +described in <<Attribute Wildcard>>. + +=== Model Group Definition + +When a named model group definition is +referenced, the JAXB property set representing its content model is +aggregated into the Java value class representing the complex type +definition that referenced the named model group definition as +illustrated in <<a999>>. + +.Binding for a reference to a model group definition. +[[a999]] +image::xmlb-16.svg[image] + +This binding style results in the same +properties occurring within both Java value class’s A and C to represent +the referenced Model Group B’s content model. + +When a model group definition’s content model +contains an XML Schema component that is to be bound to a Java value +class, element class or enum type, it is desirable to only create a +single Java representation, not one for each complex content that +references the named model group definition. This default binding from a +model group definition’s content model is defined in +<<Deriving Class Names for Named Model Group Descendants>>. + +To meet the Jakarta XML Binding goal of predictable +unmarshalling of invalid XML content, the JAXB 1.0 customization for +binding a model group to a JAXB mapped class is no longer supported. +<<Flexible Unmarshalling>> details the rationale behind this change. + +==== Bind to a set of properties + +A non-repeating reference to a model group +definition, when the particle referencing the group has _{max occurs}_ +equal to one, results in a set of content properties being generated to +represent the content model. <<content-model-particle-model-group-wildcard>> +describes how a content model +is bound to a set of properties and has examples of the binding. + +==== Bind to a list property + +A reference to a model group definition from +a particle with a repeating occurrence is bound by default as specified +in <<Bind a repeating occurrence model group>>. + +*_Example:_* + +Schema fragment contains a particle that +references the model group definition has a _{maxOccurs}_ value greater +than one. + +[source,xml,indent=4] +---- +<xs:group name="AModelGroup"> + <xs:choice> + <xs:element name="A" type="xs:int"/> + <xs:element name="B" type="xs:float"/> + </xs:choice> +</xs:group> + +<xs:complexType name="foo"> + <xs:sequence> + <xs:group ref="AModelGroup" maxOccurs="unbounded"/> + <xs:element name="C" type="xs:float"/> + </xs:sequence> +</xs:complexType> +---- + +Derived Java representation: + +[source,java,indent=4] +---- +public class Foo { + /** A valid general content property of AModelGroup content model.*/ + @XmlElements({ + @XmlElement(type=Integer.class, name="A"), + @XmlElement(type=Float.class, name="B")}) + java.util.List<Object> getAModelGroup() {...} + + float getC() {...} + void setC(float value) {...} +}; +---- + +==== Deriving Class Names for Named Model Group Descendants + +When a model group definition’s content model +contains XML Schema components that need to be bound to a Java class or +interface, this section describes how to derive the package and name for +the Java value class, enum type or element class derived from the +content model of the model group definition. The binding of XML Schema +components to Java classes/interfaces is only performed once when the +model group definition is processed, not each time the model group +definition is referenced as is done for the property set of the model +group definition. + +XML Schema components occurring within a +model group definition’s content model that are specified by this +chapter and the customization chapter to be bound to a Java value class, +interface or typesafe enum class are bound as specified with the +following naming exceptions: + +* *package*: The element class, Java value +class or typesafe enum class is bound in the Java package that +represents the target namespace containing the model group definition. +* *name*: The name of the interface or +class is generated as previously specified with one additional step to +promote uniqueness between interfaces/classes promoted from a model +group definition to be bound to a top-level class within a Java package. +By default, a prefix for the interface/class name is computed from the +model group definition’s _{name}_ using the XML name to Java identifier +algorithm. If the schema customization *[jaxb:globalBindings]* +_@localScoping_ has a value of _toplevel_, then a prefix is not +generated from the model group definition’s _{name}_. + +For example, given a model group definition +named _Foo_ containing an element declaration named _bar_ with an +anonymous complex type definition, the anonymous complex type definition +is bound to a Java value class with the name _FooBar_. The following +figure illustrates this example. + +.Default binding for anonymous type def within a model group definition. +image::xmlb-17.svg[image] + + +Note that even customization specified Java +value class, interface or typesafe enum class names are prepended with +the model group definition’s name. Thus, if a model group definition +named `Foo` contains an anonymous simple type definition with a typesafe +enum class customization name of `Colors`, the enum type name is +`FooColors`. + +=== Attribute Declaration + +An attribute declaration is bound to a Java +property when it is referenced or declared, as described in +<<Attribute use>>, from a complex type definition. + +==== Bind global attribute to a QName Constant + +To assist the dynamic access to schema-defined global attributes +described in Section 6.9, “Attribute Wildcard", a global attribute +declaration is bound to a JAXB QName constant, derived in terms of +the properties of the “Attribute Declaration Schema Component” +as follows: + +* A _package name_, which is either computed from the attribute +declaration _{target namespace}_ or specified by binding +customization of the target namespace or a specified package +name for components that are scoped to no target namespace. +* The _name_ of the generated constant is derived from +the element declaration _{name}_ using the XML Name to Java +identifier mapping algorithm for a constant name or +specified by a binding customization of the attribute’s name. +* The QName constant is a JAXB constant property in class _ObjectFactory_. +* The QName constant value is initialized using the attribute declaration’s +_{target namespace}_ and _{name}_. + +.Bind global attribute declaration to a JAXB QName constant +[source,xml,indent=4] +---- +<xs:schema targetNamespace="http://e.org" xmlns:a="http://e.org"> + <xs:attribute name="isOpen" type="xs:boolean"/> +</xs:schema> +---- +[source,java,indent=4] +---- +package org.e; +public class ObjectFactory { + /** <xs:attribute name="{http://e.org}isOpen" type="xs:boolean"/> */ + public static final javax.xml.namespace.QName IS_OPEN = + new QName("http://e.org", "isOpen"); +... +} +---- + +=== Element Declaration + +This section describes the binding of an XML +element declaration to a Java representation. For a description of how +this binding has changed since the previous version, see +<<Java Element Representation Summary>>. +This section introduces why a JAXB technology user has to use instances +of JAXB element as opposed to instances of Java datatypes or Java value +class when manipulating XML content. + +An XML element declaration is composed of the +following key components: + +* its qualified name is _{target namespace}_ and _{name}_ +* its value is an instance of the Java class binding of its _{type definition}_ +* whether the element’s content is _{nillable}_ + +Typically, an instance of +`jakarta.xml.bind.JAXBElement<T>`, returned by an element factory method, +represents an element declaration’s key components. An instance of a +Java value class or content interface represents only the value of an +element. Commonly in JAXB binding, the Java representation of XML +content enables one to manipulate just the value of an XML element, not +an actual element instance. The binding compiler statically associates +the XML element qualified name to a content property and this +information is used at unmarshal/marshal time. For cases where the +element name can be dynamically altered at runtime, the JAXB user needs +to manipulate elements, not element values. The following schema/derived +Java code example illustrates this point. + +*_Example:_* + + +Given the XML Schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="chair_kind"> + <xs:sequence> + <xs:element name="has_arm_rest" type="xs:boolean"/> + </xs:sequence> +</xs:complexType> +---- + +Schema-derived Java value class: +[source,java,indent=4] +---- +public class ChairKind { + boolean isHasArmRest() {...} + void setHasArmRest(boolean value) {...} +} +---- + +A user of the Java value class `ChairKind` +never has to create a Java instance that both has the value of local +element `has_arm_rest` and knows that its XML element name is +`has_arm_rest`. The user only provides the value of the element to the +content-property `hasArmRest`. A JAXB implementation associates the +content-property `hasArmRest` with XML element name `has_arm_rest` when +marshalling an instance of `ChairKind`. + +The next schema/derived Java code example +illustrates when XML element information can not be inferred by the +derived Java representation of the XML content. Note that this example +relies on binding described in <<Bind wildcard schema component>>. + +*_Example:_* + +[source,xml,indent=4] +---- +<xs:complexType name="chair_kind"> + <xs:sequence> + <xs:any/> + </xs:sequence> +</xs:complexType> +---- + +[source,java,indent=4] +---- +public class ChairKind { + @XmlAnyElement(lax="true") + java.lang.Object getAny() {...} + void setAny(java.lang.Object elementOrValue) {...} +} +---- + +For this example, the user can provide an +Element instance to the `any` content-property that contains both the +value of an XML element and the XML element name since the XML element +name could not be statically associated with the content-property `any` +when the Java representation was derived from its XML Schema +representation. The XML element information is dynamically provided by +the application for this case. <<content-model-particle-model-group-wildcard>> +cover additional circumstances when one can use JAXB elements. + +==== Bind to _JAXBElement<T>_ Instance + +The characteristics of the generated +ObjectFactory element factory method that returns an `JAXBElement<T>` +instance are derived in terms of the properties of the +<<Element Declaration Schema Component>> as follows: + +* The element factory method is generated +into the `ObjectFactory` class in the Java package that represents the +binding of the element declaration’s _{target namespace}_. +* The element factory method returns an +instance of `jakarta.xml.bind.JAXBElement<T>`, where `T` is the Java +value class representing the _{type definition}_ of the element +declaration. The factory method sets the element name of the returned +instance to the element declaration’s fully qualified name. +* The element factory method has a single +parameter that is an instance of type `T`, where `T` is the Java value +class representing the _{type definition}_ of the element declaration. +* The name of the factory method is generated +by concatenating the following components: +** The string constant `create`. +** By default, if the element declaration is +nested within another XML Schema component, then the concatenation of +all outer Java class names representing those XML Schema components. If +the schema customization *[jaxb:globalBindings]* _@localScoping_ has a +value of toplevel, skip this step. +** A name that is generated from the element +declaration's _{name}_ using the XML Name to Java identifier name +mapping algorithm specified in <<The Name to Identifier Mapping Algorithm>>. +* The `JAXBElement<T>` property for nil +test whether an element’s content model is `xsi:nil="true"`. + +For example, an element declaration named +`Foo` with a type of `xs:int` that is nested within the content +model of complex type definition `Bar` would have the following factory +method generated in the containing Java package's `ObjectFactory` class: + +[source,java,indent=8] +---- +JAXBElement<Integer> createBarFoo(Integer value) {...} +---- + +Default binding rules require an element +declaration to be bound to element factory method under the following +conditions: + +* All non-abstract, named element +declarations with global _{scope}_ are bound to an element factory method +that returns an `JAXBElement<T>` instance. The rationale is that any +global element declaration can occur within a wildcard context and one +might want to provide element instances, not instances of the element’s +type, the element’s value, for this case. +* All local element declarations, having a +_{scope}_ of a complex type definition, occurring within content that is +mapped to a general content property of JAXB elements must have an +element factory method generated. General content property is specified +in <<General content property>>. An +example of when a content model is mapped to a general content property, +forcing the generation of element declarations is at +<<Examples>>. + +The schema-derived element factory method is +annotated, either explicitly or by default mapping annotations, with the +mapping annotation `@XmlElementDecl`, specified in Section 8. The +`@XmlElementDecl` annotation elements are derived in terms of the +abstract model properties for an element declaration summarized in +<<Element Declaration Schema Component>> as follows: + +.Annotate element instance factory with @XmlElementDecl element-value pairs. +[width="100%",cols="50%,50%",options="header",] +|=== +| @XmlElementDecl element |@XmlElementDecl value +| name | element declaration's _{name}_ +| namespace | _{target namespace}_ +| scope | If _{scope}_ is _global_, `JAXBElement.GlobalScope.class` else the JAXB +Java value class representing the __{scope}__ing complex type definition. +| substitutionHeadName | If optional _{substitution group affiliation}_ exists, +its local name. +| substitutionHeadNamespace | If optional _{substitution group affiliation}_ exists, +its namespace. +|=== + +The element declaration’s _{type}_ can +result in additional JAXB annotations being generated on the element +instance factory. For more details, see <<Annotations for standard XML datatypes>> +and @XmlList in +<<list>>. + +The schema-derived ObjectFactory class +containing the @XmlElementDecl annotations is annotated with +@XmlRegistry annotation. + +==== Bind to Element Class + +<<class-declaration>> customization enables the binding of an element declaration +with a named type definition to a schema-derived Element class. The +characteristics of the schema-derived Element class are derived in terms +of the properties of the <<Element Declaration Schema Component>> as follows: + +* The _name_ of the generated Java Element +class is derived from the element declaration _{name}_ using the XML Name +to Java identifier mapping algorithm for class names. +* Each generated Element class must extend +the Java value class `jakarta.xml.bind.JAXBElement <T>`. The next bullet +specifies the schema-derived Java class name to use for generic +parameter `T`. +* If the element declaration’s _{type definition}_ is +** Anonymous ++ +Generic parameter `T` from the second bullet +is set to the schema-derived class represented the anonymous type +definition generated as specified in Section 6.7.3. +** Named ++ +Generic parameter `T` from the second bullet is +set to the Java class representing the element declaration’s +_{type definition}_. +* The `ObjectFactory` method to create an +instance of _name_ has a single parameter that is an instance of type `T`. +By default, the name of the ObjectFactory method is derived by +concatenating _outerClassNames_ and _name_. When schema customization, +*[jaxb:globalBindings]* _@localScoping,_ specified in <<Usage>>, +has a value of _toplevel_, +then the outer Classnames are ommitted from the factory method name. +* If _{scope}_ is +** *Global*: The derived Element class is +generated into the Java package that represents the binding of +_{target namespace}_. +** *A Complex Type Definition*: By default, +the derived Element class is generated within the Java value class +represented by the complex type definition value of _{scope}_. When +_@localScoping_ is _toplevel_ , the derived element class is generated +as a toplevel class. +* The property for nil test whether element’s content model is `xsi:nil="true"`. +* Optional _{value constraint}_ property with +pair of `default` or `fixed` and a value. + +If a default or fixed value is specified, the data binding system must +substitute the default or fixed value if an empty tag for the element +declaration occurs in the XML content. + +A global binding customization, +*@generateElementClass*, specified in <<globalbindings-declaration>> +enables this binding over the default +binding specified in the previous subsection. + +==== Binding of an anonymous complex type definition + +An anonymous complex type definition is bound +to a generated schema-derived Java value class by default. + +The naming characteristics of the generated +Java value class is derived in terms of the properties of the +<<Element Declaration Schema Component>> as follows: + +* The _name_ of the generated Java value class +is derived from the element declaration _{name}_ using the XML Name to +Java identifier. +* The _package_ of the generated Java value +class is the same as the package derived from the element declaration’s +_{target namespace}_. +* The _outer class names_ of the generated +Java value class is determined by the element declaration’s _{scope}_. +If _{scope}_ is: +** Global + +There is no outer class name. +** A Complex Type Definition + +By default, the derived Java value class is generated nested within the +Java value class represented by the complex type definition value of +_{scope}_. The derived Java value is not generated nested when schema +customization *[globalBindings]* has attribute _@localScoping_ with a +value of _toplevel_. +* _base class_: Same as defined in +<<Java value class>>. +* _property set_: As defined in +<<Java value class>>. +* A type factory method is generated in the +package’s `ObjectFactory` class introduced in +<<Java Package>>. The factory method +returns the type of the Java value class. The name of the factory method +is generated by concatenating the following components: +** The string constant `create`. +** If the element declaration containing the +anonymous complex type definition is nested within another complex type +definition representing a value class and [globalBindings] @localScoping +has a value of _nested_ , then the concatenation of all outer Java class +names. This step is skipped when @localScoping has a value of _toplevel_. +** The _name_ of the Java value class. + +The schema-derived value class is annotated +with the mapping annotation `@XmlType`, specified in +<<xmltype-2>>. The `@XmlType` annotation +elements are set as described in <<a956>> with one +exception: `@XmlType.name()` is set to the empty string. + +As long as the element declaration is not one +of the exception cases specified in +<<Bind Element Declaration to JAXBElement>>, the schema-derived value +class is annotated with the mapping annotation `@XmlRootElement` +specified in Section 8. The `@XmlRootElement` annotation elements are +derived in terms of the abstract model properties for the referenced +global element declaration summarized in +<<Element Declaration Schema Component>> as follows: + +.Annotate JAXB Mapped Class with @XmlRootElement element-value pairs + +[width="100%",cols="50%,50%",options="header",] +|=== +| @XmlRootElement element | @XmlRootElement value +|namespace a| When element declaration _{target namespace}_ is absent, + +(i.e. unqualified local element declaration), @XmlElement.namespace() is +not set. + + +Otherwise, set @XmlElement.namespace() to +value of _{target namespace}_. (either a qualified local element +declaration or a reference to a global element) + +Note: same result could be achieved with +package level annotation of @XmlSchema and not setting +@XmlElement.namespace. +| name | element declaration _{name}_ +|=== + +*_Example:_* + +Given XML Schema fragment: +[source,xml,indent=4] +---- +<xs:element name="foo"> + <xs:complexType> + <xs:sequence> + <xs:element name="bar" type="xs:int"/> + </xs:sequence> + </xs:complexType> +</xs:element> +---- + +Derived Java code: +[source,java,indent=4] +---- +/* Value class representing element +declaration with an anonymous complex type definition. */ +@XmlType(name="") +@XmlRootElement(namespace="", name="foo") +public class Foo { + int getBar() {...} + void setBar(int value) {...} +}; +class ObjectFactory { + // type factory method + Foo createFoo() {...} + // element factory method + JAXBElement<Foo> createFoo(Foo value) {...} +} +---- + +===== Bind Element Declaration to JAXBElement + +An element declaration with an anonymous +complex type definition is not bound to a `@XmlRootElement`,annotated +schema-derived class when the element declaration is: + +* nillable +* the head element or a member of a +substitution group +* non-global (i.e. declared within a complex +type definition) + +When one or more of the above conditions are +met, the schema-derived class representing the anonymous complex type +definition must not be annotated with `@XmlRootElement`. Instead, an +element factory that returns `JAXBElement<__anonymousTypeValueClass__>` +may be generated as specified in <<bind-to-jaxbelementt-instance>>. + +*_Example:_* + +Given XML Schema fragment: +[source,xml,indent=4] +---- +<xs:element name="foo" nillable="true"> + <xs:complexType> + <xs:sequence> + <xs:element name="bar" type="xs:int"/> + </xs:sequence> + </xs:complexType> +</xs:element> +---- + +Derived Java code: +[source,java,indent=4] +---- +/* Value class representing anonymous complex type definition. */ +@XmlType(name="") +public class Foo { + int getBar() {...} + void setBar(int value) {...} +}; +@XmlRegistry +class ObjectFactory { + // type factory method + Foo createFoo() {...} + // element factory method + @XmlElementDecl(name="foo", namespace="", nillable="true") + JAXBElement<Foo> createFoo(Foo value) {...} +} +---- + +==== Bind to a Property + +A local element declaration is bound by +default to a Java property as described in +<<Properties>>. The characteristics of the +Java property are derived in terms of the properties of the +<<Element Declaration Schema Component>> +and <<Particle Schema Component>> as follows: + +* The _name_ of the Java property is derived +from the _{element declaration}_ property’s _{name}_ property using the +XML Name to Java Identifier mapping algorithm described in +<<The Name to Identifier Mapping Algorithm>>. +* A _base type_ for the Java property is +derived from the `{element declaration}` property’s `{type +definition}` property as described in binding of Simple Type Definition +in <<Simple Type Definition>>. or +<<Complex Type Definition>>. If the base +type is initially a primitive type and this JAXB property is _optional_, +the *[jaxb:globalBinding]* customization `@optionalProperty` controls +the binding of an optional primitive property as described in +<<Usage>>. +* An optional _predicate_ for the Java +property is constructed from the `{element declaration}` property’s +`{type definition}` property as described in the binding of simple type +definition to a Java representation. +* An optional _collection type_ for the Java property is derived from: +** `{element declaration}` property’s +`{type definition}` property as described in the binding of simple type +definition to a Java representation +** the `{particle}` property’s `{max occurs}` +value being greater than one. +* Element defaulting + +The default value is derived from the element declaration’s \{value +constraint} property’s value. Unlike attribute defaulting, an element +only defaults when there is an empty element tag in an xml document. The +element’s default value is captured by mapping annotation +`@XmlElement.defaultValue()`. The unmarshaller sets the property to +this default value when it encounters an empty element tag. The +marshaller can output an empty element tag whenever the element’s +`@XmlValue` property value is the same as its defaulted value.. +* A local element declaration that binds to a +JAXB property with a primitive base type is bound as an _optional_ JAXB +property if the element declaration is a member of a choice model group +or the element declaration’s particle has optional occurrence, `{min +occurs}` value is `"0"`, or belongs to a model group that has optional +occurrence. By default, the optional JAXB property binds the property’s +base type to the Java wrapper class for the primitive type. One can test +and set the absence of an optional property using null. The +*[jaxb:globalBinding]* customization `@optionalProperty` controls +alternative bindings of an optional primitive property as described in +<<Usage>>. +* If the element declaration’s _{nillable}_ +property is `"true"` , the base type for the Java property is mapped to +the corresponding Java wrapper class for the Java primitive type. +Setting the property to the `null` value indicates that the property has +been set to the XML Schema concept of `@xs:nil="true"`. + +This Java property is a member of the Java +value class that represents the binding of the complex type definition +containing the local element declaration or reference to global element. + +The schema-derived JAXB property getter +method is annotated, either explicitly or by default mapping +annotations, with the mapping annotation `@XmlElement`, specified in +<<xmlelement>>. The `@XmlElement` annotation elements are +derived in terms of the abstract model properties for the referenced +global element declaration summarized in +<<Element Declaration Schema Component>> as follows: + +.Annotate JAXB Property with @XmlElement element-value pairs +[width="100%",cols="50%,50%",options="header",] +|=== +| @XmlElement element | @XmlElement value +|namespace a| When element declaration _{target namespace}_ is absent, + +(i.e. unqualified local element declaration), @XmlElement.namespace() is +not set. + + +Otherwise, set @XmlElement.namespace() to +value of _{target namespace}_. (either a qualified local element +declaration or a reference to a global element) + +Note: same result could be achieved with +package level annotation of @XmlSchema and not setting +@XmlElement.namespace. +| name | element declaration _{name}_ +| nillable | element declaration _{nillable}_ +| defaultValue |if element declaration _{value constraint}_ is not absent, +set defaultValue() to _{value constraint}_ ’s value. +|=== + +<<a1240>> illustrates how to +define an element substitution group and to reference the head element +of the substitution group within an Xml Schema. +<<a1242>> illustrates the Java bindings of the element substation +enabled schema. <<a1244>> demonstrates element +substitution using the JAXB API. <<a1246>> +illustrates invalid element substitution handling. + +===== Type Substitution of a Complex Type Definition + +<<Complex Type Definition>> describes that when a complex type definition is mapped to +Java value class that the type definition derivation hierarchy is +preserved in the Java class hierarchy. This preservation makes it quite +natural for Java to support the Xml Schema mechanism type substitution +across all complex type definitions. + +Performing an invalid type substitution is +not detected as a fail-fast check when setting the JAXB property or +checked as part of marshalling the element declaration. Invalid type +substitution can be checked by optional validation that can be enabled +as part of unmarshalling or marshalling process. + +The following three code examples illustrate +how type substitution is supported in JAXB for a complex type +definition hierarchy. + +.Xml Schema example containing type derivation hierarchy +[[a1152]] +[source,xml,indent=4,subs=+quotes] +---- +<xs:schema targetNamespace="travel:acme" xmlns:a="travel:acme"> + + <!-- Define type definition derivation hierarchy --> + <xs:complexType name="**TransportType**">...</xs:complexType> + <xs:complexType name="**PlaneType**"> + <xs:extension base="a:TransportType">...</xs:complexType> + <xs:complexType name="**AutoType**"> + <xs:extension base="a:TransportType">...</xs:complexType> + <xs:complexType name="**SUV**"> + <xs:extension base="a:AutoType">...</xs:complexType> + + <xs:complexType name="**itinerary**"> + <xs:sequence> + <!-- Type substitution possible for "transport". --> + <xs:element name="**transport**" type="**TransportType**"/> + </xs:sequence> + </xs:complexType> +</xs:schema> +---- + +.Java binding of Xml Schema from <<a1240>> +[[a1154]] +[source,java,indent=4,subs=+quotes] +---- +package travel.acme; + +// Type derivation hierarchy from schema is preserved in Java binding. +public class *TransportType* {...} +public class *PlaneType* extends TransportType {...} +public class *AutoType* extends TransportType {...} +public class *SUV* extends AutoType {...} + +public class ObjectFactory { + // Type Factories + TransportType createTransportType() {...} + AutoType createAutoType() {...} + PlaneType createPlaneType() {...} + TrainType createSUV() {...} +} + +public class Itinerary { + // Simple property supports type substitution. + *TransportType* getTransport() {...} + void setTransport(**TransportType** value) +} +---- + +.Type substitution using Java bindings from <<a1242>> +[source,java,indent=8,subs=+quotes] +---- +ObjectFactory of = ...; +Itinerary itinerary = of.createItinerary(); +itinerary.setTransport(of.createTransportType); // Typical Use + +*// Type Substitution* +// transport marshalled as <e:transport xsi:type="e:AutoType"> +itinerary.setTransport(of.createAutoType()); + +// transport marshalled as <e:transport xsi:type="e:PlaneType"> +itinerary.setTransport(of.createPlaneType()); +---- + +===== Type Substitution of a Simple Type Definition + +An XML element declaration having a simple +type definition is bound most naturally to a JAXB property with a base +type that is a primitive Java datatype. Unfortunately, this strongly +typed binding conflicts with fully supporting type substitution of a +simple type definition. Unlike the JAXB binding of complex type +definitions, the simple type derivation hierarchy is not preserved when +binding builtin XML Schema simple type definitions to corresponding Java +datatypes as specified in <<Atomic Datatype>>. +Since there is not a natural Java inheritance hierarchy to +support simple type substitution, a JAXB property customization is +required to enable optimal support of simple type substitution. + +For example, the most natural binding of an +XML Schema built-in datatype `xs:int` is to the Java primitive datatype, +`int`. However, simple type substitution implies that an `xs:short` or +a complex type definition that derives by extension from `xs:int` can be +type substituted for an `xs:int` within an XML document using the +`xsi:type` attribute. The strongly typed JAXB property with Java type +`int` would never allow for a Java value class for the complex type to +be assigned to a JAXB property of type `int`. + +By default, unmarshalling handles simple type +substitution by assigning the relevant part of the type substituted +content to the JAXB property. When the value of the xsi:type attribute +resolves to: + +* a type that derives by restriction from the +element’s schema type. +The substituted value is always parsable into a legal value of the base +type of the JAXB property being type substituted. +* a complex type that derives by extension +from element’s schema type. The JAXB binding +of the substituted complex type definition must have +one JAXB property annotated with an `@XmlValue` that is assignable to +the type substituted JAXB property’s base type. Attribute(s) associated +with the complex type definition can not be preserved by the default +binding. + +The rationale behind the default binding is +that substitution of a simple type definition occurs rarely. The default +JAXB binding is more convenient and precise for programmer to use. Its +one drawback is that it does not faithfully preserve `xsi:type` +occurring in an XML document. + +To enable more comprehensive support of +simple type substituting of an XML element with a simple type +definition, the JAXB property customization specified in +<<generalizespecialize-basetype-with-attribute-name>> enables +setting the property’s base type to the more +general type of `java.lang.Object`. This binding allows for retention of +the XML document `xsi:type` and attributes associated with complex type +definition substituted for an XML element with a simple type definition. +When an `xsi:type` value refers to a type definition not registered with +`JAXBContext` instance, the content is unmarshalled as the element’s +schema type. + +To preserve an application-defined simple +type definition involved in simple type substitution, it must be mapped +to a JAXB mapped class as described in <<Bind to a JAXB mapped class>>. +This can be achieved for all simple type +definitions in a schema using the customization `<jaxb:globalBinding +mapSimpleTypeDefs="true"/>` or it can be achieved per simple type +definition using <jaxb:class> customization. An invalid simple type +substitution can be detected by JAXP validation enabled at unmarshal +or marshal time + +Below are examples of the type substitution +of an XML element’s simple type definition for the default and +customized binding. + +.Schema fragment to illustrate simple type substitution +[[a1168]] +[source,xml,indent=4,subs=+quotes] +---- +<xsd:element name="Price"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="name" type="xsd:string"/> + _<!-- element price subject to type substitution -->_ + <xsd:element name="price" type="xsd:int"/> + </xsd:sequence> + </xsd:complexType> +</xsd:element> +<xsd:complexType name="AmountType"> + <xsd:simpleContent> _<!-- type substitutable for xs:int -->_ + <xsd:extension base="xsd:int"> + <xsd:attribute name="currency" type="xsd:string"/> + </xsd:extension> + </xsd:simpleContent> +</xsd:complexType> +<xsd:simpleType name="AppInt"> + <xsd:restriction base="xsd:int"/> +</xsd:simpleType> +---- + +.XML documents with simple type substitution +[[a1170]] +[source,xml,indent=4,subs=+quotes] +---- +<product> + <name>hotdog</name> + <price>3</price> +</product> + +<product> + <name>peanuts</name> + <price **xsi:type="short"**>4</price> +</product> + +<product> + <name>popcorn</name> + <price **xsi:type="AppInt"**>5</price> +</product> + +<product> + <name>sushi</name> + <price **xsi:type="AmountType"** currency="yen">500</price> +</product> +---- + +====== Default Handling of Simple Type Substitution + +.Default JAXB binding of <<a1168>> +[[a1176]] +[source,java,indent=4] +---- +public class AmountType { + @XmlValue + int getValue() {...} void setValue(int value) {...} + String getCurrency() {...} void setCurrency(String value) {...} +} + +@XmlRootElement(namespace="", name="product") +public class Product { + int getPrice() {...} void setPrice(int value) {...} + int getName() {...} void setName(String value) {...} +} +---- + +Unmarshalling XML document fragments from +<<a1170>> into <<a1176>> JAXB binding of element `product` results in the +`xsi:type` and attributes associated with JAXB mapped class `Price` +being lost as part of the unmarshal process. This loss is illustrated by +comparing <<a1179>> with <<a1204>>. + +.Product instances from unmarshalling XML docs from <<a1170>> +[[a1179]] +[width="100%",cols="20%,20%,20%,20%,20%",options="header",] +|=== +| document xsi:type | Product.name + +value | Product.price + +value | Product.price + +type | marshal Product.price xsi:type +| | hotdog | 3 | int | +| xs:short | peanuts | 4 | int | +| AppInt | popcorn | 5 | int | +| AmountType | sushi | 500 | int | +|=== + +====== Simple Type Substitution enabled by JAXB customizations. + +The simple type definition `AppInt` is mapped +to a JAXB class either by `<jaxb:class>` customization or by +`<jaxb:globalBindings mapSimpleTypeDef="true"/>`. The JAXB property +`Product.Price` is mapped to a JAXB property with a general base type of +`java.lang.Object` with following external JAXB schema customization: + +[source,xml,indent=4] +---- +<jaxb:bindings schemaLocation="CODE EXAMPLE" + node="//xsd:element[@name=’price’]"> + <jaxb:property> + <jaxb:baseType name="java.lang.Object" /> + </jaxb:property> +</jaxb:bindings> +---- + +specified in <<generalizespecialize-basetype-with-attribute-name>>. + +.Customized JAXB binding of <<a1168>> +[[a1201]] +[source,java,indent=4] +---- +public class AmountType { + @XmlValue + int getValue() {...} void setValue(int value) {...} + String getCurrency() {...} void setCurrency(String value) {...} +} + +public class AppInt { + @XmlValue + int getValue() {...} void setValue(int value) {...} +} + +public class Product { + // enable simple type substitution with base type of Object + @XmlElement(type=java.lang.Integer.class) + Object getPrice() {...} void setPrice(Object value) {...} + int getName() {...} void setName(String value) {...} +} +---- + +Unmarshalling XML document fragments from +<<a1170>> +into <<a1201>> +JAXB binding of element `product` preserves +the `xsi:type` and attributes associated with JAXB mapped class +`AmountType` is illustrated in <<a1204>>. + +.Product instances from unmarshalling XML docs from <<a1170>> +[[a1204]] +[width="100%",cols="20%,20%,20%,20%,20%",options="header",] +|=== +| document xsi:type | Product.name + +value | Product. + +price + +value | Product. + +price + +Java type | Marshal + +Product. + +price + +xsi:type +| | hotdog | 3 | Integer | +| xs:short | peanuts | 4 | Short | xs:short +| AppInt | popcorn | 5 | AppInt | AppInt +| AmountType | sushi | {value=500, + +currency=”yen”} | AmountType | AmountType +|=== + +==== Bind to a Simple Element property + +Element substitution group is an Xml Schema +mechanism that enables the substitution of one named element for +another. This section uses terms and concepts described in Section 4.6 +of [XSD Part 0] and normatively defined in Section 2.2.2.2 of [XSD Part +1]. + +The following constraints assist in defining +the Java binding that enables element substitution group: + +. Element substitution is only possible for a +reference to a global element. +.. Assuming the absence of the Xml Schema +constraints on substitution, any global element can be made the head +element of a substitution group. +. All elements in a substitution group must +derive from or have the same type definition as the head element. + +To support element substitution, for +each global element reference to a head element of a substitution group +or to an abstract element, it is necessary to generate the Element +property bindings defined in <<Element Property>>.footnote:[Element substitution +extensibility does allow element substitution(s) to be defined in a +separate schema than a global element reference occurs. When schemas are +not compiled at same time, the schema to java binding declaration, +<jaxb:property generateElementProperty=”true”/> described in +<<usage-4>> forces the generation of an +element property for a global element reference, independent of it not +belonging to a element substitution group.] This property enables the overriding +of the schema-specified element name bound to a JAXB property by setting +and getting the JAXB element representation, +`jakarta.xml.bind.JAXBElement<T>`. The name property of the `JAXBElement<T>` +instance overrides the schema specified element declaration name. +To enable the passing of any element that could be part of the element +substitution group, it is necessary to accept any JAXBElement derivation +that extends Java binding of the head element’s type definition. Using +the upper bounded wildcard notation for a generic JAXBElement container, +`JAXBElement<? extends T>`, the element property is able to get and set +any element that has an element value that is a subtype of T. Compile +time checking will not allow invalid JAXBElement derivations to be +passed to the Element property setter. When the element type is correct +but the element name is not part of the substitution group, this invalid +scenario can only be caught at runtime by validation or optional +fail-fast checking by the element property +setter.footnote:[The desire to reduce +the overall number of schema-derived classes generated by default +influenced the decision to default to binding an element declaration to +an element instance factory. A customization described in +<<globalbindings-declaration>> exists +that binds each element declaration to a Java element class so element +substitution checking can be enforced entirely by strongly typed method +signatures.] + +The schema-derived Element property getter +method is annotated, either explicitly or by default mapping +annotations, with the mapping annotation `@XmlElementRef`, specified in +Section 8.10.3, “@XmlElementRef”. The `@XmlElementRef` annotation +elements are derived in terms of the abstract model properties for the +referenced global element declaration summarized in +<<Element Declaration Schema Component>> as follows: + +.Annotate Element Property with @XmlElementRef element-value pairs +[cols="1,1",options="header",] +|=== +| @XmlElementRef element | @XmlElementRef value +| value | jakarta.xml.bind.JAXBElement.class +| namespace | referenced element declaration _{target namespace}_ +| name | referenced element declaration _{name}_ +|=== + +<<a1240>> illustrates how to +define an element substitution group and to reference the head element +of the substitution group within an Xml Schema. +<<a1242>> illustrates the Java bindings of the element substation +enabled schema. <<a1244>> +demonstrates element substitution using the JAXB API. +<<a1246>> illustrates invalid element substitution handling. + +.Xml Schema example containing an element substitution group +[[a1240]] +[source,xml,indent=4] +---- +<xs:schema targetNamespace="travel:acme" xmlns:a="travel:acme"> + + <!-- See type definition derivation hierarchy defined in CODE EXAMPLE for +complexType definitions TransportType, PlaneType, AutoType and SUV.--> + <!-- Define element substitution group. a:transport is head element. --> + <xs:element name="transport" type="a:TransportType"/> + <xs:element name="plane" type="a:PlaneType" substitutionGroup="a:transport" /> + <xs:element name="auto" type="a:AutoType" substitutionGroup="a:transport" /> + + <xs:complexType name="itinerary"> + <xs:sequence> + <!-- Global element reference. + References head element of element substitution group. --> + <xs:element ref="a:transport"/> + </xs:sequence> + </xs:complexType> +</xs:schema> +---- + +.Avoid binding of Xml Schema from <<a1240>> +[[a1242]] +[source,java,indent=4] +---- +package travel.acme; +public class ObjectFactory { + // Type Factories + TransportType createTransportType(); + AutoType createAutoType(); + PlaneType createPlaneType(); + TrainType createSUVType(); + + // Element Instance Factories + JAXBElement<AutoType> createAuto(AutoType value); + JAXBElement<PlaneType> createPlane(PlaneType value); + JAXBElement<TransportType> createTrain(TransportType value); +} + +// See Java binding of type derivation hierarchy in CODE EXAMPLE 6-5 + +public class Itinerary { + // Element substitution supported by See [Element Property] + JAXBElement<? extends TransportType> getTransport(); + void setTransport(JAXBElement<? extends TransportType> value); +} +---- + +.Element substitution using Java bindings from <<a1242>> +[[a1244]] +[source,java,indent=8,subs=+quotes] +---- +ObjectFactory of = ...; +Itinerary itinerary = of.createItinerary(); +itinerary.setTransport(of.createTransportType()); // Typical use. + +**// Element substitution:** +__// Substitute <e:auto> for schema specified <e:transport>.__ +itinerary.setTransport(of.createAuto(of.createAutoType())); + +__// Substitute <e:plane> for schema specified <e:transport>__ +itinerary.setTransport(of.createPlane(of.createPlaneType())); + +**// Combination of element and type substitution:** +__// Substitutes <e:auto xsi:type="e:SUV"> for <e:transport>__ +itinerary.setTransport(of.createAuto(of.createSUV())); +---- + +.Invalid element substitution using Java bindings from <<a1242>> +[[a1246]] +[source,xml,indent=4] +---- +<!-- Add elements not part of element substitution group. --> +<xs:element name="apple" type="xsd:string"/> +<xs:complexType name="spaceShuttle"> + <xs:extension base="a:TransportType">...</xs:complexType> +<xs:element name="spaceShuttle" type="a:spaceShuttleType"> +---- + +[source,java,indent=8,subs=+quotes] +---- +ObjectFactory of = ...; +Itinerary itinerary = of.createItinerary(); +**// Invalid element substitution** +**// compile time error: method not found** +// Element apple of type JAXBElement<String> does not match +// bounded wildcard JAXBElement<? extends TransportType>. +itinerary.setTransport(of.createApple("granny smith")); + +**// Invalid element substitution detected by validation.** +// Element spaceShuttle not part of substitution group. +// Adding _substitutionGroup="transport"_ to line 4 fixes this. +itinerary.setTranport( +of.createSpaceShuttle(of.createSpaceShuttleType())); +---- + +==== Bind to an Element Collection property + +A repeating occurrence element declaration +that is element substitutable binds solely to a JAXB Collection property +of JAXBElement. + +.Bind repeating occurrence element substitution variant of <<a1240>> +[source,xml,indent=4,subs=+quotes] +---- +<!--deleted schema that remains same --> +<xs:complexType name="itinerary"> + <xs:sequence> + **<!-- Repeating occurance to substitutable global element reference. -->** + <xs:element ref="a:transport" **maxOccurs="unbounded"** /> + </xs:sequence> +</xs:complexType> +---- + +Java Binding: +[source,java,indent=4] +---- +public class Itinerary { + List<JAXBElement<? extends TransportType>> getTransport(); +} +---- + +=== Attribute use + +A ‘required’ or ‘optional’ attribute use is +bound by default to a Java property as described in +<<Properties>>. The characteristics of the +Java property are derived in terms of the properties of the +<<Attribute Use Schema Component>> and <<Attribute Declaration Schema Component>> +as follows: + +* The _name_ of the Java property is derived +from the _{attribute declaration}_ property’s _{name}_ property using the +XML Name to Java Identifier mapping algorithm described in +<<The Name to Identifier Mapping Algorithm>>. +* A _base type_ for the Java property is +derived from the `{attribute declaration}` property’s `{type +definition}` property as described in binding of Simple Type Definition +in <<Simple Type Definition>>. If the +base type is initially a primitive type and this JAXB property is +_optional_ , the *[jaxb:globalBinding]* customization +`@optionalProperty` controls the binding of an optional primitive +property as described in <<Usage>>. +* An optional _predicate_ for the Java +property is constructed from the `{attribute declaration}` property’s +`{type definition}` property as described in the binding of simple type +definition to a Java representation. +* An optional _collection type_ for the Java +property is derived from the `{attribute declaration}` property’s +`{type definition}` property as described in the binding of simple type +definition to a Java representation. +* The _default value_ for the Java property +is the _value_ from the attribute use’s _{value constraint}_ property. If +the optional _{value constraint}_ is absent, the default value for the +Java property is the Java default value for the base type. +* The JAXB property is _optional_ when the +attribute use’s `{required}` property is `false`. + +This Java property is a member of the Java +value class that represents the binding of the complex type definition +containing the attribute use + +The JAXB property getter for this attribute +is annotated, either explicitly or via default mapping, with the mapping +annotation @XmlAttribute, specified in <<xmlattribute>>. The @XmlAttribute +element values are derived in terms of the properties of the +<<Attribute Use Schema Component>> and +<<Attribute Declaration Schema Component>> +as follows: + +.Annotate Attribute property getter method with @XmlAttribute annotation +[[a1262]] +[cols="1,1",options="header",] +|=== +| @XmlAttribute element | @XmlAttribute value +| name | attribute declaration's _{name}_ +| namespace | if attribute declaration’s _{target namespace}_ absent, +set to “” + +otherwise, set to _{target namespace}_ +| required | attribute use's _{required}_ +|=== + +[NOTE] +.Design Note +==== +Since the target namespace is not being considered when mapping +an attribute to a Java property, two distinct attributes +that have the same _{name}_ property but not the same _{target namespace}_ +will result in a Java property naming collision. +As specified generically in Section D.2.1, “Collisions and conflicts”, +the binding compiler detect this name collision between +the two distinct properties and reports the error. +The user can provide a customization that provides an alternative +Java property name to resolve this situation. + +==== + +*_Example:_* + + +Given XML Schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"> + <xs:attribute name="country" type="xs:string"/> +</xs:complexType> +---- + +Default derived Java code: +[source,java,indent=4] +---- +public class USAddress { + @XmlAttribute(name="country", targetNamespace="", required="false"); + public String getCountry() {...} + public void setCountry(String value) {...} +} +---- + +==== Bind to a Java Constant property + +Rather than binding to a read/write JAXB +property, an attribute use with a `fixed` _{value constraint}_ property +can be bound to a Java Constant property. This mapping is not performed +by default since `fixed` is only a validation constraint. The user must +set the binding declaration attribute `fixedAttributeToConstantProperty` +on `<jaxb:globalBinding>` element as specified in +<<usage>> or on`<jaxb:property>` element +as specified in <<usage-4>> to enable this +mapping. + +*_Example:_* + + +Given XML Schema fragment: +[source,xml,indent=4] +---- +<xs:annotation><xs:appinfo> + <jaxb:globalBindings fixedAttributeAsConstantProperty="true"/> +</xs:appinfo></xs:annotation> +<xs:complexType name="USAddress"> + <xs:attribute name="country" type="xs:NMTOKEN" fixed="US"/> +</xs:complexType> +---- + +If the appropriate binding schema +customization enables mapping a fixed XML value to Java constant +property, the following Java code fragment is generated. + +[source,java,indent=4] +---- +public class USAddress { + @XmlAttribute + public static final String COUNTRY="US"; + ... +} +---- + +The schema-derived constant for this fixed +attribute is annotated, either explicitly or via default mapping, with +the mapping annotation `@XmlAttribute`. The elements of `@XmlAttribute` +are set as described in <<a1262>>. + +Note that if derivation by restriction +constrains an existing attribute declaration to be fixed, this +refinement must not be bound to a constant property. The initial binding +of the attribute to a JAXB property remains the only binding of the +attribute in the Java class hierarchy. + +===== Contributions to Local Structural Constraint + +If the attribute use’s _{required}_ property +is true, the local structural constraint for an instance of the Java +value class requires that the corresponding Java property to be set when +the Java value class instance is validated. + +==== Binding an IDREF component to a Java property + +An element or attribute with a type of +`xs:IDREF` refers to the element in the instance document that has an +attribute with a type of `xs:ID` or derived from type `xs:ID` with the +same value as the `xs:IDREF` value. Rather than expose the Java +programmer to this XML Schema concept, the default binding of an +`xs:IDREF` component maps it to a Java property with a base type of +`java.lang.Object`. The caller of the property setter method must be +sure that its parameter is identifiable. An object is considered +identifiable if one of its properties is derived from an element or +attribute that is or derives from type `xs:ID`. The JAXB mapped class +must have one property annotated with an `@XmlID` program annotation as it +is specified in Section 8. There is an expectation that all instances +provided as values for properties’ representing an `xs:IDREF` should +have the Java property representing the `xs:ID` of the instances set +before the content tree containing both the `xs:ID` and `xs:IDREF` is +marshalled. If a property representing an `xs:IDREF` is set with an +object that does not have its `xs:ID` set, the `NotIdentifiableEvent` is +reported by marshalling. + +* The _name_ of the Java property is derived +from the _{name}_ property _of the attribute or element_ using the XML Name +to Java Identifier mapping algorithm described in +<<The Name to Identifier Mapping Algorithm>>. +* A _base type_ for the Java property is java.lang.Object. +* There is no _predicate_ for a property representing an `xs:IDREF`. +* An optional _collection type_ +* Default and fixed values can not be +supported for an attribute with type `xs:IDREF`. + +The schema-derived JAXB property representing +xs:IDREF(s) is annotated, either explicitly or by default mapping +annotations, with the mapping annotation @XmlIDREF, specified in Section +8. + +*_Example:_* + + +Given XML Schema fragment: +[source,xml,indent=4,subs=+quotes] +---- +<xs:complexType name="Book"> + <xs:sequence> + __<xs:element name="author" type="xs:IDREF"/>__ + <!-- ... --> + </xs:sequence> +</xs:complexType> +<xs:complexType name="AuthorBio"> + <xs:sequence> <!-- ... --> </xs:sequence> + __<xs:attribute name="name" type="xs:ID"/>__ +</xs:complexType> +---- + +Schema-derived Java value class: +[source,java,indent=4] +---- +public class Book { + @XmlIDREF + java.lang.Object getAuthor() {...} + + /** Parameter referencedObj should have an attribute or + * child element with base type of xs:ID by validation + * or marshal time. + */ + void setAuthor(java.lang.Object referencedObj) {...} +} +public class AuthorBio { + @XmlID + String getName() {...} + void setName(String value) {...} +} +---- + +Demonstration of a Java content instance +referencing another instance: + +[source,java,indent=8] +---- +Book book = ...; +AuthorBio authorBio = ...; +book.setAuthor(authorBio); +authorBio.setName("<some author’s name>"); +// The content instance root used to validate or marshal book must +// also include "authorBio" as a child element somewhere. +// A Java content instance is not included +---- + +Note that `ID` and `IDREF` mechanisms do not +incorporate type definitions that can be referenced. To generate +stronger typing for a JAXB property representing an IDREF, the schema +customization described in <<Generalize/Specialize baseType with attribute @name>> +can be used to specialize the binding. <<exidrefcust,Specialize binding of an IDREF via customization>> +illustrates the generation of stronger typing for the above example. + +=== Attribute Wildcard + +Attribute wildcard is an extensibility +feature in XML Schema. It enables an XML document author to introduce +attribute(s) to an element that were not statically associated with the +element’s complex type definition. Obviously, it is not possible to bind +such an attribute to a strongly typed JAXB property as the previous +section describes for attribute use schema component. The JAXB binding +of a complex type definition that contains an attribute wildcard, +directly or indirectly, provides dynamic access to the wildcard +attributes via the following property: +[source,java,indent=8] +---- +// Return, by reference, a mapping of +attribute QName and String. + +Map<QName, String> getOtherAttributes(); +---- +The returned attribute map provides dynamic +access to wildcard attributes associated with a complex type definition. +The key to the map is the attribute’s QName and the key’s value is the +String value of the attribute. + +The schema-derived property getter method is +annotated, either explicitly or by default mapping annotations, with the +mapping annotation `@XmlAnyAttribute`, specified in Section 8. + +The following code examples show the JAXB +binding for xs:anyAttribute and how to manipulate wildcard attributes +using this binding. + +.Bind anyAttribute to a JAXB property +[source,xml,indent=4,subs=+quotes] +---- +<xs:schema targetNamespace="http://a.org"> + <xs:complexType name="**widget**"> + <xs:anyAttribute/> + <xs:attribute name="color" type="xs:string"/> + </xs:complexType> +</xs:schema> +---- +[source,java,indent=4,subs=+quotes] +---- +package org.a; +import javax.xml.namespace.QName; +import java.util.Map; +public class **Widget** { + String getColor() {...} + void setColor(String value) {...} + @XmlAnyAttribute Map<QName, String> **getOtherAttributes** () {...} +} +---- + +.Dynamic access to wildcard attribute and attribute use +[source,java,indent=4] +---- +import jakarta.xml.bind.DatatypeConverter; +Widget w = ...; +Map attrs = w.getOtherAttributes(); + +// access schema-defined global attribute associated with +// complexType defintion widget via attribute wildcard. +QName IS_OPEN = new QName("http://example.org", "isOpen"); +boolean isOpen = DatatypeConverter.parseBoolean(attrs.get(IS_OPEN)); + +// set wildcard attribute value +attrs.put(IS_OPEN, DatatypeConverter.printBoolean(false)); + +// semantically the same results setting attribute use via +// dynamic or static setter for attribute use. +attrs.put(new QName("color"), "red"); + +// iterate over wildcard attributes +for (Map.Entry<QName,String> e: attrs.entrySet()) { +System.out.println("Attribute: " + e.getKey() + + " Value:" + e.getValue()); +} +---- + +=== Redefine + +Redefinition allows an existing XML Schema +component to be “renamed” and its new definition takes the place of the +old one. The binding of the redefined schema components, simple and +complex type definitions and model and attribute group declarations, are +described in the following subsections. + +==== Bind Redefined Simple Type Definition + +As introduced in +<<Simple Type Definition>>, a schema +component using a simple type definition typically binds to a JAXB +property. The base type, collection type and predicate of the JAXB +property are derived from the simple type definition. Thus, the redefine +of a simple type definition results in the redefinition of the simple +type definition being used to derive the base type, collection type and +predicate of the JAXB property. + +The one exception to this binding is that a +simple type definition with enum facets is sometimes bound to an enum +type. A redefined simple type definition that binds to an enum type, as +described in <<Enum Type>>, is not bound +to a Java representation, only the redefinition is bound to an enum +type. + +==== Bind Redefined Complex Type Definition + +A redefinition of a type definition must use +the original type definition as its base type definition. The redefined +complex type definition is bound to a Java value class or interface name +that prepends “_” to the class name. The redefinition complex type +definition is bound to a class that extends the JAXB class that +represents the redefined complex type definition. + +.Binding of a redefined complex type definition +[source,xml,indent=4] +---- +File: v1.xsd: +<!-- Extracted from Section 4.2.2 of [XSD1] --> +<xs:complexType name="personName"> + <xs:sequence> + <xs:element name="title" type="xs:string" minOccurs="0"/> + <xs:element name="forename" type="xs:string" + minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> +</xs:complexType> + +File: v2.xsd: +<xs:redefine schemaLocation="v1.xsd"> + <xs:complexType name="personName"> + <xs:complexContent> + <xs:extension base="personName"> + <xs:sequence> + <xs:element name="generation" minOccurs="0"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> +</xs:redefine> +---- +Java binding: +[source,java,indent=4] +---- +// binding of file v1.xsd complex type definition for personName +@XmlType(name="_PersonName") +public class _PersonName { + void setTitle(String value); String getTitle(); + List<String> getForename(); +} +// binding of v2.xsd redefinition for complex type personName +@XmlType(name="PersonName") +public class PersonName extends _PersonName { + void setGeneration(Object value); Object getGeneration(); +} +---- + +==== Bind Redefined Group Definition + +The attribute or model group redefinition is +used instead of the initial group definition to construct the property +set of the content model(s) that reference the redefined attribute or +model group definition. The construction of a property set is described +in <<Java value class>>. + +Since there is no binding of an attribute or +model group definition to a Java representation, no other special case +handling is required for this binding. + +=== Identity Constraint + +An identity constraint does not represent any +data, it represents a constraint that is enforced by validation. These +constraints can be checked by optional validation that can be enabled at +either unmarshal and/or marshal time. + +=== Content Model - Particle, Model Group, Wildcard + +This section describes the possible Java +bindings for the content model of a complex type definition schema +component with a _{content type}_ property of `mixed` or `element-only`. +The possible element content(s) and the valid ordering between those +contents are constrained by the _{particles}_ describing the complex type +definition’s content model. The Java binding of a content model is +realized by the derivation of one or more content-properties to +represent the element content constrained by the model group. Section +6.12.1 through 6.12.7 describes the _element binding_ of a content +model. + +==== Element binding style + +The ideal Java binding would be to map each +uniquely named element declaration occurring within a content model to a +single JAXB property. The model group schema component constraint, +element declarations consistent, specified in [XSD-Part 1] ensures that +all element declarations/references having the same {target namespace} +and {name} must have the same top-level type definition. This model +allows the JAXB technology user to specify only the content and the JAXB +implementation infers the valid ordering between the element content +based on the _{particles}_ constraints in the source schema. + +However, there do exist numerous scenarios that this ideal binding is not +possible for parts of the content model or potentially the entire +content model. For these cases, default binding has a fallback position +of representing the element content and the ordering between the content +using a _general content model_. The scenarios where one must fallback +to the general content model will be identified later in this +subsection. + +==== Bind each element declaration name to a JAXB property + +This approach relies on the fact that a model +group merely provide constraints on the ordering between children +elements and the user merely wishes to provide the content. It is +easiest to introduce this concept without allowing for repeating +occurrences of model groups within a content model. Conceptually, this +approach presents all element declarations within a content model as a +set of element declaration __{name}__’s. Each one of the __{name}__’s is +mapped to a content-property. Based on the element content that is set +by the JAXB application via setting content-properties, the JAXB +implementation can compute the order between the element content using +the following methods. + +Computing the ordering between element +content within *[children]* of an element information item + +* Schema constrained fixed ordering or +semantically insignificant ordering ++ +The sequence in the schema represents an +ordering between children elements that is completely fixed by the +schema. Schema-constrained ordering is not exposed to the Java +programmer when mapping each element in the sequence to a Java property. +However, it is necessary for the marshal/unmarshal process to know the +ordering. No new ordering constraints between children elements can be +introduced by an XML document or Java application for this case. +Additionally, the Java application does not need to know the ordering +between children elements. When the compositor is `all`, the ordering +between element content is not specified semantically and any ordering +is okay. So this additional case can be handled the same way. + +* Schema only constrains content and does not +significantly constrain ordering ++ +If the ordering between the children elements +is significant and must be accessible to the Java application, then the +ordering is naturally preserved in Java representation via a collection. +Below are examples where schema provides very little help in +constraining order based on content. ++ +-- +[source,xml,indent=4] +---- +<xs:choice maxOccurs="unbounded"> ... </xs:choice> +<xs:sequence maxOccurs="unbounded"> ... </xs:sequence> +---- +-- + +==== General content property + +A general content property is, as its name +implies, the most general of all content properties. Such a property can +be used with any content specification, no matter how complex. A general +content property is represented as a List property as introduced in +<<List Property>>. Unlike the prior +approach where the JAXB implementation must infer ordering between the +element content, this approach always requires the JAXB technology user +to specify a valid ordering of element and text content. This approach +has the benefit of providing the application with more control over +setting and knowing the order between element content. + +A general content property is capable of +representing both element information items and character data items +occurring within *[children]* of an element information item. Character +data is inserted into the list as java.lang.String values. Element data +is added to the list as instances of JAXB element. To support wildcard +content occurring as part of a general content property, xml data +content with no static Java binding is added and accessed from the list +as instances of `org.w3c.org.dom.Node`. + +The schema-derived Collection property getter +method is annotated, either explicitly or by default mapping +annotations, with the mapping annotations reflecting what content is +within the Collection. + +* If the content model is mixed, the property +is annotated as `@XmlMixed`. See <<Bind mixed content>> for details. +* <<Collection of Element types>> describes an optimized binding of a collection of +element values, instead of a collection of JAXB elements annotated with +`@XmlElementRefs(@XmlElementRef, ...)`. +* If optimized binding can not be used, each +element in the content model is represented by an `@XmlElementRef`, +described in <<Bind to a Simple Element property>>. +If there is more than one element annotations needed, they +must occur as elements in the map annotation `@XmlElementRefs` specified +in Section 8.10.3, “@XmlElementRef”. + +===== Collection of Element types + +If the content model for a general content +property meets all of the following constraints, the collection can be +optimized to be a list of value classes instead of a list of JAXB +elements. + +* If the content model is not mixed and does not contain a wildcard. +* If none of the element declarations in the +content model are abstract or the head of an element substitution group. +* If none of the element declarations in the +content model have a xml datatype that is or derives from xs:list or +xs:IDREF. +* For all element declarations in the content +model, there does not exist two distinct element declarations whose +types bind to the same Java datatype. +* If not more than one element declaration in +the content model is nillable. + +Such a collection is annotated with `@XmlElements` annotation, +specified in Section 8, that contains a +`@XmlElement` annotation for each unique Java datatype within the +collection. The `@XmlElement` annotation associates an element name with +each unique Java datatype in the collection + +===== Examples + +*_Example 1:_ Complex content model of Elements with primitive types* + +[source,xml,indent=4] +---- +<xs:complexType name="Base"> + <xs:choice maxOccurs="unbounded"> + <xs:element name="A" type="xs:string"/> + <xs:element name="B" type="xs:string"/> + <xs:element name="C" type="xs:int"/> + </xs:choice> +</xs:complexType> +---- +[source,java,indent=4] +---- +public class ObjectFactory \{ + // Element instance factories. + JAXBElement<String> createBaseA(String value) {...} + JAXBElement<String> createBaseB(String value) {...} + JAXBElement<Integer> createBaseC(Integer value) {...} + // Type factories + Base createBase() {...} +} + +public class Base { + /** + * A general content list that can contain + * element instances representing A, B and/or C. + */ + @XmlElementRefs({ + @XmlElementRef(name="A", value=JAXBElement.class), + @XmlElementRef(name="B", value=JAXBElement.class), + @XmlElementRef(name="C", value=JAXBElement.class)}) + List<JAXBElement> getAOrBOrC()\{...} +} +---- + +*_Example 2:_ Optimized Binding to a Collection of Element Types* + +XML Schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="AType"/> +<xs:complexType name="BType"/> +<xs:complexType name="FooBar"> + <xs:choice maxOccurs="unbounded"> + <xs:element name="foo" type="AType"/> + <xs:element name="bar" type="BType"/> + </xs:choice> +</xs:complexType> +---- + +Default derived Java code: +[source,java,indent=4] +---- +public class AType {...} +public class BType {...} + +class ObjectFactory { + // element instance factories only + JAXBElement<AType> createFooBarFoo(AType value); + JAXBElement<BType> createFooBarBar(BType value); +} + +public class FooBar { + /** Collection of element types: AType and BType. */ + @XmlElements({ + @XmlElement(value=AType.class, name="Foo"), + @XmlElement(value=BType.class, name="Bar")}) + List<Object> getFooOrBar() {...} +}; +---- + +==== Bind mixed content + +When a complex type definition’s _{content type}_ +is “mixed,” its character and element information content is +bound to general content list as described in +<<General content property>>. Character +information data is inserted as instances of `java.lang.String` into a +JAXB collection property. + +The schema-derived Collection property getter +method is annotated, either explicitly or by default mapping +annotations, with the mapping annotation `@XmlMixed`, specified in +Section 8. + +*_Example:_* + + +Schema fragment loosely derived from mixed +content example from [XSD Part 0]. +[source,xml,indent=4] +---- +<xs:element name="letterBody"> + <xs:complexType mixed="true"> + <xs:sequence> + <xs:element name="name" type="xs:string"/> + <xs:element name="quantity" type="xs:positiveInteger"/> + <xs:element name="productName" type="xs:string"/> + <!-- etc. --> + </xs:sequence> + </xs:complexType> +</xs:element> +---- + +Derived Java code: +[source,java,indent=4] +---- +import java.math.BigInteger; +class ObjectFactory { + // element instance factories only + JAXBElement<LetterBody> createLetterBody(LetterBody value); + JAXBElement<String> createLetterBodyName(String value); + JAXBElement<BigInteger> createLetterBodyQuantity(BigInteger value); + JAXBElement<String> createLetterBodyProductName(String value); +} + +public class LetterBody implements JAXBElement<LetterBody> { + /** Mixed content can contain instances of Element classes + Name, Quantity and ProductName. Text data is represented as + java.util.String for text. */ + @XmlMixed + @XmlElementRefs( { + @XmlElementRef(name="productName", type=JAXBElement.class), + @XmlElementRef(name="quantity", type=JAXBElement.class), + @XmlElementRef(name="name", type=JAXBElement.class)}) + List getContent() {...} +} +---- + +The following instance document +[source,xml,indent=4] +---- +<letterBody> +Dear Mr.<name>Robert Smith</name> +Your order of <quantity>1</quantity> <productName>Baby +Monitor</productName> shipped from our warehouse. .... +</letterBody> +---- + +could be constructed using JAXB API. +[source,java,indent=4] +---- +LetterBody lb = ObjectFactory.createLetterBody(null); +List gcl = lb.getContent(); +gcl.add("Dear Mr."); +gcl.add(ObjectFactory.createLetterBodyName("Robert Smith")); +gcl.add("Your order of "); +gcl.add(ObjectFactory. + createLetterBodyQuantity(new BigInteger("1"))); +gcl.add(ObjectFactory.createLetterBodyProductName("Baby Monitor")); +gcl.add("shipped from our warehouse"); +---- + +Note that if any element instance is placed +into the general content list, _gcl_, that is not an instance of +`LetterBody.Name`, `LetterBody.Quantity` or `LetterBody.ProductName`, +validation would detect the invalid content model. With the fail fast +customization enabled, element instances of the wrong type are detected +when being added to the general content list, _gcl_. + +==== Bind wildcard schema component + +A wildcard is mapped to a simple content-property with: + +* Content-property name set to the constant “`any`”. +A binding schema customization could provide a more +semantically meaningful content-property name. +* Content-property _base type_ set to +`java.lang.Object` by default. +Wildcard content is represented as one of the +following: +.. JAXB element + +Either an instance of `jakarta.xml.bind.JAXBElement<T>` or a JAXB class +annotated with `@XmlRootElement`. + +Corresponds to a recognized global element tag name registered with +the instance `jakarta.xml.bind.JAXBContext`, meaning the schema(s) +describing the element content is registered with the _JAXBContext_ +instance, see <<JAXBContext>> on how +bindings are registered with a `JAXBContext` instance., +.. instance of `jakarta.xml.bind.JAXBElement`. + +Corresponds to an unknown element name but a recognized type +definition specified by *_@xsi:type_* on the element. JAXBElement +_declaredType_ is set to `java.lang.Object` since the unknown element +declaration’s default type is `xs:anyType`. +.. element node instance of a supported xml infoset API. + +Necessary to represent Xml data content that does not have a schema +defined element or type definition. Such content is allowed by element +*xs:any* with attribute *@processContents="lax"* or "`*skip*`". +* See content-property predicate for a wildcard. +* If the `maxOccurs` is greater than one, the +content property is mapped to a collection property. The default +collection property is a List property of base type java.lang.Object. +* There is no _default value_. + +Since the schema does not contain any +information about the element content of a wildcard content, even the +content-property, by default, can not infer an XML element tag for +wildcard element content. + +The schema-derived property getter method for +representing wildcard content is annotated, either explicitly or by +default mapping annotations, with the mapping annotation +`@XmlAnyElement`, specified in Section 8. The @XmlAnyElement annotation +element values are derived in terms of the abstract model properties for +wildcard summarized in <<Wildcard Schema Component>> as follows: + +.Annotate JAXB property with @XmlAnyElement element-value pairs +[cols="1,1",options="header"] +|=== +| @XmlAnyElement element | @XmlAnyElement element value +| lax | If wildcard schema component’s _{process contents}_ is `lax` or `strict_`, + +set `@XmlAnyElement.lax()` to `true`. + + + +else if _{process contents}_ is `skip`, set `@XmlAnyElement.lax()` to `false`. +| value | `jakarta.xml.bind.annotation.W3CDomHandler.class` +|=== + +==== Bind a repeating occurrence model group + +A choice or sequence model group, containing +more than one member, with a repeating occurrence, `maxOccurs` attribute +greater than one, is bound to a general content property in the +following manner: + +* Content-property _name_ is derived in following ways: +** If a named model group definition is being +referenced, the value of its _{name}_ property is mapped to a Java +identifier for a method using the algorithm specified in +<<The Name to Identifier Mapping Algorithm>>. +** To derive a content property _name_ for +unnamed model group, see <<Deriving an identifier for a model group>>. +* Content-property _base type_ set to +`java.lang.Object`. A binding schema customization could provide a more +specialized java class. +* Content-property _predicate_ validates the +order between element instances in the list and whether the occurrence +constraints for each element instance type is valid according to the +schema. +* Since the `maxOccurs` is always greater +than one, the content property is mapped to a collection property. The +default collection property is a List property. +* There is no _default value_. + +The schema-derived collection property is +annotated as specified in <<General content property>> +and <<Collection of Element types>>. + +*_Local structural Constraints_* + +The list content property’s value must +satisfy the content specification of the model group. The ordering and +element contents must satisfy the constraints specified by the model +group. + +==== Content Model Default Binding + +The following rules define _element_ binding +style for a complex type definition’s content model. + +. If _{content type}_ is mixed, bind the +entire content model to a general content property with the +content-property name `"content"`. See +<<Bind mixed content>> for more details. +. If (1) a particle has _{max occurs}_ >1 and +(2) its _{term}_ is a model group and (3) all the particles in the model +group have \{terms} that bind to different Java datatypes, bind to a +collection of element types. See complete list of constraints required +to perform this optimized binding in <<Collection of Element types>>. +. If (1) a particle has _{max occurs}_ >1 and +(2) its _{term}_ is a model group, then that particle and its descendants +are mapped to one general content property that represents them. See +<<Bind a repeating occurrence model group>> for details. +. Process all the remaining particles (1) +whose _{term}_ are wildcard particles and (2) that did not belong to a +repeating occurrence model group bound in step 2. If there is only one +wildcard, bind it as specified in <<Bind wildcard schema component>>. +If there is more than one, then fallback to +representing the entire content model as a single general content +property. See <<General content property>>. +. Process all particles (1) whose _{term}_ are +element declarations and (2) that do not belong to a repeating +occurrence model group bound in step 2. ++ +First, we say a particle has a label _L_ if it +refers to an element declaration whose _{name}_ is _L_. Then, for all the +possible pair of particles _P_ and _P’_ in this set, if the following +constraints are not met: ++ +-- +.. If _P_ and _P’_ have the same label, then they +must refer to the same element declaration. +.. If _P_ and _P’_ refer to the same element +reference, then its closest common ancestor particle may not have +sequence as its _{term}_. +-- ++ +If either of the above constraints are +violated, it is not possible to map each element declaration to a unique +content property. Fallback to representing the entire content model as a +single general content property. + ++ +Otherwise, create a content property for each +label _L_ as follows: + +* The content property _name_ is derived from label name _L_. +* The _base type_ will be the Java type to +which the referenced element declaration maps. +* The content property _predicate_ reflects the +occurrence constraint. +* The content property _collection type_ +defaults to `‘list’` if there exist a particle with label _L_ that has +_{maxOccurs}_ > 1. +* For the default value, if all particles +with label _L_ has a _{term}_ with the same _{value constraint}_ default or +fixed value, then this value. Otherwise none. + +Below is an example demonstrating of not +meeting the uniqueness constraints of 5(a) and 5(b) specified above. + +[source,xml,indent=4] +---- +<xs:sequence> + <xs:choice> + <xs:element ref="ns1:bar"/> (A) + <xs:element ref="ns2:bar"/> (B) + </xs:choice> + <xs:element ref="ns1:bar"/> (C) +</xs:sequence> +---- + +The pair _(A,B)_ violates the first clause +because they both have the label “bar” but they refer to different +element declarations. The pair _(A,C)_ violates the second clause because +their nearest common ancestor particle is the outermost `<sequence>`. +This model group fragment is bound to a general content property. + +===== Default binding of content model “derived by extension” + +If a content-property naming collision occurs +between a content-property that exists in an base complex type +definition and a content-property introduced by a “derive by extension” +derived complex type definition, the content-properties from the +colliding property on are represented by a general content property with +the default property name `rest`. + +*_Example:_* derivation by extension content model with a content-property collision. + +Given XML Schema fragment: +[source,xml,indent=4] +---- +<xs:complexType name="Base"> + <xs:sequence> + <xs:element name="A" type="xs:int"/> + <xs:element name="B" type="xs:int"/> + </xs:sequence> +</xs:complexType> + +<xs:complexType name="Derived"> + <xs:complexContent> + <xs:extension base="Base"> + <xs:sequence> + <xs:element name="A" type="xs:int"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> +</xs:complexType> +---- + +Default binding derived Java codefootnote:[Specifying a +customization of the local element declaration A within Derived complex +type to a different property name than A would avoid the fallback +position for this case.]: +[source,java,indent=4] +---- +public class Base { + int getA() {...} void setA(int) {...} + int getB() {...} void setB(int) {...} +} + +public class Derived extends Base { + /** + * Instances of Derived.A must be placed in this general + * content propert that represents the rest of the content + * model. */ + List getRest() {...} +} + +class ObjectFactory { + // element instance factories only + JAXBElement<Integer> createDerivedA(Integer value) {...} +} +---- + +===== Bind single occurrence choice group to a choice content property + +Setting the `choiceContentProperty` attribute +of `<jaxb:globalBindings>` as specified in +<<Usage>> enables this customized binding +option. + +A non-repeating choice model group is bound +to a simple property. The simple choice content property is derived from +a choice model group as follows: + +* The choice content property name is either +the referenced model group definition _{name}_ or obtained using the +algorithm specified in <<Deriving an identifier for a model group>>. +* The choice content property `base type` is +the first common supertype of all items within the choice model group, +with `java.lang.Object` always being a common root for all Java +objects.footnote:[Note that primitive +Java types must be represented by their Java wrapper classes when base +type is used in the choice content property method signatures. Also, all +sequence descendants of the choice are treated as either a general +content property or are mapped to their own value class.] +* The predicate +* The collection type defaults to List if one +or more items in the choice model group bind to List. +* No default value. + +A choice property consists of the following +methods: + +* The `getChoiceID` method returns the set +value. If the property has no set value then the value `null` is +returned. Note that a set value of a primitive Java type is returned as +an instance of the corresponding Java wrapper class. +* The `setChoiceID` method has a single +parameter that is the type of the choice content property `base type`. + +The `globalBindings` and property +customization attribute, `choiceContentProperty`, enables this +customized binding. The customization is specified in +<<globalbindings-declaration>>. + +*_Example:_* + + +XML Schema representation of a choice model group. +[source,xml,indent=4] +---- +<xs:choice> + <xs:element name="foo" type="xs:int"/> + <xs:element name="bar" type="xs:string"/> +</xs:choice> +---- + +Derived choice content property method +signatures: +[source,java,indent=8] +---- +void setFooOrBar(Object) {...} +Object getFooOrBar() {...} +---- + +=== Modifying Schema-Derived Code + +There exist a number of use cases on why a +developer would find it beneficial to modify schema-derived classes. +Here are some of those use cases. + +* Add functionality to schema-derived +classes. + +Since schema-derived classes are derived from a data description +language, the derived classes only represent data and have no +object-level functionality. +* Add polymorphic methods to Java class hierarchy generated +from XML Schema type definition derivation hierarchy. +* Initialize a JAXB property or field +representing an XML element with a default value. Regretfully, XML +Schema element defaulting is insufficient to accomplish this. Note that +XML Schema attribute defaulting is sufficient and does not require this +approach. + +The JAXB schema-derived class was +designed to be easily understandable and modifiable by a developer. For +many development environments, it is not sufficient to only run the +schema compiler once due to modification of the schema-derived classes. +Since schemas evolve over time, it is desirable to have the ability to +regenerate schema-derived classes from an updated schema while +preserving modification made by a developer. Given the complexities of +supporting this capability, a JAXB implementation is not required to +support regeneration from a schema into previously modified +schema-derived classes. External tools, such as an IDE, could assist in +supporting the sophisticated task of regeneration of a modified +schema-derived class in the future. To enable tools to support +regeneration, a JAXB implementation is required to have an option for +generating an annotation that enables a portable means for +distinguishing between developer code and generated code in a +schema-derived class.The next section describes the portable format for +distinguishing between generated and developer added/modified methods +and/or fields in a schema-derived class. + +==== Distinguish between generated and user added code + +A schema compiler must have an option to +generate the Jakarta Annotation, `@jakarta.annotation.Generated` +annotation, specified in [CA], on every generated class, method and +field. If a developer does modify an `@Generated` annotated method or +field, they must denote this modification by deleting the `@Generated` +annotation. If a developer adds a new method or field, it will not have +an `@Generated` annotation on it. Based on these conventions, a JAXB +implementation in conjunction with an IDE or other external tool, would +be able to support regeneration of schema-derived code while preserving +developer additions/modifications to methods and fields in a +schema-derived class. + +When schema compiler option to generate +`@Generated` annotation is selected, the table describes the annotation +to be generated. + +.Annotate generated class, field and property with @Generated element-value pairs +[cols="1,1",options="header"] +|=== +| @Generated element | @Generated element value +| value | fully qualified class name of schema compiler +| date | date of generation of schema-derived class. +Value must follow the ISO 8601 standard. +| comment | optional. Is implementation specific. +|=== + +=== Default Binding Rule Summary + +Note that this summary is non-normative and +all default binding rules specified previously in the chapter take +precedence over this summary. + +* Bind the following to Java package: +** XML Namespace URI +* Bind the following XML Schema components to Java value class: +** Named complex type +* Bind to typesafe enum class: +** A named simple type definition with a +basetype that derives from `"xs:NCName"` and has enumeration facets. +* Bind the following XML Schema components to +an element instance factory that returns `jakarta.xml.bind.JAXBElement<T>` +** A global element declaration with a named type definition. +** Local element declaration with a named type +definition that can be inserted into a general content list. +* Bind the following XML Schema components to a Java Element class +** A global element declaration with anonymous +type definition to a Java value class. +** Local element declaration with anonymous +type definition that can be inserted into a general content list. +* Bind to Java property +** Attribute use +** Particle with a term that is an element reference or local element declaration. ++ +Additionally, generate an element property +for an element reference to the head element of a substitution group. +* Bind to JAXB property: + +`getOtherAttributes(): java.util.Map<QName, String>` +** Attribute Wildcard occurring directly or +indirectly via an attribute group reference in a complex type +definition. +* Bind model group and wildcard content with +a repeating occurrence and complex type definitions with `mixed` +_{content type}_ to: +** A general content property - a List +content-property that holds Java instances representing element +information items and character data items. To support dynamic Xml +content that validates against xs:any processContents=”lax” or “skip”, +allow instances of org.w3c.dom.Node into the list. + +.Summarize default XSD to Java binding for Figure 5.1 and Figure 5.2 +[[table614]] +[cols="1,1",options="header"] +|=== +| XML Schema | Java Representation +| Schema targetNamespace | Package +| Global Element Declaration with named type definition | ObjectFactory.elementInstanceFactory method returning JAXBElement<T> +Value must follow the ISO 8601 standard. +| Global Complex Type Definition (Named) | value class/class + ObjectFactory.typeInstanceFactory method +a| Global Simple Type Definition + +* derive base of string +* has @enum facet(s) | enum type +| SimpleType facets | ConstraintPredicate +a| Attribute Uses + +Local Element Declaration | Property +a| facet *@maxOccurs > 1* xsd:list | PropertyStyle List +a| **@fixed**PropertyStyle | Constant +| Global Element Declaration with anonymous type definition | value class for anonymous type + ObjectFactory.typeInstanceFactory + ObjectFactory.elementInstanceFactory method +| Element reference to SubstitutionGroup Head maxOccurs = “1” | Simple + Element property +| Element reference to SubstitutionGroup Head maxOccurs > “1” | List<JAXBElement<T>> +|=== +
diff --git a/spec/src/main/asciidoc/ch07-customize_xml_schema.adoc b/spec/src/main/asciidoc/ch07-customize_xml_schema.adoc new file mode 100644 index 0000000..42fa8a1 --- /dev/null +++ b/spec/src/main/asciidoc/ch07-customize_xml_schema.adoc
@@ -0,0 +1,2836 @@ +// +// Copyright (c) 2020, 2024 Contributors to the Eclipse Foundation +// + +== Customizing XML Schema to Java Representation Binding + +The default binding of source schema +components to derived Java representation by a binding compiler +sometimes may not meet the requirements of a JAXB application. In such +cases, the default binding can be customized using a __binding declaration__. +Binding declarations are specified by a __binding language__, +the syntax and semantics of which are defined in this chapter. + +All JAXB implementations are required to +provide customization support specified here unless explicitly stated as +optional. + +=== Binding Language + +The binding language is an XML based language +which defines constructs referred to as __binding declarations__. A binding +declaration can be used to customize the default binding between an XML +schema component and its Java representation. + +The schema for binding declarations is defined in the namespace +`https://jakarta.ee/xml/ns/jaxb`. This specification uses the +namespace prefix `"jaxb"` to refer to the namespace of binding +declarations. For example, + +[source,xml,indent=4] +---- +<jaxb: binding declaration> +---- + +A binding compiler interprets the binding +declaration relative to the source schema and a set of default bindings +for that schema. Therefore a source schema need not contain a binding +declarations for every schema component. This makes the job of a JAXB +application developer easier. + +There are two ways to associate a binding +declaration with a schema element: + +* as part of the source schema (_inline +annotated schema_) +* external to the source schema in an +_external binding declaration_. + +The syntax and semantics of the binding +declaration is the same regardless of which of the above two methods is +used for customization. + +A binding declaration itself does not +identify the schema component to which it applies. A schema component +can be identified in several ways: + +* explicitly - e.g. QName, XPath expressions +etc. +* implicitly - based on the context in which +the declaration occurs. + +It is this separation which allows the +binding declaration syntax to be shared between inline annotated schema +and the external binding. + +==== Extending the Binding Language + +In recognition that there will exist a need +for additional binding declarations than those currently specified in +this specification, a formal mechanism is introduced so all JAXB +processors are able to identify _extension binding declarations_ . An +extension binding declaration is not specified in the _jaxb:_ namespace, +is implementation specific and its use will impact portability. +Therefore, binding customization that must be portable between JAXB +implementations should not rely on particular customization extensions +being available. + +The namespaces containing extension binding +declarations are specified to a JAXB processor by the occurrence of the +global attribute `<jaxb:extensionBindingPrefixes>` within an instance of +`<xs:schema>` element. The value of this attribute is a +whitespace-separated list of namespace prefixes. The namespace bound to +each of the prefixes is designated as a customization declaration +namespace. Prefixes are resolved on the `<xs:schema>` element that +carries this attribute. It is an error if the prefix fails to resolve. +This feature is quite similar to the extension-element-prefixes +attribute in [XSLT 1.0] `http://www.w3.org/TR/xslt10/#extension`, +introduces extension namespaces for extension instructions and functions +for XSLT 1.0. + +This specification does not define any +mechanism for creating or processing extension binding declarations and +does not require that implementations support any such mechanism. Such +mechanisms, if they exist, are implementation-defined. + +==== Inline Annotated Schema + +This method of customization utilizes on the +`<appinfo>` element specified by the XML Schema [XSD PART 1]. A binding +declaration is embedded within the `<appinfo>` element as illustrated +below. + +[source,xml,indent=4] +---- +<xs:annotation> + <xs:appinfo> + <binding declaration> + </xs:appinfo> +</xs:annotation> +---- + +The inline annotation where the binding +declaration is used identifies the schema component. + +==== External Binding Declaration + +The external binding declaration format +enables customized binding without requiring modification of the source +schema. Unlike inline annotation, the remote schema component to which +the binding declaration applies must be identified explicitly. The +`<jaxb:bindings>` element enables the specification of a remote schema +context to associate its binding declaration(s) with. Minimally, an +external binding declaration follows the following format. + +[source,xml,indent=4] +---- +<jaxb:bindings [schemaLocation = "xs:anyURI"]> + <jaxb:bindings [node = "xs:string"]> + <binding declaration> + <jaxb:bindings> +</jaxb:bindings> +---- + +The schemaLocation attribute is optional for +specifying `<jaxb:globalBindings>`, and the _node_ attribute is optional +for specifying `<jaxb:schemaBindings>`. The attributes _schemaLocation_ +and _node_ are used to construct a reference to a node in a remote +schema. The binding declaration is applied to this node by the binding +compiler as if the binding declaration was embedded in the node’s +`<xs:appinfo>` element. The attribute values are interpreted as follows: + +* _schemaLocation -_ It is a URI reference +to a remote schema. +* _node_ - It is an XPath 1.0 expression +that identifies the schema node within schemaLocation to associate +binding declarations with. + +An example external binding declaration can +be found in <<example>>. + +===== Restrictions + +* The external binding element +`<jaxb:bindings>` is only recognized for processing by a JAXB processor +when its parent is an `<xs:appinfo>` element, it is an ancestor of +another `<jaxb:bindings>` element, or when it is root element of a +document. An XML document that has a `<jaxb:bindings>` element as its +root is referred to as an external binding declaration file. +* The top-most `<jaxb:binding>` element +within an `<xs:appinfo>` element or the root element of an external +binding file must have its _schemaLocation_ attribute set. + +==== Version Attribute + +The normative binding schema specifies a +global `version` attribute. It is used to identify the version of the +binding declarations. For example, a future version of this +specification may use the version attribute to specify backward +compatibility. To indicate this version of the specification, the +`version should` be `"3.0"`. +If any other version is specified, it must result in an invalid +customization as specified in <<Invalid Customizations>>. + +The `version` attribute must be specified in +one of the following ways: + +* If customizations are specified in inline +annotations, the `version` attribute must be specified in `<xs:schema>` +element of the source schema. For example, ++ +[source,xml,indent=4] +---- + <xs:schema jaxb:version="3.0"> +---- + +* If customizations are specified in an +external binding file, then the `jaxb:version` attribute must be +specified in the root element `<jaxb:bindings>` in the external binding +file. Alternately, a local `version` attribute may be used. Thus the +version can be specified either as ++ +[source,xml,indent=4] +---- + <jaxb:bindings version="3.0" ... /> +---- +or ++ +[source,xml,indent=4] +---- + <jaxb:bindings jaxb:version="3.0" ... /> +---- ++ +Specification of both `version` and +`<jaxb:version>` must result in an invalid customization as specified in +<<Invalid Customizations>>. + +==== Invalid Customizations + +A _non conforming_ binding declaration is a +binding declaration in the `jaxb` namespace but does not conform to this +specification. A non conforming binding declaration results in a +_customization error_. The binding compiler must report the customization +error. The exact error is not specified here. For additional +requirements see <<Compatibility>>. + +The rest of this chapter assumes that non +conforming binding declarations are processed as indicated above and +their semantics are not explicitly specified in the descriptions of +individual binding declarations. + +=== Notation + +The source and binding-schema fragments shown +in this chapter are meant to be illustrative rather than normative. The +normative syntax for the binding language is specified in +<<Normative Binding Schema Syntax>> in +addition to the other normative text within this chapter. All examples +are non-normative. + +* Metavariables are in _italics_. +* Optional attributes are enclosed in `[ square="bracket" ]`. +* Optional elements are enclosed in `[ <elementA> ... </elementA> ]`. +* Other symbols: ‘`,`’ denotes a sequence, +‘`|`’ denotes a choice, ‘`+`’ denotes one or more, ‘`*`’ denotes +zero or more. +* The prefix `xs:` is used to refer to schema +components in W3C XML Schema namespace. +* In examples, the binding declarations as +well as the customized code are shown in bold like this: +*<appinfo> <annotation>* or *getAddress()*. + +=== Naming Conventions + +The naming convention for XML names in the +binding language schema are: + +* The first letter of the first word in a +multi word name is in lower case. +* The first letter of every word except the +first one is in upper case. + +For example, the XML name for the Java +property basetype is baseType. + +=== Customization Overview + +A binding declaration customizes the default +binding of a schema element to a Java representation. The binding +declaration defines one or more customization values each of which +customizes a part of Java representation. + +==== Scope + +When a customization value is defined in a +binding declaration, it is associated with a _scope_. A scope of a +customization value is the set of schema elements to which it applies. +If a customization value applies to a schema element, then the schema +element is said to be _covered_ by the scope of the customization value. +The scopes are: + +* *global scope*: A customization value defined +in `<globalBindings>` has _global scope_. A global scope covers all the +schema elements in the source schema and (recursively) any schemas that +are included or imported by the source schema. +* *schema scope*: A customization value defined +in `<schemaBindings>` has _schema scope_. A schema scope covers all the +schema elements in the target namespace of a schema. +* *definition scope*: A customization value in +binding declarations of a type definition or global declaration has +_definition scope_. A definition scope covers all schema elements that +reference the type definition or the global declaration. This is more +precisely specified in the context of binding declarations later on in +this chapter. +* *component scope*: A customization value in a +binding declaration has _component scope_ if the customization value +applies only to the schema element that was annotated with the binding +declaration. + +.Scoping Inheritance and Overriding For Binding Declarations +image::xmlb-18.svg[image] + +The different scopes form a taxonomy. The +taxonomy defines both the inheritance and overriding semantics of +customization values. A customization value defined in one scope is +inherited for use in a binding declaration covered by another scope as +shown by the following inheritance hierarchy: + +* a schema element in schema scope inherits a +customization value defined in global scope. +* a schema element in definition scope +inherits a customization value defined in schema or global scope. +* a schema element in component scope +inherits a customization value defined in definition, schema or global +scope. + +Likewise, a customization value defined in +one scope can override a customization value inherited from another +scope as shown below: + +* value in schema scope overrides a value +inherited from global scope. +* value in definition scope overrides a value +inherited from schema scope or global scope. +* value in component scope overrides a value +inherited from definition, schema or global scope. + +==== XML Schema Parsing + +Chapter 5 specified the bindings using the +abstract schema model. Customization, on the other hand, is specified in +terms of XML syntax not abstract schema model. The XML Schema +specification [XSD PART 1] specifies the parsing of schema elements into +abstract schema components. This parsing is assumed for parsing of +annotation elements specified here. In some cases, [XSD PART 1] is +ambiguous with respect to the specification of annotation elements. +<<Annotation Restrictions>> outlines how +these are addressed. + +[NOTE] +.Design Note +==== +The reason for specifying using the XML syntax instead of +abstract schema model is as follows. For most part, +there is a one-to-one mapping between schema elements +and the abstract schema components to which they are bound. +However, there are certain exceptions: local attributes and particles. +A local attribute is mapped to two schema components: +{attribute declaration} and {attribute use}. But the XML parsing +process associates the annotation with the {attribute declaration} +not the {attribute use}. This is tricky and not obvious. +Hence for ease of understanding, a choice was made to specify +customization at the surface syntax level instead. + +==== + + +=== `<globalBindings>` Declaration + +The customization values in `"<globalBindings>"` +binding declaration have global scope. This binding +declaration is therefore useful for customizing at a global level. + +==== Usage + +[source,xml,indent=4] +---- +<globalBindings + [ collectionType = "collectionType" ] + [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ] + [ generateIsSetMethod = "true" | "false" | "1" | "0" ] + [ enableFailFastCheck = "true" | "false" | "1" | "0" ] + [ choiceContentProperty = "true" | "false" | "1" | "0" ] + [ underscoreBinding = "asWordSeparator" | "asCharInWord" ] + [ typesafeEnumBase = "typesafeEnumBase" ] + [ typesafeEnumMemberName = "skipGeneration" | + "generateName" | "generateError" ] + [ typesafeEnumMaxMembers = “xxxx”] + [ enableJavaNamingConventions = "true" | "false" | "1" | "0" ] + [ generateElementClass = "false" | "true" | "0" | "1" ] + [ generateElementProperty = "false" | "true" | "0" | "1" ] + [ generateValueClass = "true" | "true" | "0" | "1" ] + [ optionalProperty = "wrapper" | "primitive" | "isSet" ] + [ mapSimpleTypeDef = "true" | "false" | "1" | "0" ] + [ localScoping = "nested" | "toplevel" ] > + [ <javaType> ... </javaType> ]* + [ <serializable uid=”xxxx”/> ]* +</globalBindings> +---- + +The following customization values are +defined in global scope: + +* `_collectionType_` if specified, must be +either `"indexed"` or any fully qualified class name that implements +`_java.util.List_`. The default value is to any fully qualified class name +that implements `_java.util.List_`. +* `_fixedAttributeAsConstantProperty_` if +specified , defines the customization value +`_fixedAttributeAsConstantProperty_`. The value must be one of `"true"`, +`"false"`, `"1"` or `"0"`. The default value is `"false"`. +* `_generateIsSetMethod_` if specified, +defines the customization value of `_generateIsSetMethod_`. The value must +be one of `"true"`, `"false"`, `"1"` or `"0"`. The default value is `"false"`. +Consider customizing using the newly introduced _optionalProperty_ +before using this JAXB customization. +* `_enableFailFastCheck_` if specified, +defines the customization value `_enableFailFastCheck`_. The value must be +one of `"true"`, `"false"`, `"1"` or `"0"`. If enableFailFastCheck is `"true"` or +`"1"` and the JAXB implementation supports this optional checking, type +constraint checking when setting a property is performed as described in +<<Properties>>. The default value is `"false"`. +* `_choiceContentProperty_` if +specified, defines the customization value `_choiceContentProperty_`. The +value must be one of `"true"`, `"false"`, `"1"` or `"0"`. +The default value is `"false"`. +* `_underscoreBinding_` if specified, defines +the customization value `_underscoreBinding_`. The value must be one of +`"asWordSeparator"` or `"asCharInWord"`. The default value is +`"asWordSeparator"`. +* `_enableJavaNamingConventions_` if +specified, defines the customization value `_enableJavaNamingConventions_`. +The value must be one of `"true"`, `"false"`, `"1"` or `"0"`. +The default value is `"true"`. +* `_typesafeEnumBase_` if specified, defines +the customization value `_typesafeEnumBase_`. The value must be a list of +QNames, each of which must resolve to a simple type definition. Only +simple type definitions with an enumeration facet and a restriction base +type listed in `_typesafeEnumBase_` or derived from a type listed in +`_typesafeEnumBase_` is bound to a `_typesafeEnumClass_` by default as +specified in <<Enum Type>>. The default +value of `_typesafeEnumBase_` is `"xs:string"`. ++ +The `_typesafeEnumBase_` cannot contain the +following simple types and therefore a JAXB implementation is not +required to support the binding of the these types to typesafe +enumeration class: `_"xs:QName"_`, `_"xs:NOTATIION"_`, `_"xs:base64Binary"_`, +`_"xs:hexBinary"_`, `_"xs:date"_`, `_"xs:time"_`, `_"xs:dateTime"_`, `_"xs:duration"_`, +`_"xs:gDay"_`, `_"xs:gMonth"_`, `_"xs:gYear"_`, `_"xs:gMonthDay"_`, `_"xs:gYearMonth"_`, +`_"xs:IDREF"_`, `_"xs:ID"_`. If any of them are specified, it must result in an +invalid customization as specified in <<Invalid Customizations>>. +JAXB implementation must be capable of binding +any other simple type listed in `_typesafeEnumBase_` to a typesafe +enumeration class. + +* `_typesafeEnumMemberName_` if specified, +defines the customization value `_typesafeEnumMemberName_`. The value must +be one of `skipGeneration`, `generateError` or `generateName`. The +default value is `skipGeneration`. See <<typesafeenummembername>> for details. +* `_typesafeEnumMaxMembers_` if specified, +defines the maximum number of enum facets that a simple type definition +can have and be consider to binding to an enum type by default. The +attributes type is `xs:int` and its default value is `256`. +* `_generateElementClass_` if specified as +true, a schema-derived Element class, as specified in +<<Java Element Class>>, is generated for +each element declaration that has an element factory method generated +for it. Its default value is `"false"`. +* `_generateElementProperty_` if specified as +true, controls the generation of JAXBElement property. The value must be +one of `"true"`, `"false"`, `"1"` or `"0"`. The default is absence of the +value. +* `_generateValueClass_` if specified as true, a +schema-derived Java value class is generated for each complex type +definiton.Value class is specified in <<Value Class>>. +If generateValueClass is specified as false, a +schema-derived interface and implementation class is generated for each +complex type definition as specified in <<Java Content Interface>>. +The attribute’s default value is true. See +examples of this binding in <<generateElementClass and generateValueClass>>. +* zero or more `_javaType_` binding +declarations. Each binding declaration must be specified as described in +<<javatype-declaration>>. +* zero or one serializable binding declaration. +* `_optionalProperty_` controls how a JAXB property with a +primitive base type that represents an optional non-nillable +element/attribute is bound. If the attribute has the value "wrapper", +then the base type of the JAXB property is the wrapper class for the +primitive type. A user can indicate that this optional property is not +set by calling the setter with “null” value. If the attribute’s value is +"primitive", it binds as it did in JAXB 1.0. If the attribute’s value is +“isSet”, it binds the optional property using the primitive base type +and also the isSet/unset methods are generated for the optional +property. The attribute’s default value is “wrapper”. +* `_mapSimpleTypeDef_` controls whether a JAXB +mapped class should be generated for each simple type definition as +specified in <<Bind to a JAXB mapped class>>. +This attribute’s default value is `"false"`. This customization +eases preserving simple type substituting precisely as described in +<<Type Substitution of a Simple Type Definition>>. +* `_localScoping_` attribute can have the +value of either _nested_ or _toplevel_ . This attribute describes the +JAXB binding of nested XML schema component to either a _nested_ +schema-derived JAXB class or a _toplevel_ schema-derived JAXB class. To +avoid naming collisions between nested components, the default value for +this attribute is _nested_. A developer can customize _localScoping_ to +_toplevel_ when schema components nest too deeply or an application +would prefer to not work with nested classes. + +The semantics of the above customization +values, if not specified above, are specified when they are actually +used in the binding declarations. + +For inline annotation, a `<globalBindings>` +is valid only in the annotation element of the `<schema>` element. There +must only be a single instance of a `<globalBindings>` declaration in +the annotation element of the `<schema>` element. + +==== Customized Name Mapping + +A customization value can be used to specify +a name for a Java object (e.g. class name, package name etc.). In this +case, a customization value is referred to as a _customization name_. + +A customization name is always a legal Java +identifier (this is formally specified in each binding declaration where +the name is specified). Since customization deals with customization of +a Java representation to which an XML schema element is bound, requiring +a customization name to be a legal Java identifier rather than an XML +name is considered more meaningful. + +A customization name may or may not conform +to the recommended Java language naming conventions. [JLS - Java +Language Specification, Second Edition, Section 6.8, "Naming +Conventions"]. The customization value _enableJavaNamingConventions_ +determines if a customization name is mapped to a Java identifier that +follows Java language naming conventions or not. + +If _enableJavaNamingConventions_ is defined and +the value is `"true"` or `"1"`, then the customization name (except for +constant name) specified in the section from where this section is +referenced must be mapped to Java identifier which follows the Java +language naming conventions as specified in +<<Conforming Java Identifier Algorithm>>; +otherwise the customized name must be used as is. + +==== Underscore Handling + +The *[jaxb:globalBindings]* attribute +customization _underscoreBinding_ allows for the preservation of +underscore(s) occurring in an XML name when deriving a a Java identifier +from it. + +The default value for _@underscoreBinding_ is +`"asWordSeparator"` and categorizes underscore (‘_’) as a punctuation +mark in the XML name to Java identifier algorithm specified in Appendix +<<The Name to Identifier Mapping Algorithm>>. +The resulting algorithm transforms one or more consecutive +underscores in an XML name to camel case separated words in the derived +Java class and method names. Examples of this mapping are in +<<jcmcn>>. + +When _@underscoreBinding_ is +`"asCharInWord"`, underscore (‘_’) is considered a special letter within +a word. The result is that all underscore characters from the original +XML name are preserved in the derived Java identifier. Example of this +mapping are in <<asCharInWord>>. + +==== generateElementClass and generateValueClass + +The following code examples illustrate +default binding to value class and customization to bind to +interface/implementation classes. + +*_Example:_* Default Binding to a value class. + + +Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"> + <xs:attribute name="City" type="xs:string"/> +</xs:complexType> +---- + +Default Value Class: + +[source,java,indent=4] +---- +public class USAddress { + public USAddress() {...} + public String getCity() {...} + public void setCity(String value) {...} + ... +} +---- +Customization `<jaxb:globalBinding generateValueClass="false">` +generates following interface instead of +default value class: + +*_Example:_* Customized binding to an interface. + + +[source,java,indent=4] +---- +public interface USAddress { + String getCity(); + void setCity(String value); +} +---- + +*_Example:_* Generation of an Element Class. + + +Schema fragment: + +[source,xml,indent=4] +---- +<xs:element name="Address" type="USAddress"/> +---- +[source,java,indent=4] +---- +// Default Java binding of global element to element instance factory +public ObjectFactory { + JAXBElement<USAddress> createAddress(USAddress value); +} +---- + +`<jaxb:globalBinding generateElementClass="true"/>` results in generation +of following Element class: + +[source,java,indent=4] +---- +public class Address extends JAXBElement<USAddress> { +} +---- + +==== @typesafeEnumMemberName + +If there is a collision among the generated +constant fields *name* or if it is not possible to generate a legal Java +identifier for one or more of the generated constant field names, then +the binding is determined based on the value of @ +`_typesafeEnumMemberName_` of element *[jaxb:globalBindings]*. + +* _skipGeneration_ + +An enum type is not generated. This is the default behavior if +`_typesafeEnumMemberName_` has not been specified. A binding compiler may +report a warning on why the simple type definition was not bound to an +enum type. +* _generateName_ + +The constant fields *name* is `__"VALUE____<N>"_` where `_<N>_` is 1 +for the first enumeration value and increments by 1 to represent each +value within the XML enumeration. +* _generateError_ + +An error must be reported. + +==== <serializable> Declaration + +When the serializable customization is +specified, all schema-derived classes implement `java.io.Serializable`. +Each class is generated with a `serialVersionUID` field set to the value +specified by _@uid_. + +[source,java,indent=4] +---- +private static final long serialVersionUID = <value of @uid>; +---- +The JAXB user is required to identify when +schema-derived classes do not follow +_https://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a6519§[Java +serialization class evolution rules]_ and change the generated +`serialVersionUID` field by changing the *[serializable]* element’s +attribute _@uid_ value. + +==== @generateElementProperty + +Some schemas use both minOccurs="0" on +element as well as nillable="true", causing the generation of +JAXBElement. This customization lets you control this behavior. This +attribute may take two values: + +* _true_: + +Always generate properties to use JAXBElement, unless overriden by +`<jaxb:property generateElementProperty="false"/>` on individual +property. +* _false_: + +When generating properties from `<element nillable=”true” minOccurs=”0”/>`, +generate a property not to use JAXBElement, as if the +element declaration were just `<element nillable=”true” />`, unless +overriden by `<jaxb:property generateElementProperty="true"/>` on +individual property. It is an error to specify this customization, when +the property is required to be JAXBElement (such as when a property +contains multiple elements with different names but of the same type.) + +=== `<schemaBindings>` Declaration + +The customization values in +`<schemaBindings>` binding declaration have schema scope. This binding +declaration is therefore useful for customizing at a schema level. + +==== Usage + +[source,xml,indent=4] +---- +<schemaBindings [ map="boolean" ] > + [ <package> package </package> ] + [ <nameXmlTransform> ... </nameXmlTransform>]* +</schemaBindings> + +<package [ name = "packageName" ] + [ <javadoc> ... </javadoc> ] +</package> + +<nameXmlTransform> + [ <typeName [ suffix="suffix" ] + [ prefix="prefix" ] /> ] + [ <elementName [ suffix="suffix" ] + [ prefix="prefix" ] /> ] + [ <modelGroupName [ suffix="suffix" ] + [ prefix="prefix" ] /> ] + [ <anonymousTypeName [ suffix="suffix" ] + [ prefix="prefix" ] /> ] +</nameXmlTransform> +---- + +For readability, the `<nameXmlTransform>` and +`<package>` elements are shown separately. However, they are local +elements within the `<schemaBindings>` element. + +The following customizations are defined in +the schema scope: + +* _map_ if specified, prevents the classes +from being generated from this schema. When the value is `"0"` or `"false"`, +then no class/interface/enum will be generated from this package. _map_ +defaults to `"true"`. + +The semantics of the customization value, if +not specified above, are specified when they are actually used in the +binding declarations. + +For inline annotation, a `<schemaBindings>` +is valid only in the annotation element of the `<schema>` element. There +must only be a single instance of a `<schemaBindings>` declaration in +the annotation element of the `<schema>` element. + +If one source schema includes (via the +include mechanism specified by XSD PART 1) a second source schema, then +the `<schemaBindings>` declaration must be declared in the first +including source schema. It should be noted that there is no such +restriction on `<schemaBindings>` declarations when one source schema +imports another schema since the scope of `<schemaBindings>` binding +declaration is schema scope. + +===== package + +Usage + +* `_name_` if specified, defines the +customization value `_packageName_`. `_packageName_` must be a valid Java +package name. +* `_<javadoc>_` if specified, customizes the +package level Javadoc. `_<javadoc>_` must be specified as described in +<<javadoc-declaration>>. The Javadoc +must be generated as specified in <<Javadoc Customization>>. +The Javadoc section customized is the `package +section`. + +[NOTE] +.Design Note +==== +The word “package” has been prefixed to `_name_` used in the binding declaration. +This is because the attribute or element tag names “name” is not unique by itself +across all scopes. For e.g., “name” attribute can be specified +in the <property> declaration. The intent is to disambiguate by reference such as `"packageName"`. + +==== + +The semantics of the `_packageName_` is +specified in the context where it is used. If neither `_packageName_` nor +the `_<javadoc>_` element is specified, then the binding declaration has +no effect. + +*_Example:_* Customizing Package Name + + +[source,xml,indent=4] +---- +<jaxb:schemaBindings> + <jaxb:package name = "org.example.po" /> +</jaxb:schemaBindings> +---- + +specifies `"org.example.po"` as the package +to be associated with the schema. + +===== nameXmlTransform + +The use case for this declaration is the UDDI +Version 2.0 schema. The UDDI Version 2.0 schema contains many +declarations of the following nature: + +[source,xml,indent=4] +---- +<xs:element name="bindingTemplate" type="uddi:bindingTemplate"/> +---- + +The above declaration results in a name +collision since both the element and type names are the same - although +in different XML Schema symbol spaces. Normally, collisions are supposed +to be resolved using customization. However, since there are many +collisions for the UDDI V2.0 schema, this is not a convenient solution. +Hence the binding declaration `nameXmlTransform` is being provided to +automate name collision resolution. + +The `nameXmlTransform` allows a `_suffix_` and +a `_prefix_` to be specified on a per symbol space basis. The following +symbol spaces are supported: + +* `<typeName>` for the symbol space “type +definitions” +* `<elementName>` for the symbol space +“element definitions” +* `<modelGroupName>` for the symbol space +“model group definitions.” +* `<anonymousTypeName>` for customizing Java +value class to which an anonymous type is bound.footnote:[XML schema does not +associate anonymous types with a specific symbol space. However, +_nameXmlTransform_ is used since it provides a convenient way to +customize the value class to which an anonymous type is bound.] + +If `_suffix_` is specified, it must be appended +to all the default XML names in the symbol space. The `_prefix_` if +specified, must be prepended to the default XML name. Furthermore, this +XML name transformation must be done after the XML name to Java +Identifier algorithm is applied to map the XML name to a Java +identifier. The XML name transformation must not be performed on +customization names. + +By using a different `_prefix_` and/or `_suffix_` +for each symbol space, identical names in different symbol spaces can be +transformed into non-colliding XML names. + +`*anonymousTypeName*` + +The `<anonymousTypeName>` declaration can be +used to customize the suffix and prefix for the Java value class. If +`_prefix_` is specified, then it must be prepended to the Java value class +name for the anonymous type. If suffix is specified, it must be +appended. + +=== `<class>` Declaration + +This binding declaration can be used to +customize the binding of a schema component to an element class, value +class or interface/implementation class. The customizations can be used +to specify: + +* a name for the derived Java class. +* an alternative implementation of +interface/implementation binding. + +Specification of an alternate implementation +for an interface allows implementations generated by a tool (e.g. based +on UML) to be used in place of the default implementation generated by a +JAXB provider. + +The implementation class may have a +dependency upon the runtime of the binding framework. The +implementation class may not be portable across JAXB provider +implementations. Hence one JAXB provider implementation is not required +to support the implementation class from another JAXB provider. + +==== Usage + +[source,xml,indent=4] +---- +<class [ name = "className" ] + [ implClass = "implClass" ] + [ ref = "className" ] > + [ <javadoc> ... </javadoc> ] +</class> +---- + +* `_className_` is the name of the derived +value class, if specified. It must be a legal Java class name and must +not contain a package prefix. The package prefix is inherited from the +current value of _package_. +* `_implClass_` if specified, is the name of +the implementation class for `_className_` and must include the complete +package name. Note that this customization only impacts the return value +for `className` ’s factory method. This customization is ignored when +`new` is used to create instances of a schema-derived Value class. +* `_ref_` if specified, is the name of the +value class that is provided outside the schema compiler. This +customization causes a schema compiler to refer to this external class, +as opposed to generate a definition. It must include the complete +package name. This attribute is mutually exclusive with the `_className_` +attribute and the `_implClass_` attribute. +* `_<javadoc>_` element, if specified +customizes the Javadoc for the derived value class. `_<javadoc>_` must be +specified as described in <<javadoc-declaration>>. + +==== Customization Overrides + +When binding a schema element’s Java +representation to a value class or a Java Element class, the following +customization values override the defaults specified in Chapter 5. It is +specified in a common section here and referenced from +<<Customizable Schema Elements>>. + +* *name*: The name is `_className_` if specified. +* *package name:* The name of the package is +`_packageName_` inherited from a scope that covers this schema element. ++ +[NOTE] +.Note +==== +The `_packageName_` is only set in the `<package>` declaration. The +scope of `_packageName_` is schema scope and is thus inherited by all +schema elements within the schema. + +==== + +* *javadoc:* The Javadoc must be generated as +specified in section <<Javadoc Customization>>. +The Javadoc section customized is the `class/interface +section`. + +==== Customizable Schema Elements + +===== Complex Type Definition + +When `<class>` customization specified in the +annotation element of the complex type definition, the complex type +definition must be bound to a Java value class as specified in +<<Java value class>> applying the +customization overrides as specified in <<Customization Overrides>>. + +*_Example:_* Class Customization: Complex Type Definition To Java value class + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"> + <xs:annotation><xs:appinfo> + <jaxb:class name="MyAddress" /> + </xs:appinfo></xs:annotation> + <xs:sequence>...</xs:sequence> + <xs:attribute name="country" type="xs:string"/> +</xs:complexType> +---- + +Customized code: + +[source,java,indent=4] +---- +// public class USAddress { // Default Code +public class MyAddress { // Customized Code + public String getCountry() {...} + public void setCountry(String value) {...} + ... +} +---- + +===== Simple Type Definition + +When `<class>` customization specified in the +annotation element of a simple type definition, the simple type +definition must be bound to a Java value class as specified in +<<Bind to a JAXB mapped class>> applying +the customization overrides as specified in +<<Customization Overrides>>. + +*_Example:_* Class Customization: Simple Type Definition To Java value class + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:simpleType name="SKU"> + <xs:annotation><xs:appinfo> + <jaxb:class/> + </xs:appinfo></xs:annotation> + <xs:restriction base=”xs:int”/> +</xs:simpleType> +---- + +Customized code: + +[source,java,indent=4] +---- +public class SKU { + @XmlValue + public int getValue() {...} + public void setValue(int value) {...} + ... +} +---- + +===== Model Group Definition + +It is invalid to place a `<jaxb:class>` customization on a model group. + +===== Model Group + +It is invalid to place a `<jaxb:class>` customization on an unnamed model group. + +===== Global Element Declaration + +A `_<class>_` declaration is allowed in the +annotation element of the global element declaration. However, the +`_implClass_` attribute is not allowed. The global element declaration +must be bound as specified in <<Bind to Element Class>> +applying the customization overrides specified in +<<Customization Overrides>>. + +*_Example:_* Class Customization: Global Element to Class + + +XML Schema Fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="AComplexType"> + <xs:sequence> + <xs:element name="A" type="xs:int"/> + <xs:element name="B" type="xs:string"/> + </xs:sequence> +</xs:complexType> + +<xs:element name="AnElement" type="AComplexType"> + <xs:annotation><xs:appinfo> + <jaxb:class name="MyElement"/> + </xs:appinfo></xs:annotation> +</xs:element> +---- + +Customized code: + +[source,java,indent=4] +---- +// following class is generated because of customization + +public class AComplexType { + void setA(int value) {...} + int getA() {...} + void setB(String value) {...} + String getB() {...} +} + +public class MyElement extends JAXBElement<AComplexType> {...} + +public class ObjectFactory { + + // Default code + // JAXBElement<AnElement> createAnElement(AnElement)\{...} + + // Customized code + MyElement createMyElement(AnElement) {...} + ... other factory methods ... + +} +---- + +===== Local Element + +A local element is a schema element that +occurs within a complex type definition. A local element is one of: + +* local element reference (using the “ref” +attribute) to a global element declaration. +* local element declaration (“ref” attribute is not used). + +A `<class>` declaration is allowed in the +annotation element of a local element. <<Annotation Restrictions>> +contains more information regarding the +annotation element for a local element reference. However, the +`_implClass_` attribute is not allowed. + +A `<class>` customization on local element +reference must result in an invalid customization as specified in +<<Invalid Customizations>> since a local +element reference is never bound to a Java Element class. + +A `<class>` customization on local element +declaration applies only when a local element declaration is bound to a +Java Element class. Otherwise it must result in an invalid customization +as specified in <<Invalid Customizations>>. +If applicable, a local element must be bound as +specified in <<bind-to-jaxbelementt-instance>> +applying the customization overrides as specified in +<<Customization Overrides>>. + +*_Example:_* Class Customization: Local Element Declaration To Java Element + + +The following example is from <<Examples>>. + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="Base"> + <xs:choice maxOccurs="unbounded"> + <xs:element name="A" type="xs:string"> + <xs:annotation><xs:appinfo> + <jaxb:class name="Bar"/> + </xs:appinfo></xs:annotation> + </xs:element> + <xs:element name="B" type="xs:string"/> + <xs:element name="C" type="xs:int"/> + </xs:choice> +</xs:complexType> +---- + +Customized code: + +[source,java,indent=4] +---- +import jakarta.xml.bind.JAXBElement; +public class ObjectFactory { + // element instance factories only + // JAXBElement<String> createBaseA(String value); // default code + JAXBElement<String> createBaseBar(String value); // Customized + JAXBElement<String> createBaseB(String value); + JAXBElement<Integer> createBaseC(Integer value); +} +public class Base { + static public class Bar extends JAXBElement<String> {...} // Customized code + /** + * A general content list that can contain element + * instances of JAXBElement<String> or JAXBElement<Integer>. + */ + List<Object> getBarOrBOrC() {...} +} +---- + +=== `<property>` Declaration + +This binding declaration allows the +customization of a binding of an XML schema element to its Java +representation as a property. This section identifies all XML schema +elements that can be bound to a Java property and how to customize that +binding. + +The scope of customization value can either +be definition scope or component scope depending upon which XML schema +element the `_<property>_` binding declaration is specified. + +==== Usage + +[source,xml,indent=4] +---- +<property [ name = "propertyName" ] + [ collectionType = "propertyCollectionType" ] + [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ] + [ generateIsSetMethod = "true" | "false" | "1" | "0" ] + [ enableFailFastCheck = "true" | "false" | "1" | "0" ] + [ generateElementProperty = "true" | "false" | "1" | "0" ] + [ attachmentRef = "resolve" | "doNotResolve" | "default" ] > + [ <baseType name = "fully qualified Java class"> ... </baseType> ] + [ <javadoc> ... </javadoc> ] +</property> + +<baseType name=”fully qualified Java class”> + <javaType> ... </javaType> +</baseType> +---- + +For readability, the `<baseType>` element is +shown separately. However, it can be used only as a local element within +the `<property>` element. + +The use of this declaration is subject to the +constraints specified in <<usage-constraints>>. + +The customization values defined are: + +* `_name_` if specified, defines the +customization value `_propertyName;_` it must be a legal Java identifier. +* `_collectionType_` if specified, defines the +customization value `_propertyCollectionType_` which is the collection +type for the property. `_propertyCollectionType_` if specified, must be +either `"indexed"` or any fully qualified class name that implements +`_java.util.List_`. +* `_fixedAttributeAsConstantProperty_` if +specified , defines the customization value +`_fixedAttributeAsConstantProperty_`. The value must be one of +`"true"`, `"false"`, `"1"` or `"0"`. +* `_generateIsSetMethod_` if specified, +defines the customization value of `_generateIsSetMethod_`. The value must +be one of `"true"`, `"false"`, `"1"` or `"0"`. +* `_enableFailFastCheck_` if specified, +defines the customization value `_enableFailFastCheck_`. The value must be +one of `"true"`, `"false"`, `"1"` or `"0"`. +* `@generateElementProperty` if specified, +controls the generation of JAXBElement property. The value must be one +of `"true"`, `"false"`, `"1"` or `"0"`. The default is absence of the value. +It is an error for this attribute to be present if this customization is +attached to local or global attribute declarations. This customization +affects the binding as follows. It is an error to specify this +customization, when the property is required to be `_JAXBElement_` (such +as when a property contains multiple elements with different names but +of the same type.) +** _true_ : Always generate properties to use `_JAXBElement_`. +** _false_ : When generating properties from +`_<element nillable="true" minOccurs="0" />_`, generate a property not to +use JAXBElement, as if the element declaration were just `_<element nillable="true"/>_`. +* `@attachmentRef` has a default value of +“default”. This mode defers to default processing as specified in +<<binding-ws-i-attachment-profile-refswaref>>. + + + +When `@attachmentRef` value is _resolve_ and the property’s base type is +or derives from `xsd:anyURI`, the schema-derived JAXB property has a +base type of `jakarta.activation.DataHandler` and the property is +annotated with `@XmlAttachmentRef`. + + + +Disabling autoresolving an element/attribute of type `ref:swaRef`: + +When `@attachmentRef` value is _doNotResolve_ and the property’s base +type derives from standard schema type `ref:swaRef`, the schema-derived +JAXB property has the base type `String`, derived from `xsd:anyURI`, +and `@XmlAttachmentRef` is not generated for the property. +* `_<javadoc>_` element, if specified +customizes the Javadoc for the property’s getter method. `_<javadoc>_` +must be specified as described in <<javadoc-declaration>>. + +==== baseType + +The `<baseType>` element is intended to allow +the customization of a base type for a JAXB property. This element can +only be a child of <jaxb:property> element. + +[source,xml,indent=4] +---- +<baseType name="fully qualified Java class>"> + <javaType> ... </javaType> +</baseType> +---- + + +The `@name` attribute enables either the +specialization or generalization of the default base type binding for a +JAXB property. Child element `<javaType>` is used to convert the default +base type to a Java class. These two mutual exclusive usages of the +<baseType> customization are described below. + +===== Conversion using Child element <javaType> + +Optional child element `_<javaType>_`, if +specified, defines the customization value `_javaType_` and must be +specified as defined in <<javatype-declaration>>. +The customization value defined has component scope. This +customization converts the default base type’s value for a simple type +definition to the Java class specified by <javaType> name. + +The schema-derived JAXB property is annotated +with `@XmlJavaTypeAdapter` specified in Section 8. +`@XmlJavaTypeAdapter.value()` is set to a generated +classfootnote:[There is no need to +standardize the name of the generated class since +_@XmlJavaTypeAdapter.value()_ references the class.] that extends +`jakarta.xml.bind.annotation.adapter.XmlAdapter`. The generated class’ +`unmarshal` method must call the <javaType> customization’s parse +method, which is specified in <<<javatype-declaration>>. +The generated class’ `marsha` method must call +the <javaType> customization’s print method. + +===== Generalize/Specialize baseType with attribute @name + +The `name` attribute for`<baseType` enables +more precise control over the actual base type for a JAXB property. This +customization enables specifying an alternative base type than the +property’s default base type. The alternative base type must still be in +the same class inheritance hierarchy as the default base type. The +alternative base type must be either a super interface/class or subclass +of the default Java base type for the property. The customization +enables one to specialize or generalize the properties binding. + +The `name` attribute value must be a fully +qualified Java class name. When the default base type is a primitive +type, consider the default Java base type to be the Java wrapper class +of that primitive type. + +Generalizing the basetype using this +customization enables simple type substitution for a JAXB property +representing with too restrictive of a default base type. To enable all +possible valid type substitutions, the `name` attribute should be +`java.lang.Object`. However, if for example, it is known that all type +substitutions will share a more specific Java super interface/class than +`java.lang.Object`, that Java class name can be used achieve a stronger +typed binding. With this customization, the JAXB annotation generated +for the property’s `@XmlElement.type()` or `@XmlAttribute.type()` is +still the default Java datatype for the element/attribute’s +schema-defined type. + +The schema-derived customized JAXB property +is annotated, either explicitly or by default mapping annotations, with +the mapping annotation `@XmlElement`, specified in Section 8.10.1. The +`@XmlElement` annotation element type is derived in terms of the +abstract model properties for a element type definition summarized in +<<Element Declaration Schema Component>> +as follows: + +.Annotate JAXB property with @XmlElement element-value pairs +[cols=",",options="header"] +|=== +| @XmlElement element | @XmlElement value +| type |the java type binding of the element declaration’s _{type definition}_ +|=== + +Note that the Java class for +`@XmlElement.type()` can differ from the recommended JAXB property’s +base type to enable type substitution of java.lang.Object. This binding +enables unmarshalling of the Element’s simple content when it is not +qualified with an `xsi:type` as the element’s schema-declared type. +`@XmlElement.type()` acts as the default `xsi:type` for a JAXB property +where the property’s base type was generalized to allow for type +substitution of an element declaration with a simple type definition. + +Specializing the basetype using this +customization generates stronger typing than default JAXB binding. For +example, an XML element or attribute of `xs:IDREF` binds to +`java.lang.Object` by default as specified in +<<Binding an IDREF component to a Java property>>. +If the schema only intends the reference to be to an element +that binds to a specific type, the baseType @name schema customization +can be used to specialize the binding. + +[#exidrefcust] +*_Example:_* Specialize binding of an IDREF via customization + + +Given XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="Book"> + <xs:sequence> + <xs:element name="author" type="xs:IDREF"/> + <xs:annotation><xs:appinfo> + <jaxb:property> + <jaxb:baseType name=”AuthorBio.class”/> + </jaxb:property> + </xs:appinfo></xs:annotation> + <!-- ... --> + </xs:sequence> +</xs:complexType> +<xs:complexType name="AuthorBio"> + <xs:sequence><!-- ... --> </xs:sequence> + <xs:attribute name="name" type="xs:ID"/> +</xs:complexType> +---- + +Schema-derived Java value class: + +[source,java,indent=4] +---- +public class Book { + @XmlIDREF + AuthorBio getAuthor() {...} + void setAuthor(AuthorBio referencedObj) {...} +} +public class AuthorBio { + @XmlID + String getName() {...} + void setName(String value) {...} +} +---- + +===== Usage Constraints + +The usage constraints on `<property>` are +specified below. Any constraint violation must result in an invalid +customization as specified in <<Invalid Customizations>>. The usage constraints are: + +. The `<baseType>` is only allowed with the +following XML schema elements from the +<<Customizable Schema Elements>>: +.. Local Element, <<Local Element>>. +.. Local Attribute, <<Local Attribute>>. +.. ComplexType with simpleContent, <<ComplexType>>. +. `<baseType>` can either have a name attribute +or a `<javaType>`, they both can not exist at the same time. +. The `_fixedAttributeAsConstantProperty_` is +only allowed with a local attribute, <<Local Attribute>>, that is fixed. +. If a `<property>` declaration is associated +with the `<complexType>`, then a `<property>` customization cannot be +specified on the following schema elements that are scoped to +`<complexType>`: ++ +-- +.. Local Element +.. Model group +.. Model Group Reference +-- +The reason is that a `<property>` declaration +associated with a complex type binds the content model of the complex +type to a general content property. If a `<property>` declaration is +associated with a schema element listed above, it would create a +conflicting customization. + +[NOTE] +.Design Note +==== +A Local Attribute is excluded from the list above. +The reason is that a local attribute is not part of the content model +of a complex type. This allows a local attribute to be customized +(using a <property> declaration) independently +from the customization of a complex type’s content model. + +==== + +*_Example:_* Property Customization: simple type customization + + +[source,xml,indent=4] +---- +<xs:complexType name="internationalPrice"> + .... + <xs:attribute name="currency" type="xs:string"> + <xs:annotation><xs:appinfo> + <jaxb:property> + <jaxb:baseType> + <jaxb:javaType name="java.math.BigDecimal" + parseMethod="jakarta.xml.bind.DatatypeConverter.parseInteger" + printMethod="jakarta.xml.bind.DatatypeConverter.printInteger"/> + </jaxb:baseType> + </jaxb:property> + </xs:appinfo></xs:annotation> + </xs:attribute> +</xs:complexType> +---- + +The code generated is: + +[source,java,indent=4] +---- +public class InternationalPrice { + // String getCurrency(); default + java.math.BigDecimal getCurrency() {...} //customized + public void setCurrency(java.math.BigDecimal val) {...} // customized +} +---- + +==== Customization Overrides + +When binding a schema element’s Java +representation to a property, the following customization values +override the defaults specified in Chapter 6. It is specified in a +common section here and referenced from <<Customizable Schema Elements>>. + +* *name*: If _propertyName_ is defined, then it +is the name obtained by mapping the name as specified in +<<Customized Name Mapping>>. +* *base type*: The basetype is +`_propertyBaseType_` if defined. The _propertyBaseType_ is defined by a XML +schema element in <<Customizable Schema Elements>>. +* *collection type*: The collection type is +`_propertyCollectionType_` if specified; otherwise it is the +`_propertyCollectionType_` inherited from a scope that covers this schema +element. +* *javadoc*: The Javadoc must be generated as +specified in section <<Javadoc Customization>>. The Javadoc section customized is the `method section`. +* If `_propertyBaseType_` is a Java primitive +type and `_propertyCollectionType_` is a class that implements +`java.util.List`, then the primitive type must be mapped to its wrapper +class. + +The following does not apply if local +attribute is being bound to a constant property as specified in +<<Local Attribute>>: + +* If `_generateIsSetMethod_` is `"true"` or `"1"`, then additional +methods as specified in <<isset-property-modifier>> must be generated. +* If `_enableFailFastCheck_` is `"true"` or `"1"`, +then the type constraint checking when setting a property is enforced by +the JAXB implementation. Support for this feature is optional for a JAXB +implementation in this version of the specification. + +==== Customizable Schema Elements + +===== Global Attribute Declaration + +A `_<property>_` declaration is allowed in +the annotation element of the global attribute declaration. + +The binding declaration does not bind the +global attribute declaration to a property. Instead it defines +customization values that have definition scope. The definition scope +covers all local attributes (<<Local Attribute>>) +that can reference this global attribute declaration. This +is useful since it allows the customization to be done once when a +global attribute is defined instead of at each local attribute that +references the global attribute declaration. + +===== Local Attribute + +A local attribute is an attribute that occurs +within an attribute group definition, model group definition or a +complex type. A local attribute can either be a + +* local attribute reference (using the “ref” +attribute) to a global attribute declaration. +* local attribute declaration (“ref” +attribute is not used). + +A `_<property>_` declaration is allowed in +the annotation element of a local +attribute. <<Annotation Restrictions>> +contains more information regarding the annotation element for a local +attribute reference. The customization values must be defined as +specified in <<usage-4>> and have component +scope. + +If `_javaType_` is defined, then the +`_propertyBaseType_` is defined to be Java datatype specified in the +`"name"` attribute of the `_javaType_`. + +* If `_fixedAttributeAsConstantProperty_` is +`"true"` or `"1"` and the local attribute is a fixed, the local +attribute must be bound to a Java Constant property as specified in +<<Bind to a Java Constant property>> +applying customization overrides as specified in +<<Customization Overrides>>. The +`_generateIsSetMethod_`, `_choiceContentProperty_` +and `_enableFailFastCheck_` must +be considered to have been set to `"false"`. +* Otherwise, it is bound to a Java property +as specified in <<Attribute use>> +applying customization overrides as specified in +<<Customization Overrides>>. + +*_Example:_* Customizing Java Constant Property + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"> + <xs:attribute name="country" type="xs:NMTOKEN" fixed="US"> + <xs:annotation><xs:appinfo> + <jaxb:property name="MY_COUNTRY" + fixedAttributeAsConstantProperty="true"/> + </xs:appinfo></xs:annotation> + </xs:attribute> +</xs:complexType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public class USAddress { + public static final String MY_COUNTRY = "US"; // Customized Code +} +---- + +*_Example 2:_* Customizing to other Java Property + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"> + + <xs:attribute name="country" type="xs:string"> + <xs:annotation><xs:appinfo> + <jaxb:property name="MyCountry"/> + </xs:appinfo></xs:annotation> + </xs:attribute> +</xs:complexType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public class USAddress { + // public getString getCountry(); // DefaultCode + // public void setCountry(string value);//Default Code + public String getMyCountry() {...} //Customized Code + public void setMyCountry(String value) {...}// Customized Code +} +---- + +*_Example 3:_* Generating IsSet Methods + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:attribute name="account" type = "xs:int"> + <xs:annotation><xs:appinfo> + <jaxb:property generateIsSetMethod="true"/> + </xs:appinfo></xs:annotation> +</xs:attribute> +---- + +Customized code: + +[source,java,indent=4] +---- +public int getAccount(); +public void setAccount(int account); +public boolean isSetAccount(); // Customizedcode +public void unsetAccount(); // Customizedcode +---- + +===== Global Element Declaration + +A `_<property>_` declaration is allowed in the +annotation element of a global element declaration. However, the usage +is constrained as follows: + +The binding declaration does not bind the +global element declaration to a property. Instead it defines +customization values that have definition scope. The definition scope +covers all local elements (<<Local Element>>) +that can reference this global element declaration. This is +useful since it allows the customization to be done once when a global +element is defined instead of at each local element that references the +global element declaration. + +===== Local Element + +A local element is a schema element that +occurs within a complex type definition. A local element is one of: + +* local element reference (using the “ref” +attribute) to a global element declaration. +* local element declaration (“ref” attribute +is not used). + +A `<property>` declaration is allowed in the +annotation element of a local element. <<Annotation Restrictions>> +contains more information regarding the +annotation element for a local element reference. + +The customization values must be defined as +specified in <<usage-4>> and have component +scope. + +If `_javaType_` is defined, then the +`_propertyBaseType_` is defined to be Java datatype specified in the +`"name"` attribute of the `_javaType_`. + +The local element must be bound as specified +in <<Content Model Default Binding>> +applying customization overrides as specified in +<<Customization Overrides>>. + +See example in <<propex3>> in section <<Model Group>>. + +===== Wildcard + +A `<property>` declaration is allowed in the +annotation element of the wildcard schema component. The customization +values must be defined as specified in <<usage-4>> and have component scope. + +The wildcard schema component must be bound +to a property as specified in <<Bind wildcard schema component>> +applying customization overrides as +specified in <<Customization Overrides>>. + +*_Example:_* The following schema example is from UDDI V2.0 + + +[source,xml,indent=4] +---- +<xs:complexType name="businessEntityExt"> + <xs:sequence> + <xs:any namespace="##other" + processContents="strict" + minOccurs="1" maxOccurs="unbounded"> + <xs:annotation><xs:appinfo> + <jaxb:property name="Extension"/> + </xs:appinfo></xs:annotation> + </xs:any> + .... + </xs:sequence> +</xs:complexType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public class BusinessEntityExt { + ... + // List getAny(); // Default Code + List getExtension() {...} // Customized Code +} +---- + +===== Model Group + +A `<property>` binding declaration is allowed +in the annotation element of the compositor (i.e. `<choice>`, +`<sequence>` or `<all>`). The customization values must be defined as +specified in <<usage-4>> and have component +scope. + +The customized binding of a model group is +determined by the following: + +* `choiceContentProperty` attribute in `<globalBindings>`. +. If _propertyBaseType_ is defined and a +`<property>` declaration is also present, then the customization +overrides specified in <<Customization Overrides>> +must be applied by the model group’s parent schema element +to the property used to aggregate the Java value class. +. If _propertySet_ is defined, then the model +group’s parent schema element must aggregate the property set as +specified in <<Aggregation of Property Set>>. + +*_Example 1:_* [[propex1, Example 1]]Property Customization: Model Group To ChoiceContent Property + + +XML Schema fragment + +[source,xml,indent=4] +---- +<xs:annotation><xs:appinfo> + <jaxb:globalBindings choiceContentProperty="true"/> +</xs:appinfo></xs:annotation> +<xs:complexType name=”AType”> + <xs:choice> + <xs:element name="foo" type="xs:int"/> + <xs:element name="bar" type="xs:string"/> + </xs:choice> +</xs:complexType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +class ObjectFactory { + JAXBElement<Integer> createAtypeFoo(Integer value); + JAXBElement<String> createAtypeBar(String value); +} +public class AType { + void setFooOrBar(Object o) {...} //customized code + Object getFooOrBar() {...} //customized code +} +---- + +The `choiceContentProperty` is required to +bind the choice model group to a choice content property. + +*_Example 2:_* [[propex2, Example 2]]Property Customization: Model Group To General Content Property + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="Base"> + <xs:choice maxOccurs="unbounded"> + <xs:annotation><xs:appinfo> + <jaxb:property name="items" /> + </xs:appinfo></xs:annotation> + <xs:element name="A" type="xs:string"/> + <xs:element name="B" type="xs:string"/> + <xs:element name="C" type="xs:int"/> + </xs:choice> +</xs:complexType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public class Base { + /** + * A general content list that can contain + * instances of Base.A, Base.B and Base.C. + */ + // List getAOrBOrC(); - default + List getItems() {...} // Customized Code +} +---- + +*_Example 3:_* [[propex3, Example 3]]Property Customization: Model Group To Content Property Set + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:complexType name="USAddress"/> +<xs:complexType name="PurchaseOrderType"> + <xs:sequence> + <xs:choice> + <xs:group ref="shipAndBill"/> + <xs:element name="singleUSAddress" type="USAddress"> + <xs:annotation><xs:appinfo> + <jaxb:property name="address"/> + </xs:appinfo></xs:annotation> + </xs:element> + </xs:choice> + </xs:sequence> +</xs:complexType> +<xs:group name="shipAndBill"> + <xs:sequence> + <xs:element name="shipTo" type="USAddress"> + <xs:annotation><xs:appinfo> + <jaxb:property name="shipAddress"/> + </appinfo></annotation> + </xs:element> + <xs:element name="billTo" type="USAddress"> + <xs:annotation><xs:appinfo> + <jaxb:property name="billAddress"/> + </xs:appinfo></xs:annotation> + </xs:element> + </xs:sequence> +</xs:group> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public interface PurchaseOrderType { + USAddress getShipAddress(); void setShipAddress(USAddress); + USAddress getBillAddress(); void setBillAddress(USAddress); + USAddress getAddress(); void setAddress(USAddress); +} +---- + +===== Model Group Reference + +A model group reference is a reference to a +model group using the `ref` attribute. A property customization is +allowed on the annotation property of the model group reference. Section +<<Annotation Restrictions>> contains more +information regarding the annotation element for a model group +reference. + +The customization values must be defined as +specified in <<usage-4>> and have component +scope. A model group reference is bound to a Java property set or a list +property as specified in <<Content Model Default Binding>> +applying customization overrides as specified in +<<Customization Overrides>>. + +===== ComplexType + +A `<property>` customization is allowed on +the annotation element of a complex type. The customization values must +be defined as specified in <<usage-4>> and +have component scope. The result of this customization depends upon the +content type of the complex type. + +* If the content type of the content model is +simple content, then the content model must be bound to a property as +specified in <<Simple Content Binding>>. +applying the customization overrides as specified in +<<Customization Overrides>>. If +`_javaType_` is defined, then the `_propertyBaseType_` is defined to be Java +datatype specified in the `"name"` attribute of the `_javaType_`. +* For all other content types, the content +model must be bound as specified in step 1. of +<<Content Model Default Binding>> +applying the customization overrides as specified in +<<Customization Overrides>>. + +[NOTE] +.Design Note +==== +The <property> declaration is not allowed on an annotation element +of attribute group definition. However, attributes within +the attribute group definition can themselves be customized +as described in the “Local Attribute” section above. +Section 7.8.4.2, “Local Attribute.” + +==== + +=== `<javaType>` Declaration + +A `<javaType>` declaration provides a way to +customize the binding of an XML schema atomic datatype to a Java +datatype, referred to as the _target Java datatype_. The target Java +datatype can be a Java built-in data type or an application specific +Java datatype. This declaration also provides two additional methods: +a _parse method_ and a _print method_. + +The parse method converts a lexical +representation of the XML schema datatype into a value of the target +Java datatype. The parse method is invoked by a JAXB provider’s +implementation during unmarshalling. + +The print method converts a value of the +target Java datatype into its lexical representation of the XML schema +datatype. The print method is invoked by a JAXB provider’s +implementation during marshalling. + +==== Usage + +[source,xml,indent=4] +---- +<javaType name="javaType" + [ xmlType = "xmlType" ] + [ parseMethod = "parseMethod" ] + [ printMethod = "printMethod" ]> +---- + +The binding declaration can be used in one of +the following: + +* a `<globalBindings>` declaration. +* annotation element of one of the XML schema +elements specified in <<Customizable Schema Elements>>. +* in a `<property>` declaration. See +<<property-declaration>>. This can be +used for customization at the point of reference to a simple type. + +When used in a `<globalBindings>` +declaration, `<javaType>` defines customization values with global +scope. When used in an annotation element of one of the schema elements +specified in <<Customizable Schema Elements>> +the customization values have component scope. + +===== name + +The `_javaType_`, if specified, is the Java +datatype to which `_xmlType_` is to be bound. Therefore, `_javaType_` must +be a legal Java type name, which may include a package prefix. If the +package prefix is not present, then the Java type name must be one of +the Java built-in primitive types [JLS - Java Language Specification, +Second Edition, Section 4.2, “Primitive Types and Values”]. (For +example, `"int"`) or a Java class in the unnamed package. If class +javaType declares a public constructor with following signature, +`javaType(java.lang.String)`, `parseMethod` attribute does not need to +be specified. + +===== xmlType + +The `_xmlType_`, if specified, is the name of +the XML Schema datatype to which `_javaType_` is to bound. If specified, +`_xmlType_` must be a XML atomic datatype derived from restriction. The +use of the `_xmlType_` is further constrained as follows. + +The purpose of the `_xmlType_` attribute is to +allow the global customization of a XML schema to Java datatype. Hence +`_xmlType_` attribute is required when `<javaType>` declaration’s parent +is `<globalBindings>`. If absent, it must result in an invalid +customization as specified in <<Invalid Customizations>>. +Otherwise, the _xmlType_ attribute must not be present +since the XML datatype is determined from the XML schema element with +which the annotation element containing `<javaType>` declaration or the +`<baseType>` (containing the `<javaType>`) is associated. If present, +it must result in an invalid customization as specified in +<<Invalid Customizations>>. + +Examples can be found in <<exjtcbt>> and <<exjtcus>> + +===== parseMethod + +The parse method if specified, must be +applied during unmarshalling in order to convert a string from the input +document into a value of the target Java datatype. The parse method must +be invoked as follows: + +* The parse method defaults to `new` provided +`_javaType_` is not a Java primitive type such as (``"int"``). If +`_javaType_` is a Java primitive type, then this must result in an invalid +customization as specified in <<Invalid Customizations>>. +Otherwise, the binding compiler must assume that the +target type is a class that defines a constructor as follows: ++ +-- +** `String` as the first parameter of the constructor. +-- ++ +To apply the conversion to a string it must +generate code that invokes this constructor, passing it the input +string. + +* The parse method may be specified in the +form _ClassName.methodName,_ where the _ClassName_ is a fully qualified +class name that includes the package name. A compiler must assume that +the class _ClassName_ exists and that it defines a static method named +_methodName_ that takes: ++ +-- +** `String` as the first argument. +-- ++ +To apply the conversion to a string it must +generate code that invokes this method, passing it the input string. + +* The parse method may be specified in the +form _methodName_ provided `_javaType_` is not a Java primitive type (such +as `"int"`). If `_javaType_` is Java primitive type, then this must +result in an invalid customization as specified in +<<Invalid Customizations>>. Otherwise, +the binding compiler must assume that _methodName_ is a method in the +class `_javaType_`. The binding compiler must therefore prefix the +`_javaType_` to the _methodName_ and process `_javaType_`._methodName_ as +specified in above. + +The string passed to parse method can be any +lexical representation for `xmlType` as specified in [XSD PART2]. + +If parseMethod attribute is not specified, +`xmlType` is not a primitive or wrapper class and `javaType` has an +accessible one argument constructor, where the argument is type +`java.lang.String`, input text is parsed by invoking `new` with a +`java.lang.String` parameter. + +===== printMethod + +The print method if specified, must be +applied during marshalling in order to convert a value of the target +type into a lexical representation: + +* The print method is specified in the form +_methodName_ provided `_javaType_` is not a Java primitive type (such as +`"int"`). If `_javaType_` is Java primitive type, then this must result +in an invalid customization as specified in +<<Invalid Customizations>>. Otherwise, +the compiler must assume that the target type is a class or an interface +that defines a zero-argument instance method named _methodName_ that +returns a `String`. To apply the conversion it must generate code to +invoke this method upon an instance of the target Java datatype. +* If the print method is specified in the +form _ClassName.methodName_ then the compiler must assume that the class +_ClassName_ exists and that it defines a static method named +_methodName_ that returns a string that takes the following: ++ +-- +** the first parameter is the target Java +datatype. +-- ++ +To apply the conversion to a string it must +generate code that invokes this method, passing it a value of the target +Java datatype. + +The lexical representation to which the value +of the target type is converted can be any lexical representation for +`xmlType` as specified in [XSD PART2]. + +If `printMethod` attribute is not specified +and `xmlType` is not a primitive or wrapper class, `javaType.toString()` +is used as the default print method.. + + + +==== DatatypeConverter + +Writing customized parse and print methods +can be difficult for a Java programmer. This requires a programmer to +understand the lexical representations of XML schema datatypes. To make +it easier, an interface, `DatatypeConverterInterface`, and a class +`DatatypeConverter` are defined to expose the parse and print methods of +a JAXB implementation. These can be invoked by user defined parse and +print methods. This shifts the burden of dealing with lexical spaces +back to the JAXB implementation. + +The `DatatypeConverterInterface` defines +parse and print methods for XML schema datatypes. There is one parse and +print method for each of XML schema datatype specified in +<<a725>>. The interface is fully specified by the Javadoc specified in +`jakarta.xml.bind.DatatypeConverterInterface`. + +The `DatatypeConverter` class defines a +static parse and print method corresponding to each parse and print +method respectively in the `DatatypeConverterInterface` interface. The +property `jakarta.xml.bind.DatatypeConverter` can be used to select the +name of a class that provides an implementation of the parse and print +methods. The name specified in the property must be a fully qualified +class name and must implement the interface `DatatypeConverterInterface` +. The class is fully specified by the Javadoc specified in +`jakarta.xml.bind.DatatypeConverter`. + +===== Usage + +The following example demonstrates the use of +the `DatatypeConverter` class for writing a customized parse and print +method. + +*_Example:_* [[exjtcus,javaType Customization: User Specified Parse Method]] javaType Customization: User Specified Parse Method + + +This example shows the binding of XML schema +type `"xs:date"` is bound to a Java datatype `long` using user specified +print and parse methods. + +[source,xml,indent=4] +---- +<jaxb:globalBindings> + <jaxb:javaType name="long" xmlType="xs:date" + parseMethod="pkg.MyDatatypeConverter.myParseDate" + printMethod="pkg.MyDatatypeConverter.myPrintDate"/> + </jaxb:javaType> +</jaxb:globalBindings> +---- + +[source,java,indent=4] +---- +package pkg; +import jakarta.xml.bind.DatatypeConverter; +public class MyDatatypeConverter { + public static long myParseDate(String s) { + java.util.Calendar d = DatatypeConverter.parseDateTime(s); + long result = cvtCalendarToLong(d) ; // user defined method + return result; + } + public static String myPrintDate(long l) { + java.util.Calendar d = cvtLongToCalendar(l); //user defined method + return DatatypeConverter.printDateTime(d); + } +} +---- + +The implementation of the print methods ( +`_parseDate_` and `_printDate_`) are provided by the user. + +The customization is applied during the +processing of XML instance document. During unmarshalling, the JAXB +implementation invokes `_myParseDate_`. If `_myParseDate_` method throws a +`_ParseException_`, then the JAXB implementation code catches the +exception, and generate a `_parseConversionEvent_`. + +===== Lexical And Value Space + +[XSD PART 2] specifies both a value space and +a lexical space for an schema datatypes. There can be more than one +lexical representation for a given value. + +Examples of multiple lexical representations +for a single value are: + +* For boolean, the value `true` has two +lexical representations `"true"` and `"1"`. +* For integer, the value `1` has two lexical +representations `"1.0"` and `"1"`. + +XSD PART 2 also specifies a canonical +representation for all XML schema atomic datatypes. + +The requirements on the parse and print +methods are as follows: + +* A JAXB implementation of a parse method in +`DatatypeConverterInterface` must be capable of a processing all lexical +representations for a value as specified by [XSD PART 2]. This ensures +that an instance document containing a value in any lexical +representation specified by [XSD PART 2] can be marshalled. +* A JAXB implementation of a print method in +`DatatypeConverterInterface` must convert a value into any lexical +representation of the XML schema datatype to which the parse method +applies, as specified by [XSD PART 2] and which is valid with respect to +the application’s schema. + +[NOTE] +.Design Note +==== +The print methods that are exposed may not be portable. The only +requirement on a print method is that it must output +a lexical representation that is valid with respect to the schema. +So two vendors can choose to output different lexical representations. +However, there is value in exposing them despite being non portable. +Without the print method, a user would have to be knowledgeable about +how to output a lexical representation for a given schema datatype, +which is not desirable. + +==== + +==== Built-in Conversions + +As a convenience to the user, this section +specifies some built-in conversions. A built-in conversion is one where +the parse and the print method may be omitted by a user. The built-in +conversions leverage the narrowing and widening conversions defined in +[JLS - Java Language Specification, Second Edition], Section 5.1.2, +“Widening Primitive Conversion” and Section 5.1.3, “Narrowing Primitive +Conversions.” For example: + +[source,xml,indent=4] +---- +<xs:simpleType name="foo" type="xs:long"> + <xs:annotation><xs:appinfo> + <jaxb:javaType name="int"/> + </xs:appinfo></xs:annotation> +</xs:simpleType> +---- + +If the parse method is omitted, then a JAXB +implementation must perform the one of the following binding options: + +.. If `_javaType_` is one of the following +primitive types or its corresponding wrapper class `byte`, `short`, `int`, +`long`, `float`, `double` , bind `_xmlType_` to its default Java datatype using +the parse method for the `_xmlType_` defined in `DatatypeConverter`. If +necessary, convert the default Java datatype for `xmlType` to value of +type `_javaType_` by a type cast. +.. Else if default Java datatype defines a +public one-argument constructor that takes a `java.lang.String`, use +`new` with a `java.lang.String` parameter for parsing. +.. Else javaType(java.lang.String) does not +exist, this must result in an invalid binding customization as specified +in <<Invalid Customizations>>. + +*_Example:_* [[exjtcbt,javaType Customization: Java Built-in Type]] javaType Customization: Java Built-in Type + + +This example illustrates how to bind a XML +schema type to a Java type different from the default one. + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:element name="partNumber" type="xs:int"/> +---- + +Customization: + +[source,xml,indent=4] +---- +<jaxb:globalBindings> + .... + <jaxb:javaType name="long" + xmlType="xs:int"/> +</jaxb:globalBindings> +---- + +Since a Java built-in is specified, a parse +or a print method need not be specified. A JAXB implementation uses the +parse and print methods defined in `DatatypeConverter` class for +converting between lexical representations and values. A JAXB +implementation unmarshals an input value using the following methods: + +[source,java,indent=8] +---- +int j = (int) DataTypeConverter.parseLong(string); +---- + +==== Events + +The parse method `_parseMethod_` may fail, +since it is only defined on those strings that are valid representations +of target Java datatype values and it can be applied to arbitrary +strings. A parse method must indicate failure by throwing an exception +of whatever type is appropriate, though it should never throw a +`TypeConstraintException`. A JAXB unmarshaller process must ensure that +an exception thrown by a parse method is caught and, if appropriate, a +`parseConversionEvent` event is generated. + +The print method `_printMethod_` usually does +not fail. If it does, then the JAXB implementation must ensure that the +exception thrown by a print method is caught and a +`printConversionEvent` is generated. + +==== Customization Overrides + +The `<javaType>` overrides the default +binding of `_xmlType_` to the Java datatype specified in <<a725>>. + +==== Customizable Schema Elements + +==== Simple Type Definition + +A `<javaType>` binding declaration is allowed +in the annotation element of the of a simple type definition. The +`_javaType_` overrides the default binding of `_xmlType_` to the Java +datatype specified in <<a725>>. The customization values defined have +definition scope and thus covers all references to this simple type +definition. + +If the simple type definition is mapped to a +schema-derived type, an `@XmlJavaTypeAdapter` is generated on that +class. Annotation element `@XmlJavaTypeAdapter.value()` is set to a +generated classfootnote:[There is no need to +standardize the name of the generated class since +_@XmlJavaTypeAdapter.value()_ references the class.] that extends +`jakarta.xml.bind.annotation.adapter.XmlAdapter`. The generated class’ +`unmarshal` method must call the <javaType> customization’s parse +method, which is specified in <<javatype-declaration>>. +The generated class’ `marshal` method must call +the <javaType> customization’s print method. + +===== GlobalBindings + +A `<javaType>` binding declaration is allowed +as part of `<globalBindings>`. The `_javaType_` overrides the default +binding of `_xmlType_` to the Java datatype specified in <<a725>>. +The customization values defined have global scope. + +For each element or attribute declaration +that references an `xmlType` that has a globalBindings `<javaType>` +customization specified for it, the corresponding JAXB property is +annotated with `@XmlJavaTypeAdapter`. + +===== `<property><baseType>` declaration + +A `<javaType>` binding declaration is allowed +as part of `<baseType>` in the `<property>` binding declaration. The +`_javaType_` overrides the default binding of `_xmlType_` to the Java +datatype specified in <<a725>>. Additional semantics are specified in +basetype also apply. + +The schema-derived JAXB property is annotated +with `@XmlJavaTypeAdapter` as specified in +<<basetype>>. + +=== `<typesafeEnum>` Declaration + +This binding declaration allows the +customization of a binding of an XML schema element to its Java +representation as an enum type, Section 8.9 in [JLS3]. Only simple type +definitions with enumeration facets can be customized using this binding +declaration. + +==== Usage +[source,xml,indent=4] +---- +<typesafeEnumClass> + [ name = "enumClassName" ] + [ map = "true" | "false" | "1" | "0" ] + [ ref = "enumClassName" ] + [ <typesafeEnumMember> ... </typesafeEnumMember> ]* + [ <javadoc> enumClassJavadoc </javadoc> ] +</typesafeEnumClass> + +<typesafeEnumMember name = "enumMemberName"> + [ value = "enumMemberValue"] + [ <javadoc> enumMemberJavadoc </javadoc> ] +</typesafeEnumMember> +---- +There are two binding declarations +`_<typesafeEnumClass>_` and `_<typesafeEnumMember>_`. The two binding +declarations allow the enumeration members of an enumeration class and +enumeration class itself to be customized independently. + +The `_<typesafeEnumClass>_` declaration +defines the following customization values: + +* `name` defines the customization value +`_enumClassName_`, if specified. `_enumClassName_` must be a legal Java +Identifier; it must not have a package prefix. + + +For an anonymous simple type, the `name` attribute must be present. If +absent, it must result in an invalid customization as specified in +<<Invalid Customizations>>. +* `map` determines if the simple type +definition should be bound to an enum type. When ``map``’s value is +`false`, then the simple type definition must not be bound to an enum +type. `map` defaults to `true`. +* `ref` if specified, is the name of the +enum class that is provided outside the schema compiler. This +customization causes a schema compiler to refer to this external enum, +as opposed to generate a definition. It must include the complete +package name. This attribute is mutually exclusive with the `className` +attribute and the `map` attribute. +* `<javadoc>` element, if specified +customizes the Javadoc for the enumeration class. _<javadoc>_ defines +the customization value `_enumClassjavadoc_` if specified as described in +<<javadoc-declaration>>. +* Zero or more `_<typesafeEnumMember>_` +declarations. The customization values are as defined as specified by +the `_<typesafeEnumMember>_` declaration. + +The `_<typesafeEnumMember>_` declaration +defines the following customization values: + +* `name` must always be specified and +defines a customization value `_enumMemberName_`. `_enumMemberName_` must +be a legal Java identifier. +* `value` defines a customization value +`_enumMemberValue_`, if specified. `_enumMemberValue_` must be the +enumeration value specified in the source schema. The usage of `_value_` +is further constrained as specified in <<value-attribute>>. +* `<javadoc>` if specified, customizes the +Javadoc for the enumeration constant. `<javadoc>` defines a +customization value `_enumMemberjavadoc_` if specified as described in +<<javadoc-declaration>>. + +For inline annotation, the +`<typesafeEnumClass>` must be specified in the annotation element of the +`<simpleType>` element. The `<typesafeEnumMember>` must be specified +in the annotation element of the enumeration member. This allows the +enumeration member to be customized independently from the enumeration +class. + +==== `value` Attribute + +The purpose of the _value_ attribute is to +support customization of an enumeration value using an external binding +syntax. When the `<typesafeEnumMember>` is used in an inline annotation, +the enumeration value being customized can be identified by the +annotation element with which it is associated. However, when an +external binding declaration is used, while possible, it is not +desirable to use XPath to identify an enumeration value. + +So when customizing using external binding +syntax, the `value` attribute must be provided. This serves as a key to +identify the enumeration value to which the `<typesafeEnumMember>` +applies. It’s use is therefore further constrained as follows: + +* When `<typesafeEnumMember>` is specified in +the annotation element of the enumeration member or when XPath refers +directly to a single enumeration facet, then the value attribute must be +absent. If present, it must result in must result in an invalid +customization as specified in <<Invalid Customizations>>. +* When `<typesafeEnumMember>` is scoped to +the `typesafeEnumClass` declaration, the value attribute must be +present. If absent, it must result in must result in an invalid +customization as specified in <<Invalid Customizations>>. +The _enumMemberValue_ must be used to identify the +enumeration member to which the `<typesafeEnumMember>` applies. + +An example of external binding syntax can be +found in <<ex2>>. + +==== Inline Annotations + +There are two ways to customize an +enumeration class: + +* split inline annotation +* combined inline annotation + +In split inline annotation, the enumeration +value and the enumeration class are customized separately i.e. the +`<typesafeEnumMember>` is used independently not as a child element of +`<typesafeEnumClass>`. An example of this is shown in <<ex1>>. + +In combined inline annotation, the +enumeration value and the enumeration class are customized together i.e. +the `<typesafeEnumMember>` is used as a child element of +`<typesafeEnumClass>`. This is similar to the customization used in +external binding declaration. In this case the `value` attribute must be +present in the `<typesafeEnumMember>` for reasons noted in +<<value-attribute>>. An example of this +customization is shown in <<ex3>>. + +==== Customization Overrides + +When binding a schema type definition’s Java +representation to an enum type, the following customization values +override the defaults specified in Chapter 5. It is specified in a +common section here and referenced from <<Customizable Schema Elements>>. + +* *name*: If _enumClassName_ is defined, then the +name obtained by mapping _enumClassName_ as specified in +<<Customized Name Mapping>>. +* *package name*: The name obtained by +inheriting `_packgeName_` from a scope that covers this schema element and +mapping _packageName_ as specified in <<Customized Name Mapping>>. +* *enumclass javadoc*: `_enumClassJavaDoc_` if +defined, customizes the `class/interface section` +(<<Javadoc Sections>>) for the enumeration +class, as specified in <<Javadoc Customization>>. +* *enum constant set*: Each member of the set +is computed as follows: +** *name*: If _enumMemberName_ is defined, the +name obtained by mapping _enumMemberName_ as specified in +<<Customized Name Mapping>>. +** *javadoc*: `_enumMemberJavaDoc_` if defined, +customizes the `field section` (<<Javadoc Sections>>) +for the enumeration class, as specified in +<<Javadoc Customization>>. + +==== Customizable Schema Elements + +Any XML Schema simple type which has an +enumeration facet can be customized with `<jaxb:typesafeEnumClass>` +declaration with the following exception. If the simple type definition +derives from `_xs:QName_`. `_xs:NOTATIION_`, `_xs:base64Binary_`, `_xs:hexBinary_`, +`_xs:date_`, `_xs:time_`, `_xs:dateTime_`, `_xs:duration_`, `_xs:gDay_`, `_xs:gMonth_`, +`_xs:gYear_`, `_xs:gMonthDay_`, `_xs:gYearMonth_`, `_xs:IDREF_`, `_xs:ID_`, it must result +in an invalid customization as specified in +<<Invalid Customizations>>. Since most +of these Xml datatypes bind to a mutable Java type, instances of these +Java types are not sufficient to be an immutable value of an enum +constant. + +[NOTE] +.Design Note +==== +The rationale for not allowing a type definition that derives from `xs:ID` +to bind to an enum type is to avoid complicating the resolution of `xs:IDREF` +values to `xs:ID` values. It is easiest if `xs:ID` values are always mapped to +an instance of `java.lang.String`. + +==== + +*_Example 1:_* [[ex1, Example 1]]typesafeEnum Customization: Split Inline Annotation + + +XML Schema fragment: + +[source,xml,indent=4] +---- +<xs:simpleType name="USState"> + <xs:annotation><xs:appinfo> + <jaxb:typesafeEnumClass name="USStateAbbr"/> + </xs:appinfo></xs:annotation> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="AK"> + <xs:annotation><xs:appinfo> + <jaxb:typesafeEnumMember name="STATE_AK"/> + </xs:appinfo></xs:annotation> + </xs:enumeration> + <xs:enumeration value="AL"> + <xs:annotation><xs:appinfo> + <jaxb:typesafeEnumMember name="STATE_AL"/> + </xs:appinfo></xs:annotation> + </xs:enumeration> + </xs:restriction> +</xs:simpleType> +---- + +Customized derived code: + +[source,java,indent=4] +---- +public enum USStateAbbr { + STATE_AL, STATE_AK; + public String value() { return name(); } + public static USStateAbbr fromValue(String value) {...} +}; +---- + +*_Example 2:_* [[ex2, Example 2]]typesafeEnum Customization: External Binding Declaration + + +The following example shows how to customize +the above XML schema fragment using an external binding syntax. + +[source,xml,indent=4] +---- +<jaxb:typesafeEnumClass name="USStateAbbr"> + <jaxb:typesafeEnumMember name="STATE_AK" value="AK"/> + <jaxb:typesafeEnumMember name="STATE_AL" value="AL"/> +</jaxb:typesafeEnumClass> +---- + +The attribute `value` must be specified for +`<typesafeEnumMember>`. This identifies the enumeration member to which +`<typesafeEnumMember>` applies. + +*_Example 3:_* [[ex3, Example 3]]typesafeEnum Customization: Combined Inline Annotation + + +The following example shows how to customize +the above XML schema fragment using inline annotation which does not +split the external binding syntax. + +[source,xml,indent=4] +---- +<xs:simpleType name="USState"> + <xs:annotation><xs:appinfo> + <jaxb:typesafeEnumClass name="USStateAbbr"> + <jaxb:typesafeEnumMember name="STATE_AK" value="AK"/> + <jaxb:typesafeEnumMember name="STATE_AL" value="AL"/> + </jaxb:typesafeEnumClass> + </xs:appinfo></xs:annotation> + <xs:restriction base="xs:NCName"> + <xs:enumeration value="AK"/> + <xs:enumeration value="AL"/> + </xs:restriction> +</xs:simpleType> +---- + +The attribute value must be specified for +`typesafeEnumMember`. This identifies the enumeration member to which +the binding declaration applies. + +=== `<javadoc>` Declaration + +The `<javadoc>` declaration allows the +customization of a javadoc that is generated when an XML schema +component is bound to its Java representation. + +This binding declaration is not a global XML +element. Hence it can only be used as a local element within the content +model of another binding declaration. The binding declaration in which +it is used determines the _section_ of the Javadoc that is customized. + +==== Javadoc Sections + +The terminology used for the javadoc sections +is derived from “Requirements for Writing Java API Specifications” which +can be found online at `https://www.oracle.com/java/technologies/javase/api-specifications.html`. + +The following sections are defined for the +purposes for customization: + +* package section (corresponds to package specification) +* class/interface section (corresponds to class/interface specification) +* method section (corresponds to method specification) +* field section (corresponds to field specification) + +==== Usage + +Note that the text content of a `<javadoc>` +element must use `CDATA` or `\<` to escape embedded HTML tags. + +[source,xml,indent=4] +---- +<javadoc> + Contents in <b>Javadoc<\b> format. +</javadoc> +---- + +or + +[source,xml,indent=4] +---- +<javadoc> + <<![CDATA[ + Contents in <b>Javadoc<\b> format + ]]> +</javadoc> +---- + +==== Javadoc Customization + +The Javadoc must be generated from the +`<javadoc>` element if specified. The Javadoc section depends upon where +`<javadoc>` element is used. JAXB providers may generate additional +provider specific Javadoc information (for example, contents of the +`<xs:documentation>` element). + +=== `<dom>` Declaration + +The `<dom>` customization binds an XML Schema +component to DOM rather than to a strongly typed Java representation. +Specifically, JAXB bindings for mixed content and wildcard result in a +hybrid mixture of strongly typed Java instances with DOM nodes or +java.lang.String, representing text info. These mixed bindings might be +more easily processed solely as one form, namely as an XML fragment +represented as DOM. This customization also meets a Jakarta XML Web Services +databinding requirement from <<Disabling Databinding>>. + +==== Usage + +The syntax for the customization is the following: + +[source,xml,indent=4] +---- + <dom [ [type= "w3c" | otherDomRepresentations ] /> +---- + +You can use the optional type attribute to +specify the type of DOM. By default, it is W3C DOM. + +==== Customizable Schema Elements + +This customization can be attached to the +following XML Schema components: + +* Element declaration (`<xs:element>`) +* Type definition (`<xs:complexType>` and `<xs:simpleType>`) +* Wildcard (`<xs:any>`) +* Model groups (`<xs:choice>`, `<xs:all>`, `<xs:sequence>`) +* Model group definition (`<xs:group>`) +* Particle + +For all of the above cases, the Java +representation of the DOM element is an instance of the Element class +for the specified DOM representation. For example, W3C DOM element is +bound to `org.w3c.dom.Element`. + +Special Case Handling of DOM customization on a: + +* _type definition_ - it is semantically +equivalent to placing the dom customization on each element declaration +referencing that type definition. +* _global element declaration_ - it is +semantically equivalent to placing the dom customization on each element +declaration referencing, via `@ref` , the global element declaration. +The dom customization on the global element declaration does not cause +that element to be unmarshalled as DOM when it is the root element of an +XML document nor when the element is part of a wildcard content JAXB +property. +* _mixed content_ - if an XML schema +component is annotated with a `dom` customization and that XML schema +component can contain character data information due to its parent +complex type definition being defined with mixed content, character data +information is handled as specified in <<Bind mixed content>>. + +The dom customization allows one to disable +databinding and process a part of a document using other technologies +that require “raw” XML. + +==== Examples + +*_Wildcard Binding Example_* + +A wildcard is mapped to a List of +`org.w3c.dom.Element`. Each element that matches to the wildcard will +be turned into a DOM tree. + +[source,xml,indent=4] +---- +<xs:complexType name=”foo”> + <xs:sequence> + <xs:any maxOccurs="unbounded" processContents="lax"> + <xs:annotation><xs:appinfo> + <jaxb:dom/> + </xs:appinfo></xs:annotation> + </xs:any> + </xs:sequence> +</xs:complexType> +---- + +[source,java,indent=4] +---- +import org.w3c.dom.Element; +public class Foo { + @XmlAnyElement(lax=”false”) + List<Element> getContent() {...} +} +---- + +*_Wildcard and Mixed Content Binding Example_* + +If the complexType definition above is +defined to have mixed content, due to element *[complexType]* having +attribute `@mixed="true"`, the JAXB binding is: + +[source,java,indent=4] +---- +import org.w3c.dom.Element; +public class Foo { + /* Element content is represented org.w3c.dom.Element. + * Character data information is represented as instances of + * java.lang.String. */ + @XmlMixed + @XmlAnyElement(lax=”false”) + List<Object> getContent() {...} +} +---- + +=== `<inlineBinaryData>` Declaration + +The `<inlineBinaryData>` customization +provides declarative control over the optimization for binary data +described in <<Enhanced Binary Data Handling>>. + +==== Usage + +The syntax for the customization is the +following: + +[source,xml,indent=4] +---- +<inlineBinaryData/> +---- + +This customization disables considering the +binary data optimization for a schema component containing binary data. + +This customization can be attached to the +following XML Schema components: + +* Element declaration (`<xs:element>`) with binary data or +* Type definition (`<xs:complexType>` and +`<xs:simpleType>`) deriving from binary datatype + +When a schema component that binds to a JAXB +property is customized with `<inlineBinaryData>`, its schema-derived JAXB +property is annotated with `@XmlInlineBinaryData`. When a type +definition is customized with `<inlineBinaryData>`, its schema-derived +class is annotated with program annotation `@XmlInlineBinaryData`. + +=== `<factoryMethod>` Declaration + +The `<factoryMethod>` customization provides +declarative control over an element or type factory method name +generated in a package’s `ObjectFactory` class introduced in +<<Java Package>>. This customization is +useful to resolve name collisions between factory methods in the +schema-derived `ObjectFactory` class. + +==== Usage + +The syntax for the customization is the +following: + +[source,xml,indent=4] +---- +<factoryMethod name=”BaseForFactoryMethodName”/> +---- + +The customization value defined is: + +* `_name_` - each character of name must be a +valid part of a Java identifier as determined by +`java.lang.Character.isJavaIdentifierPart()`. + +The name of the factory method is generated +by concatenating the following components: + +* The string constant `create` +* ``@name``’s value + +===== Usage Constraints + +The usage constraints on `<factoryMethod>` +are specified below. Any constraint violation must result in an invalid +customization as specified in <<Invalid Customizations>>. +The usage constraints are: + +. `<factoryMethod>` is only allowed to +annotate an element declaration or a type definition. + +Note that this customization does not require +a factory method to be generated, it simply provides a factory method +name if a factory method is to be generated for the annotated element +declaration or type definition. Section 6 and 7 specifies when a factory +method is generated for an element declarations or type definitions. + +=== Annotation Restrictions + +[XSD PART 1] allows an annotation element to +be specified for most elements but is ambiguous in some cases. The +ambiguity and the way they are addressed are described here. + +The source of ambiguity is related to the +specification of an annotation element for a reference to a schema +element using the “ref” attribute. This arises in three cases: + +* A local attribute references a global +attribute declaration using the “ref” attribute. +* A local element in a particle references a +global element declaration using the “ref” attribute. +* A model group in a particle references a +model group definition using the “ref” attribute. + +For example in the following schema fragment +(for brevity, the declaration of the global element “Name” and “Address” +has been omitted). + +[source,xml,indent=4] +---- +<xs:element name = "Customer"> + <xs:complexType> + <xs:element ref = "Name"/> + <xs:element ref = "Address" /> + </xs:complexType> +</xs:element> +---- + +XML Schema spec is ambiguous on whether an +annotation element can be specified at the reference to the “Name” +element. + +The restrictions on annotation elements has +been submitted as an issue to the W3C Schema Working Group along with +JAXB technology requirements (which is that annotations should be +allowed anywhere). Pending a resolution, the semantics of annotation +elements where the XML spec is unclear are assumed as specified as +follows. + +This specification assumes that an annotation +element can be specified in each of the three cases outlined above. +Furthermore, an annotation element is assumed to be associated with the +abstract schema component as follows: + +* The annotation element on an attribute ref +is associated with {Attribute Use} +* The annotation element on a model group ref +or an element reference is associated with the {particle}. +
diff --git a/spec/src/main/asciidoc/ch08-java_types.adoc b/spec/src/main/asciidoc/ch08-java_types.adoc new file mode 100644 index 0000000..8db2440 --- /dev/null +++ b/spec/src/main/asciidoc/ch08-java_types.adoc
@@ -0,0 +1,3087 @@ +// +// Copyright (c) 2020, 2023 Contributors to the Eclipse Foundation +// + +== Java Types To XML + +=== Introduction + +This chapter specifies the mapping from +program elements to XML Schema. The mapping includes a default as well +as a customized mapping. + +=== Overview + +This section is non normative and provides a +high level view of Java to XML Schema mapping targeted towards both JAXB +application developers and JAXB implementation vendors. + +==== Mapping Scope + +The mapping covers program elements commonly +used in the composition of a data model for an application: package, +field, property and types (classes and enum construct). Additionally, +the mapping scope also covers mapping annotations used to annotate +schema derived code. + +In so far as possible, a program element is +mapped to an equivalent XML Schema construct in an intuitive manner. +Thus, + +* *_Package_* maps to a XML target namespace. A +package provides a naming context for types. A XML target namespace +provides a naming context for schema components such as elements, type +definitions. +* *_Type_* maps to a schema type. A _value type_ is +a data container for values; e.g. a value class contains values +represented by it’s properties and fields. A schema type is a datatype, +an instance of which (e.g. element) acts as a data container for values +represented by schema components within a schema type’s content model +(e.g. element, attributes, etc.). Thus a type maps naturally to a schema +type. For e.g., +** class typically maps to a complex type definition +** java primitive types and wrapper classes map +to XML Schema simple type definition. +* *_Field or property_* maps to an element or an +attribute contained within the complex type to which a type is mapped. +* *_Enum type_* maps to a simple schema type +constrained by enumeration facets. + +The input to the mapping process is one or +more sets of packages or classes. A package or a class is mapped and +recursively, fields, properties and types contained with it. The mapping +is customizable. + +==== Mapping Annotations + +*_Mapping annotations_* The mapping of program +elements to XML Schema construct can be customized using _mapping annotations_, +program annotations based on JSR 175 program annotation +facility. Mapping annotations are used for: + +* customizing the Java to XML schema mapping. +* annotating schema derived code. +* control over optimized binary data encoding. + +The mapping annotations are described in the +`jakarta.xml.bind.annotation` and `jakarta.xml.bind.annotation.adapters` +packages. + +*_Retention Policy_* The retention policy of all +mapping annotations is RetentionPolicy.RUNTIME. This policy allows +introspection of mapping annotations at runtime. Introspection can be +used by JAXB binding framework to marshal/unmarshal an object graph to +XML representation or to customize the mapping of program elements to +XML Schema constructs. This policy also allows a JAXB vendor +implementation to generate a schema from a program element’s compiled +form rather than its source. + +==== XML Name Derivation + +Mapped program element is a program element +that has been mapped to an XML Schema construct. It is possible to use +`@XmlTransient` annotation type to prevent the mapping of a program +element. + +*_XML Names_* An XML name may be needed for the +schema components for a mapped program element, for e.g. element name. +XML names are usually derived from a program element name, for e.g. +property, field, class name etc.But they can be customized using mapping +annotation. When an XML name is derived from a property name, bean de +capitalization rules are used. If a Java Identifier is not a legal XML +name, then a legal XML name can be assigned using an annotation element +(e.g. `@XmlType(name="foo")`). + +==== Fields and Properties + +*_XML global element_* Fields and properties +typically map to local elements within a complex type for a class. But a +well formed XML document begins with a root element (a global element in +the corresponding schema). The `@XmlRootElement` annotation can be used +to associate a global element with a class or an enum type. + +*_Null Value and Nillable Element_* A null value +for a type mapped to an XML Schema element in two ways: absence of an +element or an nillable element. The mapping annotation for an element +allows either mapping. + +==== Type Mapping + +Legacy applications One of the primary use +cases for Java language to XML Schema mapping is to allow an existing +application to be exported as a web service. In many cases, the existing +applications are legacy applications consisting of classes that follow +different class designs. The annotations and default mapping are +designed to enable such classes to be mapped to schema with minimal +changes to existing code. See <<Default Mapping>> for default mapping. + +*_Class_* A class usually maps to a complex type. +However, using `@XmlValue` annotation, a class can also be mapped to a +simple type (to hold a simple value) or a complexType with simpleContent +(to hold a simple value and attributes). The `@XmlType` annotation can +be used to customize the mapping of a class. For example, it can be used +to map a class to an anonymous type or to control the ordering of +properties and/or fields. Properties and fields are unordered; but they +can be mapped to a content model that is ordered (e.g. xs:sequence) or +unordered content model (xs:all). + +*_Class Designs_* A class with a public or +protected no-arg constructor can be mapped. If a class has a +*_static zero-arg factory_* method, then the factory method can be specified using +the annotation element `@XmlType.factoryMethod()` and `@XmlType.factoryClass()`. + +*_Ordering of Properties/fields_* The ordering of +properties and fields can be customized in one of two ways: at the +package level using `@XmlAccessorOrder` or using `@XmlType.propOrder()` at +the class level. + +*_Class Hierarchy Mapping_* Class hierarchy +typically maps to a type derivation hierarchy. The `@XmlType` and +`@XmlValue` annotations together provide support mapping class hierarchy +to schema type hierarchy where XML Schema complex type derives by +extension from either another complex type or a simple type. + +*_Supported Collection Types_* Typed collections +and untyped collections are mapped. Mapped collection types are: arrays, +indexed properties and parametric types. Mapped untyped collection are: +`java.util.List`, `java.util.Set` and `java.util.HashMap`. Of these, +`java.util.HashMap` does not map naturally to a XML Schema construct. +For example, `HashMap` can have different XML serialized forms which +differ in trade-offs made between memory and speed or specificity and +generality. The XML serialization form can be customized using +`@XmlJavaTypeAdapter` (<<adapter>>). + +*_Collection serialized forms_* A collection type +can be mapped to a XML Schema complex type and collection item is mapped +to local element within it. + +Alternately, a parameterized collection +(e.g. `List<Integer>`) can be mapped to a simple schema type that derives +by list. + +When a collection type is mapped to a XML +Schema complex type, the mapping is designed to support two forms of +serialization shown below. + +[source,java,indent=4] +---- +//Example: code fragment +int[] names; +---- +[source,xml,indent=4] +---- +<!--XML Serialization Form 1 (Unwrapped collection) + Element name is derived from property or field name--> +<names> ... </names> +<names> ... </names> +... +---- + +[source,xml,indent=4] +---- +<!--XML Serialization Form 2 (Wrapped collection) + Element name of wrapper is derived from property or field name + Element name of each item in collection is also derived from + property name--> +<names> + <names> value-of-item </names> + <names> value-of-item </names> + .... +</names> +---- + +The two serialized XML forms allow a null +collection to be represented either by absence or presence of an element +with a nillable attribute. The `@XmlElementWrapper` annotation on the +property or field is used to customize the schema corresponding to the +above XML serialization forms. + +A parameterized collection (e.g. +`List<Integer>)` can also be mapped to simple schema that derives by list +using `@XmlList` annotation. For e.g. the serialized XML form is: "1 2 3". + +==== Adapter + +A type may not map naturally to a XML +representation (see Supported Collection Types above). As another +example, a single instance of a type may have different on wire XML +serialization forms. + +Adapter approach defines a portable +customization mechanism for applications exemplified above. The +mechanism provides a way to adapt a _bound type_, a Java type used to +process XML content, to _value type_, mapped to an XML representation or +vice versa. It is the value type that is used for marshalling and +unmarshalling. Use of this approach involves two steps: + +* provide an adapter class that extends the +abstract class `jakarta.xml.bind.annotation.adapters.XmlAdapter` that +defines two methods `unmarshal()` and `marshal()`. The methods are +invoked by JAXB vendor implementation during unmarshalling and +marshaling respectively to adapt between bound and value types. +* specify the adapter class using the +`@XmlJavaTypeAdapter` annotation. + +==== Referential Integrity + +Preserving referential integrity of an object +graph across XML serialization followed by a XML de serialization, +requires an object reference to be marshalled by reference or +containment appropriately. Possible strategies include: + +* marshal all references to a given object by reference. +* marshal the first reference to an object by +containment and subsequent references to the same object by reference. + +Depending on the strategy, the schema to which +program element is mapped also varies accordingly. + +Two annotations `@XmlID` and `@XmlIDREF` +provide the mechanism which can be used together to map program element +by reference or containment. This places the burden of preserving +referential integrity on a developer. On the other hand, the ability to +customize the mapping is useful since it can result in mapping of +program elements to a schema that defines a document structure more +meaningfully to an application than a default derived schema. + +==== Property/Field Name Collision + +A XML name collision can arise when the +property name obtained by bean de capitalization and the name of a field +map to a same schema component. For example + +[source,java,indent=4] +---- +public int item; +public int getItem(); +public void setItem(int val); +---- + +The name collision occurs because the property +name, bean de capitalization, and the name of the public field are both +the same i.e. `item`. In the case, where the property and the public +field refer to the same field, the `@XmlTransient` can be used to +resolve the name collision by preventing the mapping of either the +public field or the property. + +=== Naming Conventions + +Any source and schema fragments and examples +shown in this chapter are meant to be illustrative rather than +normative. + +* `@XmlAttribute` denotes both a program +annotation type as well a specific use of annotation type. +* The prefix `xs:` is used to refer to schema +components in W3C XML Schema namespace. +* The prefix `ref:` is used to refer to schema +components in the namespace `"http://ws-i.org/profiles/basic/1.1/xsd"` + +[NOTE] +.Design Note +==== +The mapping of program elements to schema components is specified +using the abstract schema component model in XML Schema Part 1. +The use of abstract schema components allows precise specification of +the mapping and is targeted towards JAXB implementation vendors. +In contrast, jakarta.xml.bind.annotation Javadoc is targeted +towards the JAXB application developer. Hence it is the Javadoc +that contains code and schema fragment samples. + +Default mapping is specified in terms of customizations. First +the mapping of program element to a schema component +with the binding annotation is specified. Then the default +mapping for a program element is specified by defining +a default binding annotation. In the absence of any binding +annotation, the default binding annotation is considered to +annotate the program element. + +For ease of reading, a synopsis of each program annotation +is included inline in this chapter. Details can be found +in the Javadoc published separately from this document. + +==== + +=== Constraint Violations + +For the purpose of mapping and constraint +checking, if a program element is not annotated explicitly, and there is +a default mapping annotation defined for that element, it must be +applied first before performing any constraint checks or mapping. This +is assumed in the normative mapping tables shown below. + +The mapping of program elements to XML Schema +constructs is subject to mapping constraints, specified elsewhere in +this chapter. The mapping constraints must be enforced by the +`jakarta.xml.bind.annotation.JAXBContext.newInstance(..)` method. Any +cycles resulting from a combination of annotations or default mapping +must be detected in +`jakarta.xml.bind.annotation.JAXBContext.newInstance(..)` method and also +constitutes a constraint violation. A `jakarta.xml.bind.JAXBException` or +(its subclass, which can be provider specific) must be thrown upon a +constraint violation. + +A JAXB Provider must support the schema +generation at runtime. See +`jakarta.xml.bind.JAXBContext.generateSchema(..)` for more information. + +=== Type Mapping + +This section specifies the mapping of Java +types to XML Schema. + +==== Java Primitive types + +The default mapping of Java types (and their +wrapper classes) specified in table <<a2310>> must be supported. + +.Mapping: Java Primitive types to Schema Types +[[a2310]] +[cols=",",options="header"] +|=== +| Java Primitive Type | XML data type +| boolean | xs:boolean +| byte | xs:byte +| short | xs:short +| int | xs:int +| long | xs:long +| float | xs:float +| double | xs:double +|=== + +==== Java Standard Classes + +The default mapping of Java classes specified in <<a2329>> must be supported. + +.Mapping of Standard Java classes +[[a2329]] +[cols=",",options="header"] +|=== +| Java Class | XML data type +| java.lang.String | xs:string +| java.math.BigInteger | xs:integer +| java.math.BigDecimal | xs:decimal +| java.util.Calendar | xs:dateTim +| java.util.Date | xs:dateTime +| javax.xml.namespace.QName | xs:QName +| java.net.URI | xs:string +| javax.xml.datatype.XMLGregorianCalendar | xs:anySimpleType +| javax.xml.datatype.Duration | xs:duration +| java.lang.Object | xs:anyType +| java.awt.Image | xs:base64Binary +| jakarta.activation.DataHandler | xs:base64Binary +| javax.xml.transform.Source | xs:base64Binary +| java.util.UUID | xs:string +|=== + +[NOTE] +.Design Note +==== +JAXP package javax.xml.datatype introduced the following classes +for supporting XML schema types: Duration and XMLGregorianCalendar. +XMLGregorianCalendar supports for 8 schema calendar types - xs:date, +xs:time, xs:dateTime, 6 g* types, all of which derive from xs:anySimpleType. +The particular schema type is computed based on values of member fields of +XMLGregorianCalendar. Since the actual schema type is not known until runtime, +by default, XMLGregorianCalendar can only be mapped to xs:anySimpleType +and an instance of XMLGregorianCalendar could be marshaled using xsi:type +to specify the appropriate schema calendar type computed at runtime. +However, the mapping can be customized. + +==== + +A byte[] must map to xs:base64Binary by default. + +==== Generics + +===== Type Variable + +The following grammar is from [JLS], Section 4.4, "Type Variables". + +[source,subs=+quotes] +---- +TypeParameter: + TypeVariable TypeBound~opt~ + +TypeBound: + extends ClassOrInterfaceType AdditionalBoundList~opt~ +---- + +A type variable without a _Typebound_ must be +mapped to xs:anyType. + +A type variable with a _TypeBound_ must map to +the schema type to which _ClassOrInterfaceType_ is mapped; the mapping of +_ClassOrInterface_ is subject to the mapping constraints specified in +other sections in this chapter. + +[source,java,indent=4] +---- +// code fragment +public class Shape <T> { + public T xshape; + public Shape() {}; + public Shape(T f) { + xshape = f; + } +} +---- + +[source,xml,indent=2] +---- +<!-- XML Schema --> +<xs:complexType name="shape"> + <xs:sequence> + <xs:element name="xshape" type="xs:anyType" minOccurs="0"/> + </xs:sequence> +</xs:complexType> +---- + +===== Type Arguments and Wildcards + +The following grammar is from [JLS], Section +4.5.1, "Type Arguments and Wildcards". + +---- +TypeArguments: + <ActualTypeArgumentList> + +ActualTypeArgumentList: + ActualTypeArgument + ActualTypeArgumentList, ActualTypeArgument + +ActualTypeArgument: + ReferenceType + Wildcard + +Wildcard: +?WildcardBounds + +WildcardBounds: + extends ReferenceType + super ReferenceType +---- + +A wildcard without a _WildcardBounds_ must map +to schema type xs:anyType. + +A wildcard with a _WildcardBounds_ whose super +type is _ReferenceType_ must map to schema type xs:anyType. + +A wildcard with a _WildcardBounds_ that extends +a _ReferenceType_ must map to the schema type to which the _ReferenceType_ +is mapped; this mapping is subject to the mapping constraints specified +in other sections in this chapter and is determined by the annotations +as specified in the mapping tables in the chapter. For example: + +[source,java,indent=4] +---- +/** + * EXAMPLE : WildcarType Mapping + */ +// Code fragment +public class Shape {...} + +public class Rectangle extends Shape {...} +public class Circle extends Shape {...} + +public class Foo { + public java.util.List<? extends Shape> shapes; +} +---- + +[source,xml,indent=2] +---- +<!-- XML Schema fragment --> +<xs:complexType name="shape"> + ... +</xs:complexType> + +<xs:complexType name="circle"> + <xs:complexContent> + <xs:extension base="shape"> + ... + </xs:extension> + </xs:complexContent> +</xs:complexType> + +<xs:complexType name="rectangle"> + <xs:complexContent> + <xs:extension base="shape"> + ... + </xs:extension> + </xs:complexContent> +</xs:complexType> + +<xs:complexType name="foo"> + <xs:sequence> + <xs:element name="shapes" type="shape" nillable="true" + maxOccurs="unbounded" minOccurs="0"/> + </xs:sequence> +</xs:complexType> +---- + +==== Collections + +The following collection must be supported: + +* `java.util.Map` and its subtypes (e.g. java.util.HashMap) +* `java.util.Collection` and it’s subtypes (e.g. java.util.List) + +The mapping of collection depends upon the +annotations on the program elements and is specified in the mapping +tables. This specification uses a _collection type_ to be one of +`java.util.Collection` (or a subtype derived from it), an array or an +JavaBean index property. + +=== Java Package + +`@XmlSchema` is used in the mapping of package to an XML target namespace. + +==== @XmlSchema + +===== Synopsis + +[source,java,indent=4] +---- +public enum XmlNsForm {UNQUALIFIED, QUALIFIED, UNSET} + +@Retention(RUNTIME) @Target({}) +public @interface XmlNs {...} + +@Retention(RUNTIME) @Target({PACKAGE}) +public @interface XmlSchema { + XmlNs[] xmlns() default {}; + String namespace() default ""; + String location() default ""; + XmlNsForm elementFormDefault() default XmlNsForm.UNSET; + XmlNsForm attributeFormDefault() default XmlNsForm.UNSET; +} +---- + +===== Mapping + +If `location()` is "", a package annotated +with `@XmlSchema` must be mapped as specified in <<a2476>>. +Otherwise a package will not produce any schema document. + +[NOTE] +.Design Note +==== +XML Schema Part 1 does not contain an abstract component definition for +a schema. Neither is there a mapping of attribute information items +(e.g. elementFormDefault) of the <schema> to properties of an abstract +schema component. So the mapping below maps to attribute information +items on the <schema> element. "absent" in the tables is used to mean +absence of the attribute information item in the schema. + +==== + +[NOTE] +.Design Note +==== +When `location()` is present, this specification only guarantees +that no schema is generated for the namespace. Implementations should +generate `<import>` statements accordingly with the `schemaLocation` +attribute pointing to the value of the `@XmlSchema.location()`, +but `<import>` statements do not have corresponding schema components, +and they are anyway just hints, so it's not possible to enforce +such constraints. Implementations are also allowed to use values +other than `@XmlSchema.location()` in `<import schemaLocation="..."/>` +for example so that the reference points to a copy of the resource +that's preferrable for the user. + +==== + +.Table 8-3 Mapping: Package to XML target namespace +[[a2476]] +[cols=","] +|=== +| `targetNamespace` | if `@XmlSchema.namespace()` is "", then `absent;` + + + +otherwise `@XmlSchema.namespace()` + +| `elementFormDefault` | if the value of `@XmlSchema.elementFormDefault() +is `@XmlNsForm.UNSET`, then `absent;` + + + +otherwise, the value of `@XmlSchema.elementFormDefault()` + +| `attributeFormDefault` | if the value of `@XmlSchema.attributeFormDefault()` +is `@XmlNsForm.UNSET`, then `absent;` + + + +otherwise, the value of `@XmlSchema.attributeFormDefault()` + +|`Namespace prefixes` | if `@XmlSchema.xmlns()` is {} then implementation defined; + + + +otherwise `@XmlSchema.xmlns()` +|=== + +==== @XmlAccessorType + +This annotation allows control over default serialization of fields and properties. + +===== Synopsis + +[source,java,indent=4] +---- +@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE}) +public @interface XmlAccessorType { + XmlAccessType value() default XmlAccessType.PUBLIC_MEMBER; +} + +public enum XmlAccessType { NONE, PROPERTY, FIELD, PUBLIC_MEMBER } +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* This annotation can be used only with the +following other annotations: `@XmlType`, `@XmlRootElement`, +`@XmlAccessorOrder`, `@XmlSchema`, `@XmlSchemaType`, `@XmlSchemaTypes`, +`@XmlJavaTypeAdapters`. It can also be used with the following +annotations at the package level: `@XmlJavaTypeAdapter`. + +See <<Default Mapping>>. + +==== @XmlAccessorOrder + +This annotation allows control over the +default ordering of properties and fields that are mapped to XML +elements. Properties and fields mapped to XML attributes are not +impacted by this annotation since XML attributes are unordered. + +===== Synopsis + +[source,java,indent=4] +---- +@Inhertited @Retention(RUNTIME) +@Target({PACKAGE, TYPE}) +public @interface XmlAccessorOrder { + XmlAccessOrder value() default XmlAccessOrder.UNDEFINED; +} + +public enum XmlAccessOrder { UNDEFINED, ALPHABETICAL } +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* This annotation can be +used only with the following other annotations: `@XmlType`, +`@XmlRootElement`, `@XmlAccessorType`, `@XmlSchema`, `@XmlSchemaType`, +`@XmlSchemaTypes`, `@XmlJavaTypeAdapters`. It can also be used with the +following annotations at the package level: `@XmlJavaTypeAdapter`. + +* If the value of `@XmlAccessorOrder.value()` is +`XmlAccessOrder.ALPHABETICAL`, then the default ordering of +fields/properties is lexicographic order as determined by +`java.lang.String.CompareTo(String anotherString)`. + +* If the `@XmlAccessorOrder.value()` is +`XmlAccessOrder.UNDEFINED`, then the default ordering of +fields/properties is unspecified. + +==== @XmlSchemaType + +This annotation allows a customized mapping to +a XML Schema built in type. This is useful where a Java type can map to +more than one schema built in types. An example is +`XMLGregorianCalendar` which can represent one of the eight schema +built-in types. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) +@Target({FIELD, METHOD, PACKAGE}) +public @interface XmlSchemaType { + String name(); + String namespace() default "http://www.w3.org/2001/XMLSchema"; + Class type() default DEFAULT.class; + final class DEFAULT {} +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* `name()` must be an atomic simple type schema +type (or a type that derives from it) to which the type of the property +or field can be mapped from XML Schema -> Java as specified in Section +6.2.2, "Atomic Datatype". ++ +Example ++ +[source,java,indent=4] +---- +// @XmlSchemaType can specify any one of the eight calendar types +// that map to XMLGregorianCalendar. +@XmlSchemaType(name="date") +XMLGregorianCalendar foo; +---- +* If the annotation is used as a package +level annotation or within `@XmlSchemaTypes`, value of +`@XmlSchemaType.type()` must be specified and must be the Java type that +is being customized. +* If the annotation is used on a field or a +method, then value of `type()` must be `DEFAULT.class`. +* This annotation can only be used with the +following other annotations: `@XmlElement`, `@XmlAttribute`, +`@XmlJavaTypeAdapter`, `@XmlJavaTypeAdapters`. + +_package:_ + +When this annotation is used at the package +level, the mapping applies to references to `@XmlSchemaType.type()` as +specified below. For clarity, the following code example is used along +with normative text. + +[source,java,indent=4] +---- +// Example: change the default mapping at package level +package foo; +@jakarta.xml.bind.annotation.XmlSchemaType + (name="date", + type=javax.xml.datatype.XMLGregorianCalendar.class) +---- + +A `@XmlSchemaType` that is specified as a +package level annotation must apply at the point of reference as +follows: + +. a property/field within a class in package +(e.g `exmple.po`) whose reference type is `@XmlSchemaType.type()`. For +e.g. ++ +[source,java,indent=4] +---- +// XMLGregorianCalendar will be mapped to XML Schema type "date" +XMLGregorianCalendar cal; +---- + +. a property/field within a class in package +(e.g `exmple.po`), where `@XmlSchemaType.type()` is used as a +parametric type. For e.g. ++ +[source,java,indent=4] +---- + // Example: Following code maps to a repeating element with + // XML Schema type of "date". + List<XMLGregorianCalendar> bar; +---- + +_property/field:_ + +A `@XmlSchemaType` specified on the +property/field maps references to `@XmlSchemaType.type()` as follows: + +. property/field is a single valued. ++ +[source,java,indent=4] +---- +// Maps XMLGregorianCalendar to XML Schema type "date"" +@XmlSchemaType(name="date") +public XMLGregorianCalendar cal; +---- + +. a property/field where +`@XmlSchemaType.type()` is used as a parametric type. For e.g. ++ +[source,java,indent=4] +---- +// Example: Following code maps to a repeating element with +// XML Schema type of "date". +@XmlSchemaType(name="date") +List<XMLGregorianCalendar> bar; +---- + +==== @XmlSchemaTypes + +This annotation is a container annotation for +defining multiple `@XmlSchemaType` annotations at the package level. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({PACKAGE}) +public @interface XmlSchemaTypes { + // Collection of @{@link XmlSchemaType} annotations + XmlSchemaType[] value(); +} +---- + +===== Mapping + +Each `@XmlSchemaType` annotation in +`@XmlSchemaTypes.value()` must be mapped as specified in <<xmlschematype>>. + +=== Java class + +==== @XmlType + +`@XmlType` is used to map a Java class to a +schema type. The schema type is computed from its annotation element +values. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({TYPE}) +public @interface XmlType { + String name() default "##default"; + String[] propOrder() default {""}; + String namespace() default "##default"; + Class factoryClass() default DEFAULT.class; + final class DEFAULT {}; + String factoryMethod() default ""; +} +---- + +===== Mapping + +The following mapping constraints must be +enforced: + +* a class must be either be a top level class +or a nested static class. +* a class must have a public or protected +no-arg constructor or a factory method identified by {`factoryClass()`, +`factoryMethod()`} unless it is adapted using `@XmlJavaTypeAdapter`. +* If `factoryClass()` is other than +`DEFAULT.class`, then `factoryMethod()` must be specified (i.e. the +default value "" cannot be used.) +* If `factoryClass()` is `DEFAULT.class` and +`factoryMethod()` is not "", then `factoryMethod()` be a method in this +class. +* if `@XmlType.propOrder` is not {} or {""}, +then the set must include all of the properties and fields mapped to +particles as specified in: +** <<xmlelement>> +** <<xmlelements>> +** <<xmlelementref>> +** <<xmlelementrefs>> +* `@XmlType.propOrder` must not include a +field or property annotated with `@XmlTransient`. +* if the class, _subClass_, derives from another +XML-bound class, _baseClass_ directly or indirectly (other than +`java.lang.Object`), then the _subClass_ must not contain a mapped property +or field annotated with `@XmlValue` annotation. +* If a class contains a mapped property or +field annotated with `@XmlValue` annotation, then all other mapped +fields or properties in the class must be mapped to an XML attribute. +* This annotation can be used with the +following annotations: `@XmlRootElement`, `@XmlAccessorOrder`, +`@XmlAccessorType`. +* Even though the syntax allows it, `@XmlType` +is disallowed on an interface. + +A class annotated with `@XmlType`, must be +mapped as specified below: + +* class must be mapped as specified in <<a2678>> +if the class contains only one mapped property or field that +is annotated with `@XmlValue` as specified in <<xmlvalue>>. +* otherwise, the class must be mapped as specified in <<a2611>>. + +.Table 8-4 Mapping: Class to Complex Type Definition +[[a2611]] +[cols=","] +|=== +| `{name}` | if `@XmlType.name()` is "", then absent + + + +otherwise if `@XmlType.name()` is `##default`, then +the XML name derived from the class name as +specified in <<Java Identifier To XML Name>> + + + +otherwise `@XmlType.name()` + +| `{target namespace}` | if `@XmlType.namespace()` is `\\##default` +&& `@XmlType.name()` is "" and class is annotated with +`@XmlRootElement`, then the `{target namespace}` as specified in +<<a2742>> + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is "" and class is not annotated with +`@XmlRootElement`, then the `{target namespace}` of the attribute or +element to which the property or field, from where this class is +referenced, is mapped. + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is not "", then the namespace to +which the package, in which class is defined, is mapped as specified in +<<a2476>> + + + +otherwise `@XmlType.namespace()` + +| `{base type definition}` a| if the class contains a mapped property or +field annotated with `@XmlValue` as specified in <<xmlvalue>>, +then the schema type to which mapped property or field’s type is mapped. + + + +otherwise schema type to which the nearest +XML-bound ancestor class is mapped + + + +[NOTE] +.Note +==== +In the absence of an extends class, java.lang.Object is the implicit +superclass of a class. java.lang.Object is by default bound to xs:anyType, +the distinguished ur- type definition, the root of schema type definition +hierarchy. In this case, the +{derivation method} is mapped to restriction rather than by extension. +java.lang.Object can be bound to xs:any using + +==== + +| `{derivation method}` | if `{base type definition}` is `xs:anyType`, +then by `restriction` + + + +otherwise `extension` + +| `{final}` | if class modifier `final` is present then the +set `{extension, restriction}`; + + + +otherwise, the empty set. + +| `{abstract}` | `true` if the class modifier `abstract` is +present; + + + +otherwise `false`. + +| `{attribute uses}` | The set of properties or fields mapped to +attributes as specified in <<xmlattribute>>. + +| `{attribute wildcard}` | Attribute wildcard as specified in <<xmlanyattribute>>. + +| `{content type}` a| +. empty if no mapped property or field is +annotated with `@XmlElement` +. `mixed` if a property or field is annotated +with _@XmlMixed_ as specified in <<xmlmixed>>. +. `simpleContent` if : +.. no property or field is annotated with `@XmlElement` +.. && one or more properties or fields is annotated with `@XmlAttribute` +.. && one property is annotated with `@XmlValue`. +. `element-only content` if one or more +properties is annotated with `@XmlElement`; + +`content model` mapped as specified in <<a2662>>. + +| `{prohibited substitutions}` | `empty set` +| `{annotations}` | `absent` +|=== + +.Table 8-5 Mapping: Class body to Model Group Component +[[a2662]] +[cols=","] +|=== +| `{compositor}` | if `@XmlType.propOrder()` is {} then `xs:all`; + + + +otherwise `xs:sequence`. The ordering of +particles is: if `@XmlType.propOrder()` is not "", then the +order in which properties/fields are listed in `@XmlType.propOrder()`. + + + +if `@XmlType.propOrder()` is "" && class is annotated with +`@XmlAccessorOrder(XmlAcessOrder.ALPHABETICAL)` or +`@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)` is specified at the +package level and class is not annotated with +`@XmlAccessorOrder(XmlAccessOrder.UNDEFINED)`, then alphabetical order +as specified in <<xmlaccessororder>>. + + + +otherwise order is unspecified. + +| `{particles}` | Set of properties or fields mapped to +particles. See `{compositor}` mapping above for ordering of particles. + +| `{annotation}` | `unspecified` +|=== + +.Table 8-6 Mapping: Class to Simple Type Definition +[[a2678]] +[cols=",,"] +|=== +| `{name}` 2.+| if `@XmlType.name()` is "", then absent + + + +otherwise if `@XmlType.name()` is `##default`, then the XML name derived from the class name +as specified in <<Java Identifier To XML Name>> + + + +otherwise `@XmlType.name()` + +| `{target namespace}` 2.+| if `@XmlType.namespace()` is `\\##default` +&& `@XmlType.name()` is "" and class is annotated with +`@XmlRootElement`, then the `{target namespace}` as specified in +<<a2742>> + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is "" and class is not annotated with +`@XmlRootElement`, then the `{target namespace}` of the attribute or +element to which the property or field, from where this class is +referenced, is mapped. + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is not "", then the namespace to +which the package, in which class is defined, is mapped as specified in +<<a2476>> + + + +otherwise `@XmlType.namespace()` + +| `{base type definition}` 2.+| ur-type definition, `xs:anyType`. + + + +NOTE: This is subject to the mapping +constraints on XmlType. See <<mapping-6>>. + +| `{facets}` 2.+| `empty set` +| `{fundamental facets}` 2.+| derived +| `{final}` 2.+| `empty set`. + +A subset of `{extension, list, restriction, union}`. + +| `{variety}` 2.+| Must be mapped as shown below + +| | atomic + +`{primitive type definition}` a| if property or field type is one of: + + * primitive type + * wrapper class + * reference type mapped to a simple atomic type. + +| | list + +`{item type definition}` a| if the property or field type is one of the +following collection types: + +* generic list +* indexed property +* single dimensional array <<xmltype-list-simple-type>> + +| | union + +`{member type definitions}` | Not mapped. + +| `{annotation}` 2.+| `unspecified` +|=== + +==== @XmlRootElement + +`@XmlRooElement` can be used to associate a +global element with the schema type to which a class is mapped. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({TYPE} +public @interface XmlRootElement { + String name() default "##default"; + String namespace() default "##default"; +} +---- + +===== Mapping + +The following mapping constraints must be +enforced: + +* The only other annotations allowed with this +annotation are: `@XmlType`, `@XmlEnum`, `@XmlAccessorType`, +`@XmlAcessorOrder`. + +A class annotated with `@XmlRootElement` +annotation, must be mapped as specified in <<a2742>>. + +.Table 8-7 Mapping: Class to Element Declaration +[[a2742]] +[cols=","] +|=== +| `{name}` | if `@XmlRootElement.name()` is `##default`, +then the XML name derived from the class name as specified in +<<Java Identifier To XML Name>>; + + + +otherwise `@XmlRootElement.name()` + +| `{target namespace}` | if `@XmlRootElement.namespace()` is `##default`, +then the value of the `targetNamespace` to which the +package containing the class is mapped as specified in +<<a2476>> + + + +otherwise `@XmlRootElement.namespace()` + +| `{type definition}` | schema type to which the class is mapped as +specified in <<xmltype-2>>. + +| `{scope}` | `global` +| `{value constraint}` | `absent` +| `{nillable}` | `false` +| `{identity-constraint definitions}` | `empty set` +| `{substitution group affiliation}` a| `absent` +[NOTE] +.Design Note +==== +The value is always absent since there is no mapping to a substitution group. + +==== + +| `{substitution group exclusions}` | `{extension, restriction}` +| `{disallowed substitution}` | `{substitution, extension, restriction}` +| `{abstract}` a| `false` +[NOTE] +.Design Note +==== +A value of true indicates that the element is abstract and can occur +in only content models when element has been substituted in a substitution group. +Since there is no mapping to substitution groups, this value +is always mapped to false. + +==== +| `{annotation}` | `unspecified` +|=== + +==== @XmlTransient + +`@XmlTransient` is used to prevent the mapping of a class. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target(TYPE) +public @interface XmlTransient {} +---- + +===== Mapping + +The class must not be mapped. Any reference to +this class from the other XML-bound classes will treated as if they are +refering to the nearest XML-bound ancestor of this class (which could be +`java.lang.Object`, which guarantees that there always exists such a +class.) + +For the effect that this annotation causes on +derived classes, see <<a2611>>. + +Note that a class with`@XmlTransient` may +still have properties and fields with JAXB annotations. Those are mapped +to XML when a derived class is mapped to XML. See <<Property And Field>> +for more details. + +The following mapping constraints must be enforced: + +* `@XmlTransient` is mutually exclusive with +all other mapping annotations. + +==== @XmlSeeAlso + +`@XmlSeeAlso` is an annotation that can be +optionally placed on a class to instruct the JAXB runtime and the schema +generator to also bind classes listed in `@XmlSeeAlso`, when it binds +the class that `@XmlSeeAlso` is on. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target(TYPE) +public @interface XmlRootElement { + Class[] value(); +} +---- + +=== Enum Type + +==== @XmlEnum + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({TYPE}) +public @interface XmlEnum { + // Java type that is mapped to a XML simple type + Class <?> value() default String.class; +} +---- + +===== Mapping + +The following mapping constraints must be +enforced: + +* `@XmlEnum.value()` must be mapped to a XML schema simple type. + +.Table 8-8 Mapping: Enum type to Base Type Definition +[[a3331]] +[cols=",a"] +|=== +| `{base type definition}` | schema type to which `@XmlEnum.value()` is mapped. +| `{variety}` | The value depends upon the schema type to which the `@XmlEnum.value()` +is mapped. But syntactically, it is always a restriction of {base type definition} +derived from the {base type definition}. +[NOTE] +.Note +==== +The {base type definition} may either be a list simple type or an atomic type. +It will never be a union type because there is no mapping to union type for java->schema + +==== +|=== + +==== @XmlEnumValue + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD} +public @interface XmlEnumValue { + String value(); +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* `@XmlEnumValue.value()` must have a valid lexical representation for `@XmlEnum.value()`. + +.Table 8-9 Mapping: Enum constant to Enumeration Schema Component +[[a3230]] +[cols=","] +|=== +| `{value}` | `@XmlEnumValue.value()` +| `{annotation}` | unspecified +|=== + +==== @XmlType + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({TYPE}) +public @interface XmlType { + String name() default "##default"; + String namespace() default "##default"; + String[] propOrder() default {""}; + Class factoryClass() default DEFAULT.class; + final class DEFAULT {}; + String factoryMethod() default ""; +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +. `factoryMethod()`, `factoryClass()` and `@XmlType.propOrder` must be ignored. +. This annotation can be used only with the +following other annotations: `@XmlRootElement`, `@XmlAccessorOrder`, +`@XmlAccessorType`. However, `@XmlAccessorOrder` and `@XmlAccessorType` +must be ignored; they are not meaningful when used to annotate an enum +type. + +.Table 8-10 Mapping: Enum type to Simple Type Definition +[cols=","] +|=== +| `{name}` | if `@XmlType.name()` is "", then absent + + + +otherwise if `@XmlType.name()` is `##default`, then +the XML name derived from the class name as +specified in <<Java Identifier To XML Name>> + + + +otherwise `@XmlType.name()` + +| `{target namespace}` | if `@XmlType.namespace()` is `\\##default` +&& `@XmlType.name()` is "" and enum type is annotated with +`@XmlRootElement`, then the `{target namespace}` as specified in +<<a2742>> + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is "" and enum type is not annotated with +`@XmlRootElement`, then the `{target namespace}` of the attribute or +element to which the property or field, from where this enum type is +referenced, is mapped. + + + +otherwise if `@XmlType.namespace()` is `##default` && `@XmlType.name()` +is not "", then the namespace to +which the package, in which enum type is defined, is mapped as specified in +<<a2476>> + + + +otherwise `@XmlType.namespace()` + +| `{base type definition}` a| Mapped as specified in <<a3331>>. + +| `{variety}` a| Mapped as specified in <<a3331>>. + +| `{final}` | `extension, restriction, list, union`. + +| `{facets}` | the set constructed by mapping each enum constant +to an enumeration schema component as specified in <<a3230>>. + +| `{fundamental facets}` | `empty set` +| `{annotations}` | `unspecified` +|=== + +==== @XmlRootElement + +`@XmlRootElement` can be used to associate a +global element with the schema type to which the enum type is mapped. + +===== Mapping + +The following mapping constraints must be enforced: + +. The only other annotations allowed with this +annotation are: `@XmlType`, `@XmlEnum`, `@XmlAccessorType`, +`@XmlAcessorOrder`. + +Note that `@XmlAccessorType` and `@XmlAccessorOrder` +while allowed will be ignored by the constraint in <<Mapping>>. + +The mapping must be performed as specified in <<a2846>>. + +.Table 8-11 Mapping: Enum type to Element Declaration +[[a2846]] +[cols=","] +|=== +| `{name}` | if `@XmlRootElement.name()` is `"##default"`, +then the XML name derived from the enum type name as specified in +<<Java Identifier To XML Name>>; + +otherwise `@XmlRootElement.name()` + +| `{target namespace}` | if `@XmlRootElement.namespace()` is `"##default"`, +then the value of the targetNamespace to which the +package containing the class is mapped as specified in +<<a2476>> + +otherwise `@XmlRootElement.namespace()` + +| `{type definition}` | schema type to which the class is mapped as +specified in <<xmltype-2>>. + +| `{scope}` | `global` +| `{value constraint}` | `absent` +| `{nillable}` | `false` +| `{identity-constraint definitions}` | `empty set` +| `{substitution group affiliation}` a| `absent` +[NOTE] +.Design Note +==== +The value is always absent since there is no mapping to a substitution group. +==== + +| `{substitution group exclusions}` | `{extension, restriction}` +| `{disallowed substitution}` | `{substitution, extension, restriction}` +| `{abstract}` | `false` +| `{annotation}` | `unspecified` +|=== + +=== Property And Field + +The following must be mapped (subject to the mapping constraints listed below): + +* read/write property with its nearest XML-bound +superclass as the stopClass. +* non static, non transient field of all the +ancestors up to the stopClass (but excluding the stopClass itself); if +annotated with `@XmlAttribute`, then static final field must be mapped +(informally this maps to a fixed attribute but this is formally +specified in the mapping tables below). + +A _mapped property_ is a property found as above +and mapped either by default or using a JAXB annotation. + +A _mapped field_ is a field found as above and +mapped either by default or using a JAXB annotation. + +A property or field that has been annotated +with `@XmlTransient` is not mapped. + +The following mapping constraints must be enforced. + +* For a property, a given annotation can be +applied to either read or write property but not both. +* A property name must be different from any +other property name in any of the super classes of the class being +mapped. +* A mapped field name or the de capitalized +name of a mapped property must be unique within a class. For e.g. ++ +[source,java,indent=4] +---- + // Example 1: + // Both the field "x" and property getX/setX are mapped by + // default. However, the decapitalized name property getX/setX + // is also "x" which collides with the field name "x". +public class Foo { + public int x; + public int getX {...}; + public void setX {...}; + } +---- + +==== @XmlElement + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD} +public @interface XmlElement { + String name() default "##default"; // name for XML element + boolean nillable() default false; + boolean required() default false; + String namespace() default "##default"; + Class type() default DEFAULT.class; + String defaultValue() default "\u0000"; + static final class DEFAULT {} +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only additional mapping annotations +allowed with `@XmlElement` are: `@XmlID`, `@XmlIDREF`, `@XmlList`, +`@XmlSchemaType`, `@XmlValue`, `@XmlAttachmentRef`, `@XmlMimeType`, +`@XmlInlineBinaryData`, `@XmlJavaTypeAdapter` and `@XmElementWrapper`. +`@XmlElement` can also be used within `@XmlElements`. +* If the property or field type is a +parametric collection type, then `@XmlElement.type()` must be +`DEFAULT.class` or `collectionitem.class` (since the type of the +collection is already known). + +A field or property annotated must be mapped as follows: + +* If `@XmlElement.namespace()` is not `"##default"` +and different from the `{target namespace}` of the +enclosing class, then it must be mapped as specified in <<a2941>>. +* If property is single valued, and it’s type +is annotated with `@XmlRootElement` and `@XmlType.name() = ""`, then the +property must be mapped as specified in <<a2941>>. ++ +[NOTE] +.Design Note +==== +This mapping is designed to eliminate an infinite recursion. For example: + +[source,java,indent=4] +---- +// Code fragment +@XmlRootElement +@XmlType(name="") +class Foo { + Foo foo; +} +---- + +In the absence of the above mapping, the above code would map to: + +[source,xml,indent=2] +---- +<schema> + <element name="foo"> + <complexType> + <sequence> + <element name="foo" minOccurs="0"> + <complexType> + ... infinite recursion ... +---- + +With the above mapping, the code fragment would instead map to: + +[source,xml,indent=2] +---- +<schema> + <element name="foo"> + <complexType> + <sequence> + <element ref="foo" minOccurs="0"> +---- +==== +* otherwise, it must be mapped as <<a2959>>. + +[NOTE] +.Design Note +==== +A local element corresponds to two abstract schema components - a particle +and an element declaration. This is reflected in the mapping shown below. +==== + +.Table 8-12 Mapping: Property/field to Particle - ref attribute +[[a2941]] +[cols=","] +|=== +| `{min occurs}` | if `@XmlElement.required()` is `true`, then `1` + +if the property type is a primitive type or a +multi dimensional array with a primitive type then `1` + +otherwise `0` + +| `{max occurs}` | if the type of the property/field is not a +collection type, then `1` + +otherwise `unbounded`. + +| `{term}` a| element declaration as specified in <<a2973>> +with the following overrides for the abstract schema component properties: + +`{scope}` is `global` + +`{value constraint}` is `absent` + +`{type definition}` is `xs:anyType` if the +mapping results in two or more element decalarations with the same name. +[NOTE] +.Note +==== +The above make the element a global +element declaration rather than a local element declaration. +==== +|=== + +.Table 8-13 Mapping: Property/field to Particle - no ref attribute +[[a2959]] +[cols=","] +|=== +| `{min occurs}` | if `@XmlElement.required()` is `true`, then `1` + +otherwise if the property type is a primitive +type or a multi dimensional array with a primitive type then `1` + +otherwise `0` + +| `{max occurs}` | if the type of the property/field is not a +collection type, then `1`; + +otherwise `unbounded`. + +| `{term}` | must be mapped as specified in <<a2973>>. +|=== + +.Table 8-14 Mapping: Property/field to Element declaration +[[a2973]] +[cols=","] +|=== +| `{name}` | if `@XmlElement.name()` is `"##default"`, then +the XML name derived from the property or field name as specified in +<<Java Identifier To XML Name>>; + +otherwise `@XmlElement.name()` + +| `{target namespace}` a| if `@XmlElement.namespace()` is `"##default"`, then +[none] +* if the enclosing package has `@XmlSchema` +annotation and is `@XmlSchema.elementFormDefault` is +`@XmlNsForm.QUALIFIED`, then the namespace of the enclosing class. +* otherwise "" (which produces unqualified element in the default +namespace). + +otherwise, `@XmlElement.namespace()` + +| `{type definition}` | Note: The order of type inference below is significant. + +if `@XmlElement.type()` is not `DEFAULT.class`, +then the schema type to which `@XmlElement.type()` is mapped. + +otherwise if annotated with `@XmlList`, schema +type derived by mapping as specified in <<xmllist>> + +otherwise if annotated with `@XmlValue`, +schema type derived by mapping as specified in <<xmlvalue>> + +otherwise if annotated with `@XmlID`, the +schema type derived by mapping as specified in <<xmlid>> + +otherwise if annotated with `@XmlIDREF`, the +schema type derived by mapping as specified in +<<xmlidref>> + +otherwise if the property or field is a +collection type, then the schema type derived by mapping the collection +item type. + +otherwise the schema type to which the type of +the property is mapped. + +| `{scope}` | complex type to which the property’s or the +field’s containing class is mapped as specified in <<xmlschema>>. + +| `{value constraint}` | if `@XmlElement.defaultValue()` is `"\u0000"` then `absent` + +otherwise default value with the value +`@XmlElement.defaultvalue()`. + +| `{nillable}` | `@XmlElement.nillable()` + +| `{identity-constraint definitions}` | `absent` + +| `{substitution group affiliation}` | `absent` + +| `{substitution group exclusions}` | {`extension`, `restriction`} + +| `{disallowed substitution}` | {`extension`, `restriction`, `substitution`} + +| `{abstract}` | `false` + +| `{annotation}` | `unspecified` +|=== + +==== @XmlElements + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD,METHOD}) +public @interface XmlElements { + XmlElement[] value(); // collection of @XmlElement annotations +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* If the property or field type is a +parameterized collection type, then the size of the +`@XmlElements.value()` must be `1`. +* This annotation can be used only with the +following annotations: `@XmlIDREF`, `@XmlElementWrapper`, +`@XmlJavaTypeAdapter`. +* If `@XmlIDREF` is specified, then each +`@XmlElement.type()` must contain a JavaBean property/field annotated +with `@XmlID`. + +The property or field must be mapped as follows: + +* If the size of `@XmlElements.value()` is `1`, +then the property must be mapped as specified in <<xmlelement>>. +* otherwise it must be mapped as specified in <<a3034>>. + + + +.Table 8-15 Mapping: List of types to choice particle +[[a3034]] +[cols=","] +|=== +| `{min occurs}` | `0` +| `{max occurs}` | `unbounded` +| `{term}` | If `{particles}` row in <<a3042>> results in a single particle, +then that single particle. Otherwise mapped as specified in <<a3042>> +|=== + + +.Table 8-16 Mapping: List of types to choice model group of elements +[[a3042]] +[cols=","] +|=== +| `{compositor}` | `choice` +| `{particles}` | set obtained by mapping each `@XmlElement` in +`@XmlElements.value()` as specified in <<a2973>>. +| `{annotation}` | `unspecified` +|=== + +==== @XmlElementRef + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD} +public @interface XmlElementRef { + String name() default "##default"; // name for XML element + String namespace() default "##default"; + Class type() default DEFAULT.class; + static final class DEFAULT {} +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only other additional JAXB mapping +annotations allowed with `@XmlElementRef` are: `@XmlElementWrapper` and +`@XmlJavaTypeAdapter`. +* If the collection item type or property type +(for single valued property) is `jakarta.xml.bind.JAXBElement`, then +{`@XmlElementRef.name()`, `@XmlElementRef.namespace()`} must point an +element factory method with an `@XmlElementDecl` annotation in a class +annotated with `@XmlRegistry` (usually `ObjectFactory` class generated +by the schema compiler): +.. `@XmlElementDecl.name()` must equal `@XmlElementRef.name()` +.. `@XmlElementDecl.namespace()` must equal `@XmlElementRef.namespace()`. +* If the collection item type (for collection +property) or property type (for single valued property) is not +`jakarta.xml.bind.JAXBElement`, then the type referenced by the property +or field must be annotated with `@XmlRootElement`. + +A field or property annotated with the +`@XmlElementRef` annotation must be mapped as follows: + +* if the type of the property or field is +single valued property, then it must be mapped as specified in <<a3078>> +* otherwise (the type of the property or field +is a parametric type), then it must be mapped as specified in <<a3097>>. + + +.Table 8-17 Mapping: Property/field (property type single valued) to Particle with ref attribute +[[a3078]] +[cols=","] +|=== +| `{min occurs}` | if `@XmlElementRef.required()` is `true` ,then `1`; + +otherwise `0` +| `{max occurs}` | `1` +| `{term}` | must be mapped as specified in <<a3085>>. +|=== + +.Table 8-18 Mapping: Property/field to Element declaration with ref attribute +[[a3085]] +[cols=","] +|=== + +| `{name}` | if `@XmlElementRef.type()` is +`@XmlElementRef.DEFAULT.class` and the property type is not +`jakarta.xml.bind.JAXBElement`, then the XML name +`@XmlRootElement.name()` on the type being referenced. + +otherwise if `@XmlElementRef.type()` is +`@XmlElementRef.DEFAULT.class` and the parametric type or the property +type (for single valued property) is a `jakarta.xml.bind.JAXBElement`, +then the `@XmlElementRef.name()` + +| `{target namespace}` | if `@XmlElementRef.type()` is +`@XmlElementRef.DEFAULT.class` and the property type is not +`jakarta.xml.bind.JAXBElement`, then the XML namespace of the type being +referenced. + +otherwise if `@XmlElementRef.type()` is +`@XmlElementRef.DEFAULT.class` and the property type is single valued +and is `jakarta.xml.bind.JAXBElement`, then the +`@XmlElementRef.namespace()` + +| `{annotation}` | `unspecified` +|=== + +.Table 8-19 Mapping: Property/Field (parametric type) to choice particle +[[a3097]] +[cols=","] +|=== + +| `{min occurs}` | `0` +| `{max occurs}` | `unbounded` +| `{term}` | If `{particles}` row in <<a3105>> results in single particle, +then that single particle. Otherwise mapped as specified in <<a3105>> +|=== + +.Table 8-20 Mapping: Property/field (parametric type) to choice model group of element refs +[[a3105]] +[cols=","] +|=== +| `{compositor}` | `choice` +| `{particles}` | set obtained by visiting parametric type and +each of its derived types and if annotated with @XmlRootElement, then +mapping the @XmlRootElement as specified in as specified in <<a3085>>. + +| `{annotation}` | `unspecified` +|=== + +==== @XmlElementRefs + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD,METHOD}) +public @interface XmlElementRefs { + XmlElementRef[] value(); +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only other additional JAXB mapping +annotations allowed with `@XmlElementRefs` are: `@XmlElementWrapper` and +`@XmlJavaTypeAdapter`. + +The property or field must be mapped as +specified in <<a3124>>. + + +.Table 8-21 Mapping: List of element instances to choice particle +[[a3124]] +[cols=","] +|=== +| `{min occurs}` | `0` +| `{max occurs}` | `unbounded` +| `{term}` | If the `{particles}` row in <<a3132>> results in a single particle, +then that single particle. Otherwise mapped as specified in <<a3132>> +|=== + +.Table 8-22 Mapping: List of element instances to choice model group of element refs +[[a3132]] +[cols=","] +|=== +| `{compositor}` | `choice` +| `{particles}` a| set obtained by mapping + +* each `@XmlElementRef` in +`@XmlElementRefs.value()` as specified in <<xmlelementref>>. +* if property is annotated with `@XmlAnyElement`, +then the particle obtained by mapping as specified in <<xmlanyelement>> + +| `{annotation}` | `unspecified` +|=== + +==== @XmlElementWrapper + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD} +public @interface XmlElementWrapper { + String name() default "##default" ; // name for XML element + String namespace() default "##default"; + boolean nillable() default false; + boolean required() default false; +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only additional mapping annotations +allowed with `@XmlElementWrapper` are: `@XmlElement`, `@XmlElements`, +`@XmlElementRef`, `@XmlElementRefs`, `@XmlJavaTypeAdapter`. +* The property or the field must be a collection property. + +The property or field must be mapped as follows: + +* If `@XmlElementWrapper.namespace()` is not `"##default"` +and different from the `{target namespace}` of the enclosing class, +then it must be mapped as specified as specified in <<a3202>>. +* otherwise, it must be mapped as <<a3158>>. + +.Table 8-23 Mapping: Property/field to Particle for Element Wrapper +[[a3158]] +[cols=","] +|=== +| `{min occurs}` | if `@XmlElementWrapper.nillable()` is `true` or +`@XmlElementWrapper.required()` is `true`, then `1`; + +otherwise `0` + +| `{max occurs}` | `1` +| `{term}` | must be mapped as specified in <<a3167>>. +|=== + +.Table 8-24 Mapping: Property/field to Element Declaration for Element Wrapper +[[a3167]] +[cols=","] +|=== +| `{name}` | if `@XmlElementWrapper.name()` is `"##default"`, +then the XML name derived from the property or field name +as specified in <<Java Identifier To XML Name>>; + +otherwise `@XmlElementWrapper.name()` + +| `{target namespace}` a| if `@XmlElementWrapper.namespace()` is `"##default"`, +[none] +* if the enclosing package has `@XmlSchema` +annotation and is `@XmlSchema.elementFormDefault` is +`@XmlNsForm.QUALIFIED`, then the namespace of the enclosing class. +* otherwise "" (which produces unqualified element in the default namespace). + +otherwise `@XmlElementWrapper.namespace()` + +| `{type definition}` | if property/field is annotated with +`@XmlElementRef` or `@XmlElementRefs` then the schema type as specified in <<a3124>> + +otherwise if property/field is annotated with +`@XmlElement` or `@XmlElements` then the schema type as specified <<a3034>>. + +| `{scope}` | complex type to which the property’s or the +field’s containing class is mapped. +| `{value constraint}` | `absent` +| `{nillable}` | `@XmlElementWrapper.nillable()` +| `{identity-constraint definitions}` | `absent` +| `{substitution group affiliation}` | `absent` +| `{substitution group exclusions}` | {`extension`, `restriction`} +| `{disallowed substitution}` | {`extension`, `restriction`, `substitution`} +| `{abstract}` | `false` +| `{annotation}` | `unspecified` +|=== + +.Table 8-25 Mapping: Property/field Element Wrapper with ref attribute +[[a3202]] +[cols=","] +|=== +| `{min occurs}` | `1` +| `{max occurs}` | `1` +| `{term}` a| element declaration whose `{name}` is +`@XmlElementWrapper.name()` and `{target namespace}` is +`@XmlElementWrapper.namespace()`. +[NOTE] +.Note +==== +The element declaration is assumed to +already exist and is not created. +==== +|=== + +==== @XmlAnyElement + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlAnyElement { + boolean lax() default false; + Class<? extends DomHandler> value() default W3CDomHandler.class; +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only other JAXB annotations allowed with +`@XmlAnyElement` are: `@XmlElementRefs`. +* There must be only one property or field +that is annotated with `@XmlAnyElement`. +* If a _baseType_ has a property annotated with +`@XmlAnyElement`, then no other sub type in the inheritance hierarchy +rooted at _baseType_ can contain a property annotated with +`@XmlAnyElement`. + +The property or field must be mapped as +specified in <<a3223>>. + +.Table 8-26 Mapping: Wildcard schema component for wildcard (xs:any) +[[a3223]] +[cols=","] +|=== +| `{namespace constraint}` | `##other` +| `{process contents}` | `"lax"` if `lax()` is `true` otherwise `"skip"` +| `{annotation}` | `unspecified` +|=== + +==== @XmlAttribute + +`@XmlAttribute` is used to map a property or a field to an XML attribute. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlAttribute { + String name() default "##default"; + boolean required() default false; + String namespace() default "##default"; +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* If the type of the field or the property is +a collection type, then the collection item type must be mapped to +schema simple type. Examples: ++ +[source,java,indent=4] +---- +@XmlAttribute List<Integer> foo; // legal +@XmlAttribute List<Bar> foo; // illegal if Bar does not map to a + // schema simple type +---- +* If the type of the field or the property is +a non collection type, then the type of the property or field must map +to a simple schema type. Examples: ++ +[source,java,indent=4] +---- +@XmlAttribute int foo; // legal +@XmlAttribute Foo foo; // illegal if Foo does not map to a schema + // simple type +---- +* The only additional mapping annotations +allowed with `@XmlAttribute` are: `@XmlID`, `@XmlIDREF`, `@XmlList`, +`@XmlSchemaType`, `@XmlValue`, `@XmlAttachmentRef`, `@XmlMimeType`, +`@XmlInlineBinaryData`, `@XmlJavaTypeAdapter`. + +[NOTE] +.Design Note +==== +The mapping below supports mapping to either a local attribute or a reference +to a global attribute that already exists. The latter is useful for mapping to +attributes in foreign namespaces for e.g. <xs:attribute ref="xml:lang"/>. +Note that the attribtue is never created in the namespace, `@XmlAttribute.namespace()`; +it is assumed to exist (for e.g. "xml:lang"). The property or field is mapped to +an attribtue reference when `@XmlAttribute.namespace()` is different from +the `{target namespace}` of the type containing the property or field being mapped. +==== + +The property or field must be mapped as follows: + +* If `@XmlAttribute.namespace()` is not +`"##default"` and differs from the `{target namespace}` of the schema +type to which the type containing the property or field is mapped, then +the property or field must be mapped as specified in <<a3255>>. +* otherwise, it must be mapped as specified in <<a3266>>. + + + +.Table 8-27 Mapping: Property/field to Attribute Use (with ref attribute) +[[a3255]] +[cols=","] +|=== +| `{required}` | `@XmlAttribute.required()` +| `{attribute declaration}` a| attribute declaration whose `{name}` is +`@XmlAttribute.name()` and `{target namespace}` is +`@XmlAttribute.namespace()`. + +For e.g. +[source,xml,indent="2"] +---- +<xs:attribute ref="xml:lang"/> +---- +| `{value constraint}` | `absent` +| `{annotation}` | `unspecified` +|=== + +.Table 8-28 Mapping: Property/field to Attribute Use (no ref attribute) +[[a3266]] +[cols=","] +|=== +| `{required}` | `@XmlAttribute.required()` +| `{attribute declaration}` | Mapped as specified in <<a3276>> + +| `{value constraint}` | if field has access modifiers public and +static then the `fixed` + +otherwise `absent` +|=== + + +.Table 8-29 Mapping: Property/field to Attribute Declaration +[[a3276]] +[cols=","] +|=== +| `{name}` | if `@XmlAttribute.name()` is `"##default"`, then +the XML name derived from the property or field name as specified in +<<Java Identifier To XML Name>>; + +otherwise `@XmlAttribute.name()`. + +| `{target namespace}` | if `@XmlAttribute.namespace()` is `"##default"`, +then value of targetNamespace in <<a2476>>; + +otherwise `@XmlAttribute.namespace()` + +| `{type definition}` | if annotated with `@XmlList`, schema type +derived by mapping as specified in <<xmllist>> + +otherwise if annotated with `@XmlID`, the +schema type derived by mapping as specified in +<<xmlid>> + +otherwise if annotated with `@XmlIDREF`, the +schema type derived by mapping as specified in <<xmlidref>> + +otherwise if the type of the property is a +collection type, then the schema type derived by mapping the collection +item type. + +otherwise the schema type to which the type of +the property is mapped. + +| `{scope}` | complex type of the containing class + +| `{value constraint}` | if field has access modifiers static and final then `fixed` + +otherwise `absent` + +| `{annotation}` | `unspecified` +|=== + +==== XmlAnyAttribute + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlAnyAttribute{} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* There must be only one property or field in +a class that is annotated with `@XmlAnyAttribute`. +* The type of the property or the field must +be `java.util.Map`. +* The only other annotations that can be used +on the property or field with `@XmlAnyAttribute` are: +`@XmlJavaTypeAdapter`. + +The property or field must be mapped as +specified in <<a3313>>. + +.Table 8-30 Mapping: Wildcard schema component for Attribute Wildcard +[[a3313]] +[cols=","] +|=== +| `{namespace constraint}` | `##other` +| `{process contents}` | `skip` +| `{annotation}` | `unspecified` +|=== + +==== @XmlTransient + +`@XmlTransient` is used to prevent the mapping of a property or a field. + +===== Synopsis +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD, TYPE}) +public @interface XmlTransient {} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The field or the property must not be mapped. +* `@XmlTransient` is mutually exclusive with +all other mapping annotations. + +==== @XmlValue + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlValue {} +---- + +===== XmlValue Type Mapping + +The following mapping constraints must be enforced: + +. At most one field or a property in a class +can be annotated with `@XmlValue`. +. `@XmlValue` can be used with the following annotations: +.. `@XmlList` - however this is redundant +since `@XmlList` maps a type to a schema simple type that derives by +list just as `@XmlValue` would. +.. `@XmlJavaTypeAdapter` +. If the type of the field or property is a +collection type, then the collection item type must map to a simple +schema type. ++ +.Examples: +[source,java,indent=4] +---- +// Examples (not exhaustive): Legal usage of @XmlValue +@XmlValue List<Integer> foo; // int maps to xs:int +@XmlValue String[] foo; // String maps to xs:string +@XmlValue List<Bar> foo; // only if Bar maps to a simple + // schema type +---- +. If the type of the field or property is not +a collection type, then the type of the property or field must map to a +schema simple type. +. The containing class must not extend another +class (other than `java.lang.Obect`). + +===== Mapping + +* If the type of the property or field is a +collection type, then the type must be must be mapped as specified in +<<a3353>>. +* Otherwise, the schema type to which the type +of the property or field is mapped. + +.Table 8-31 @XmlValue: Mapping to list simple type +[[a3353]] +[cols=","] +|=== +| `{name}` | `absent` +| `{target namespace}` | `{target namespace}` of the attribute or +element to which the property or field is mapped and from where this +type is referenced. + +| `{base type definition}` | ur-type definition, `xs:anyType`. +| `{facets}` | `empty set` +| `{fundamental facets}` | `derived` +| `{final}` | `#all` +| `{variety}` | list +| `{item type definition}` a| if the field, property or parameter is a +collection type + +* if annotated with `@XmlIDREF`, then +`xs:IDREF` as specified in <<xmlidref>> +* otherwise the schema type to which the +collection item type is mapped. + +otherwise + +* if annotated with `@XmlIDREF`, then +`xs:IDREF` as specified in <<xmlidref>> +* otherwise the schema type to which the type +of the property, field or the parameter is mapped. + +| `{annotation}` | `unspecified` +|=== + +==== @XmlID + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlID {} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* at most one field or property in a class can +be annotated with `@XmlID`. +* The type of the field or property must be +`java.lang.String`. +* The only other program annotations allowed +with `@XmlID` are: `@XmlAttribute` and `@XmlElement`. + +The type of the annotated program element must +be mapped to `xs:ID`. + +==== @XmlIDREF + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlIDREF {} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* If the type of the field or property is a +collection type, then the collection item type must contain a property +or field annotated with `@XmlID`. +* If the field or property is not a collection +type, then the type of the property or field must contain a property or +field annotated with `@XmlID`. ++ +[NOTE] +.Note +==== +If the collection item type or the type +of the property (for non collection type) is `java.lang.Object`, then +the instance must contain a property/field annotated with `@XmlID` attribute. + +==== + +* The only additional mapping annotations +allowed with `@XmlIDREF` are: `@XmlElement`, `@XmlAttribute`, `@XmlList`, +and `@XmlElements`, `@XmlJavaTypeAdapter`. + +If the type of the field or property is a +collection type, then each collection item type must be mapped to +`xs:IDREF`. + +If the type of the field or property is single +valued, then the type of the property or field must be mapped to +`xs:IDREF`. + +==== @XmlList + +This annotation maps a collection type to a list simple type. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD, PARAMETER}) +public @interface XmlList {} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The type of the field, property or parameter +must be a collection type. +* The collection item type must map to a +simple schema type that does not derive by list. For example: ++ +[source,java,indent=4] +---- +// Examples: Legal usage of @XmlList +@XmlList List<Integer> foo; // int maps to xs:int +@XmlList String[] foo; // String maps to xs:string +@XmlList List<Bar> foo; // only if Bar maps to a simple type + +// Example: Illegal usage of @XmlList +public class Foo { + // @XmlValue maps List to a XML Schema listsimple type + @XmlValue List<Integer> a; +} + +class Bar { + // Use of @XmlList is illegal since Fooitself mapped + // to a XML Schema list simple type; XMLSchema list simple + // type can't derive from another XML Schemalist simple type + @XmlList List<Foo> y; +} +---- + +* The only additional mapping annotations +allowed with `@XmlList` are: `@XmlElement`, `@XmlAttribute`, `@XmlValue` and +`@XmlIDREF`, `@XmlJavaTypeAdapter`. + +The type of the property or field must be +mapped as specified in <<a3428>>. + +.Table 8-32 @XmlList: Mapping to list simple type +[[a3428]] +[cols=","] +|=== +| `{name}` | `absent` +| `{target namespace}` | `{target namespace}` of the attribute or +element to which the property or field is mapped and from where this +type is referenced. + +| `{base type definition}` | ur-type definition, `xs:anyType`. +| `{facets}` | `empty set` +| `{fundamental facets}` | `derived` +| `{final}` | `#all` +| `{variety}` | list +| `{item type definition}` | if annotated with `@XmlIDREF`, then `xs:IDREF` +as specified in <<xmlidref>> + +otherwise the schema type to which the +collection item type is mapped. + +| `{annotation}` | `unspecified` +|=== + +==== @XmlMixed + +This annotation is used for dealing with mixed +content in XML instances. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD, METHOD}) +public @interface XmlMixed {} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* The only additional mapping annotations +allowed with`@XmlMixed` are: `@XmlElementRef`, `@XmlAnyElement`, +`@XmlJavaTypeAdapter`. + +The `java.lang.String` instances must be +serialized as XML infoset text information items. + +==== @XmlMimeType + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) +@Target({FIELD,METHOD,PARAMETER}) +public @interface XmlMimeType { + // Textual representation of the MIME type,such as "image/jpeg" + // "image/*", "text/xml; charset=iso-8859-1"and so on. + String value(); +} +---- + +===== Mapping + +.Table 8-33 @XmlMimeType: Mapping to Foreign Namespace attribute +[cols=","] +|=== +| `{name}` | `"expectedContentTypes"` +| `{target namespace}` | `"http://www.w3.org/2005/05/xmlmime"` +| `attribute value` | `@XmlMimeType.value()` +|=== + +==== @XmlAttachmentRef + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD,METHOD,PARAMETER}) +public @interface XmlAttachmentRef {} +---- + +===== Mapping + +The type of property or field must map to `ref:swaRef`. + +==== XmlInlineBinaryData + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({FIELD,METHOD,TYPE}) +public @interface XmlInlineBinaryData { +} +---- + +===== Mapping + +This annotation does not impact the schema +generation. See the javadoc for +`jakarta.xml.bind.annotation.XmlInlineBinaryData` for more details. + +=== ObjectFactory Method + +The annotations in this section are intended +primarily for use by schema compiler in annotating element factory +methods in the schema derived ObjectFactory class +(<<Java Package>>). They are not expected +to be used when mapping existing classes to schema. + +==== @XmlElementDecl + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({METHOD}) +public @interface XmlElementDecl { + Class scope() default GLOBAL.class; + + // XML namespace of element + String namespace() default "##default"; + + String name(); // local name of element + + //XML namespace name of a substitution group's head element. + String substitutionHeadNamespace() default "##default"; + + //XML local name of a substitution group's head element. + String substitutionHeadName() default ""; + final class GLOBAL {} +} +---- + +===== Mapping + +The following mapping constraints must be enforced: + +* annotation can only be used on an _element factory method_ (<<Java Package>>). +The annotation creates a mapping between an XML schema element declaration +and a element factory method that returns a `JAXBElement` instance +representing the element declaration. Typically, the element factory +method is generated (and annotated) from a schema into the +`ObjectFactory` class in a Java package that represents the binding of +the element declaration's target namespace. Thus, while the annotation +syntax allows `@XmlElementDecl` to be used on any method, semantically +its use is restricted to annotation of element factory method +* class containing the element factory method +annotated with `@XmlElementDecl` must be annotated with `@XmlRegistry`. +* element factory method must take one +parameter assignable to `java.lang.Object`. +* two or more element factory methods +annotated with `@XmlElementDecl` must not map to element declarations +with identical `{name}` `{target namespace}` values. +* if type `Foo` has an element factory method +and is also annotated with @XmlRootElement, then they must not map to +element declarations with identical `{name}` and `{target namespace}` +values. ++ +One example of where the above scenario occurs +is when a developer attempts to add behavior/data to code generated from +schema. For e.g. schema compiler generates an element instance factory +method (e.g. `createFoo`) annotated with `@XmlElementDec`. But the +developer annotates `Foo` with `@XmlRootElement`. + +An element factory method must be mapped as +specified in <<a3518>>. + +.Table 8-34 Mapping: Element Factory method to Element Declaration +[[a3518]] +[cols=","] +|=== +| `{name}` | `@XmlElementDecl.name()` +| `{target namespace}` | if `@XmlElementDecl.namespace()` is `"##default"`, +then the value of the `targetNamespace` to which the +package of the class containing the factory method is mapped as +specified in <<a2476>> + +otherwise `@XmlElementDecl.namespace()` + +| `{type definition}` | schema type to which the class is mapped as +specified in <<xmltype-2>>. + +| `{scope}` | `global` if `@XmlElementDecl.scope()` is +`@XmlElementDecl.GLOBAL` + +otherwise the complex type definition to which +the class containing the object factory method is mapped. + +| `{value constraint}` | `absent` +| `{nillable}` | `false` +| `{identity-constraint definitions}` | `empty set` +| `{substitution group affiliation}` | element declaration derived from +`@XmlElementDecl.name()` and `@XmlElementDecl.substitutionHeadName()` + +| `{substitution group exclusions}` | `{}` +| `{disallowed substitution}` | `{}` +| `{abstract}` | `false` +| `{annotation}` | `unspecified` +|=== + +=== Adapter + +==== XmlAdapter + +[source,java,indent=4] +---- +public abstract class XmlAdapter<ValueType,BoundType> { + // Do-nothing constructor for the derivedclasses. + protected XmlAdapter() {} + + // Convert a value type to a bound type. + public abstract BoundType unmarshal(ValueType v); + + // Convert a bound type to a value type. + public abstract ValueType marshal(BoundType v); +} +---- + +For an overview, see the section, <<adapter>>. + +For detailed information, see the javadocs for +`jakarta.xml.bind.annotation.adapters.XmlAdapter` and +`jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter`. + +==== @XmlJavaTypeAdapter + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({PACKAGE,FIELD,METHOD,TYPE,PARAMETER}) +public @interface XmlJavaTypeAdapter { + Class<? extends XmlAdapter> value(); + Class type() default DEFAULT.class; + final class DEFAULT {} +} +---- + +For an overview, see <<adapter>>. + +===== Scope + +The scope of `@XmlJavaTypeAdapter` must cover +the program elements as specified below: + +*_package:_* + +For clarity, the following code example is used along with normative text. + +[source,java,indent=4] +---- +// Adapts Foo type to MyFoo type +FooAdapter extends XmlAdapter<MyFoo, Foo> + +// FooAdapter is installed at the package level - example.po +@XmlJavaTypeAdapter(value=FooAdapter.class, type=Foo.class) +---- +A `@XmlJavaTypeAdapter` that extends +`XmlAdapter<valueType, boundType>` and is specified as a package level +annotation must adapt `boundType` at the point of reference as follows: + +. a property/field/parameter within a class in +package (e.g `exmple.po)` whose reference type is `boundType`. For e.g. ++ +[source,java,indent=4] +---- + // Foo will be adapted to MyFoo + Foo foo; +---- +. a property/field/parameter within a class in +package (e.g `exmple.po`), where `boundType` is used as a parametric +type. For e.g. ++ +[source,java,indent=4] +---- + // List<Foo> will be adapted to List<MyFoo> + Foo foo; +---- + +*_class, interface, enum type:_* + +For clarity, the following code example is used along with normative text. + +[source,java,indent=4] +---- +// Adapts Foo type to MyFoo type +FooAdapter extends XmlAdapter<MyFoo, Foo> + +// FooAdapter is specified on class, interface or enum type. +@XmlJavaTypeAdapter(FooAdapter.class) +public class Foo {...} +---- + +A `@XmlJavaTypeAdapter` that extends +`XmlAdapter<valueType, boundType>` and is specified on the class, +interface or Enum type (i.e. on a program element that matches meta +annotation `@Target={type}`) must adapt `boundType` at the point of +reference as follows: + +. a property/field whose reference type is `boundType`. For e.g. ++ +[source,java,indent=4] +---- +// Foo will be adapted to MyFoo +Foo foo; +---- +. a property/field where `boundType` is used as a parametric type. For e.g. ++ +[source,java,indent=4] +---- +// List<Foo> will be adapted to List<MyFoo> +List<Foo> foo; +---- + +[NOTE] +.Note +==== +A `@XmlJavaTypeAdapter` on a class does +not apply to references to it’s sub class. + +[source,java,indent=4] +---- +//Example: +@XmlJavaTypeAdapter(...) public class Foo {...} +... +public class DerivedFoo extends Foo {...} +... +public class Bar { + // XmlJavaTypeAdapter applies to foo; + public Foo foo; + ... + // XmlJavaTypeAdaper DOES NOT apply to derivedFoo; + public DerivedFoo derivedFoo; +} +---- +==== + +*_property/field/parameter_*: + +A `@XmlJavaTypeAdapter` that extends +`XmlAdapter<valueType, boundType>` and is specified on the +property/field or parameter must adapt `boundType` as follows: + +. property/field is a single valued and its type is `boundType`: ++ +[source,java,indent=4] +---- +// Foo will be adapted to MyFoo +@XmlJavaTypeAdapter(FooAdapter.class) Foo foo; +---- +. a property/field where `boundType` is used as a parametric type. For e.g. ++ +[source,java,indent=4] +---- +// List<Foo> will be adapted to List<MyFoo> +List<Foo> foo; +---- + +===== Relationship to other annotations + +`@XmlJavaTypeAdapter` must be applied first +before any other mapping annotation is processed. Further annotation +processing is subject to their respective mapping constraints. For +example, + +[source,java,indent=4] +---- + +// PtoQAdapter is applied first and therefore converts type Q to P +// Next foo is mapped with a type of P (not Q) subject to the +// mapping constraints specified in@XmlElements. +@XmlJavaTypeAdapter(PtoQAdapter) +@XmlElements({ + @XmlElement(name="x",type=PX.class), + @XmlElement(name="y",type=PY.class) +}) +Q foo; + +@XmlType abstract class P {} +@XmlType class PX extends P {} +@XmlType class PY extends P {} +---- + +===== Class Inheritance Semantics + +When annotated on a class, the use of +`@XmlJavaTypeAdapter` annotation is subject to the class inheritance +semantics described here. The semantics is described in terms of two +classes: a `BaseClas` and a `SubClass` that derives from `BaseClass`. +There are two cases to consider: + +* `@XmlJavaTypeAdapter` annotates the `BaseClass` +* `@XmlJavaTypeAdapter` annotates the `SubClass`, +a class that derives from `BaseClass`. + +*_BaseClass_*: In this case, `@XmlJavaTypeAdapter` +annotates the `BaseClass`. In this case, the marshalling and +unmarshalling of an instance of property or a field with a static type +of baseClass must follow the schema to which +`XmlJavaTypeAdapter.value()` is mapped. + +[source,java,indent=4] +---- +//Example: code fragment +@XmlJavaTypeAdapter(...) BaseClass {...} +public SubClass extends BaseClass {...} +public BaseClass foo; +public SubClass subFoo = new SubClass(); +foo = subFoo; +---- + +In the absence of `@XmlJavaTypeAdapter` annotation, +the instance of subFoo is marshalled with an `xsi:type`: + +[source,xml,indent=4] +---- +<foo xsi:type="subClass"/> +---- + +With the `@XmlJavaTypeAdapter` annotation, +however, the instance of `subFoo` must be marshalled/unmarshalled +following the XML schema for `@XmlJavaTypeAdapter.value()`. + +*_Subclass_*: In this case, `@XmlJavaTypeAdapter` +annotates the `SubClass`. By definition, the annotation does not cover +references to `BaseClass`. Thus, the schema types to which `SubClass` and +`BaseClass` map are not in the same schema type hierarchy. Hence an +object with a static type of `BaseClass` but containing an instance of +`SubClass` can’t be marshalled or unmarshalled. An attempt to do so must +fail. For e.g, + +[source,java,indent=4] +---- +// Example: Code fragment +BaseClass {...} +... +@XmlJavaTypeAdapter(...) SubClass extends BaseClass {...} + +public class Bar { + public BaseClass foo; + public SubClass subFoo = new SubClass(); + + // marshal, unmarshal of foo will fail + foo = subFoo; + + // marshal, unmarshal of subFoo will succeed +} +---- + +==== @XmlJavaTypeAdapters + +This annotation is a container annotation for +defining multiple `@XmlJavTypeAdapter` annotations at the package level. + +===== Synopsis + +[source,java,indent=4] +---- +@Retention(RUNTIME) @Target({PACKAGE}) +public @interface XmlJavaTypeAdapters { + // Collection of @{@link XmlJavaTypeAdapter}annotations + XmlJavaTypeAdapter[] value(); +} +---- + +===== Mapping + +Each `@XmlJavaTypeAdapter` annotation in +`@XmlJavaTypeAdapters.value()` must be mapped as specified in +<<xmljavatypeadapter>>. + +=== Default Mapping + +This section describes the default mapping of +program elements. The default mapping is specified in terms of +_default annotations_ that are considered to apply to a program +element even in their absence. + +==== Java Identifier To XML Name + +The following is the default mapping for different identifiers: + +* _class name_: a class name is mapped to an XML +name by de capitalization of the unqualified class name. +* _enumtype name_: enumtype name is mapped to an +XML name by de capitalization of the unqualified enumtype name. +* A property name (e.g. address) is derived +from access method (e.g. getAddress) by de +capitalization of the property name. + +==== Package + +A package must be mapped with the following default package level mapping annotations: + +* `@XmlAccessorType(jakarta.xml.bind.annotation.XmlAccessType.PUBLIC_MEMBER)` +* `@XmlAccessorOrder(jakarta.xml.bind.annotation.XmlAccessOrder.UNDEFINED)` + +[NOTE] +.Design Note +==== +Ordering of properties/fields based on source code order rather than alphabetical +order is more useful. However, at this time there is no portable way to specify +source code order. Order is undefined by Java reflection. Thus the default order +has been chosen to be `UNDEFINED`. For applications which wish to remain portable +across JAXB Providers, either `XmlAccessOrder.ALPHABETICAL` or `@XmlType.propOrder()` +can be used. +==== + +* `@XmlSchema` + +==== Class + +Unless `@XmlTransient` annotation is present, +a class with a public or protected no-arg constructor must be mapped +with the following default mapping annotations: `@XmlType`. + +==== Enum type + +An enum type must be mapped with the following +default mapping annotations: + +* enum type declaration: +[none] +** `@XmlType` +** `@XmlEnum` +** `enum type {...}` +* each enum constant: +[none] +** `@XmlEnumValue (enumConstatEnum.name())` + + +==== Property / Field + +If the value of `@XmlAccessorType.value()` is +`jakarta.xml.bind.annotation.XmlAccessType.NONE`, then + +* properties and fields, unless explicitly +annotated, must be considered to be annotated with `@XmlTransient`. + +If the value of `@XmlAccessorType.value()` is +`jakarta.xml.bind.annotation.XmlAccessType.PROPERTY`, then + +* properties not explicitly annotated must be +mapped; fields, unless explicitly annotated, must be considered to be +annotated with `@XmlTransient`. + +If the value of `@XmlAccessorType.value()` is +`jakarta.xml.bind.annotation.XmlAccessType.FIELD`, then + +* fields not explicitly annotated must be +mapped; properties, unless explicitly annotated, must be considered to +be annotated with `@XmlTransient`. + +If the value of `@XmlAccessorType.value()` is +`jakarta.xml.bind.annotation.XmlAccessType.PUBLIC_MEMBER`, then + +* all properties and public fields, unless +annotated with `@XmlTransient`, must be mapped. + +See javadoc for +`@jakarta.xml.bind.annotation.XmlAccessorType` for further information on +inheritance rules for this annotation. + +===== Default Mapping + +A property name (e.g. address) must be derived +from JavaBean access method (e.g. getAddress) by JavaBean +decapitalization of the JavaBean property name. + +A single valued property or field must be +mapped with the following default mapping annotation: +[none] +** `@XmlElement` ++ +[NOTE] +.Note +==== +An alternative to mapping property or a field to an element by default is to map +property or field to an attribute if its type maps to a XML Schema simple type. +However, neither alternative is dominant. +The default has been chosen to be `@XmlElement`. +==== + +A property or field with a collection type +must be mapped by with the following default mapping annotation: + +* if the property or field is annotated with +`@XmlList`, then the default mapping annotation is: `@XmlElement` +* otherwise the default mapping annotation is: `@XmlElements( { @XmlElement(nillable=true)})` + +==== Map + +By default, `java.util.Map<K,V>` must be +mapped to the following anonymous schema type. The parameterized types K +and V must be mapped as specified in <<Type Arguments and Wildcards>>. +The anonymous schema type is at the +point of reference. + +[source,xml,indent=2] +---- +<!-- Default XML Schema mapping for Map<K,V> --> +<xs:complexType> + <xs:sequence> + <xs:element name="entry" + minOccurs ="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="key" type="xs:anyType" + minOccurs="0"/> + <xs:element name="value" type="xs:anyType" + minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> +</xs:complexType> + +<!-- Default XML Schema mapping for Map<String, Integer> --> +<xs:complexType> + <xs:sequence> + <xs:element name="entry" + minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="key" type="xs:string" + minOccurs="0"/> + <xs:element name="value" type="xs:int" + minOccurs="0"/> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> +</xs:complexType> +---- + +The mapping of Map can be customized using `@XmlJavaTypeAdapter` annotation. + +==== Multidimensional Array + +By default, a multidimensional array must be +mapped to a complex type as follows. Note the table specifies a two +dimensional array mapping. If an array is more than two dimensions, then +the mapping is used recursively. + + + +.Table 8-35 Mapping: Two dimensional array to Complex Type Definition +[cols=","] +|=== +| `{name}` | If the _basetype_ is a primitive type (e.g. +`int[][]`) or its corresponding wrapper class (e.g. `Integer[][]`), then the +name is _basetype_ concatenated with `"Array"` (e.g. `intArray`). + +otherwise if the basetype is a reference type +(e.g. `Foo[][]`), then the XML name to which the reference type is mapped +(e.g. `foo`) concatenated with `"Array"` (e.g. `fooArray`). + +| `{target namespace}` | if the _basetype_ is a primitive or its +corresponding wrapper class then `"http://jaxb.dev.java.net/array"` + +otherwise the namespace to which the reference +type is mapped (e.g. for `Foo[][]`, the namespace of the XML type to which +`Foo` is mapped). + +| `{base type definition}` | `xs:anyType` +| `{derivation method}` | `restriction` +| `{final}` | `#all` +| `{abstract}` | `false` +| `{attribute uses}` | `empty set` +| `{attribute wildcard}` | `absent` +| `{content type}` | element-only content +| `{prohibited substitutions}` | `empty set` +| `{annotations}` | `absent` +|=== + +.Table 8-36 Mapping: Two dimensional array to sequence model group +[cols=","] +|=== +| `{compositor}` | `xs:sequence` +| `{particles}` a| A repeating element defined as follows: + +[source,xml,indent=4] +---- +<xs:element name="item" + type=schematype minOccurs="0" + maxOccurs="unbounded" nillable="true"/> +---- + +where schematype is the schema to which the +array’s component type is mapped (e.g. `int[][]`, then `"xs:int"`; `Foo[][]` +then `"foo"` assuming `Foo` is mapped to the schema type `foo`. + +| `{annotation}` | `unspecified` +|=== + +=== Notes + +This section contains a collection of notes +intended to aid in the review of this version of the specification. They +are collected here in a separate section and referenced from possibly +multiple places elsewhere in the specification to make the specification +more compact. + +==== @XmlType: List simple type + +It is possible to map a homogenous collection +to a simple type with a variety of {list}. For e.g. + +[source,java,indent=4] +---- +// Code fragment +public class USStateList { + @XmlValue List <int> items; +} +---- + +// schema fragment +[source,xml,indent=4] +---- +<xs:simpleType name="USStateList"> + <xs:list itemType="int"/> +</xs:simpleType> +---- + +Other types which can be mapped to a list +simple type include: indexed property, single dimensional arrays.
diff --git a/spec/src/main/asciidoc/ch09-compatibility.adoc b/spec/src/main/asciidoc/ch09-compatibility.adoc new file mode 100644 index 0000000..3023fa1 --- /dev/null +++ b/spec/src/main/asciidoc/ch09-compatibility.adoc
@@ -0,0 +1,68 @@ +// +// Copyright (c) 2020, 2021 Contributors to the Eclipse Foundation +// + +== Compatibility + +This section describes conformance +requirements for an implementor of this specification. A JAXB +implementation must implement these constraints, without exception, to +provide a predictable environment for application development and +deployment. + +This section explicitly lists the high level +requirements of this specification. Additional requirements can be found +in other sections of this specification and the associated javadoc for +package `jakarta.xml.bind` and its subpackages. If any requirements listed +here conflict with requirements listed elsewhere in the specification, +the requirements here take precedence and replace the conflicting +requirements. + +A JAXB implementation must implement the +processing model specified in Appendix B, +<<Runtime Processing>>. + +A JAXB implementation included in a product +that supports software development must support a schema generator. A +schema generator must support all the Java Types to XML Schema mapping +specified in <<Java Types To XML>>. + +A JAXB implementation included in a product +that supports software development must support a schema compiler. All +operating modes of a schema compiler must support all the XML +Schema-to-Java bindings described in this specification. Additionally, +any operating mode must not implement a default binding for XML +Schema-to-Java bindings as an alternative to those specified in +<<Binding XML Schema to Java Representations>> nor alternative interpretations for the standard +customizations described in <<Customizing XML Schema to Java Representation Binding>>. + +The default operating mode for a schema +compiler MUST report an error when extension binding declaration is +encountered. All operating modes for a schema compiler MUST report an +error if an invalid binding customization is detected as defined in +Section 7. An extension binding declaration must be introduced in the +following cases: + +. to alter a binding customization that is +allowed to be associated with a schema element as specified in +<<Customizing XML Schema to Java Representation Binding>>. +. to associate a binding customization with a +schema element where it is disallowed as specified in +<<Customizing XML Schema to Java Representation Binding>>. + +The default operating mode for a schema +compiler MUST report an error when processing a schema that does not +comply with the 2001 W3C Recommendation for XML Schema, [XSD Part 1] and +[XSD Part 2]. + +A schema compiler MAY support non-default +operating modes for binding schema languages other than XML Schema. + +A schema compiler MUST be able to generate +Java classes that are able to run on at least one Sun's Reference +Implementation of the J2SE Java Runtime Environment that is J2SE 5 or +higher. + +A schema generator MAY support non-default +operating modes for mapping Java types to schema languages other than +XML Schema.
diff --git a/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png b/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png new file mode 100644 index 0000000..97b46ce --- /dev/null +++ b/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png Binary files differ
diff --git a/spec/src/main/asciidoc/images/xmlb-10.svg b/spec/src/main/asciidoc/images/xmlb-10.svg new file mode 100644 index 0000000..4194c14 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-10.svg
@@ -0,0 +1,133 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-10.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.12236in" + height="2.26409in" viewBox="0 0 440.81 163.015" xml:space="preserve" color-interpolation-filters="sRGB" class="st7"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st6 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="439.37" height="161.575" class="st1"/> + </g> + <g id="shape2-3" v:mID="2" v:groupContext="shape" transform="translate(193.476,-82.6413)"> + <title>Foglio.2</title> + <rect x="0" y="146.007" width="73.7008" height="17.0079" class="st2"/> + </g> + <g id="shape3-5" v:mID="3" v:groupContext="shape" transform="translate(193.476,-81.5074)"> + <title>Foglio.3</title> + <desc><<FooType>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="154.511" width="59.53" height="17.0079"/> + <rect x="0" y="146.007" width="59.5276" height="17.0079" class="st3"/> + <text x="4.63" y="156.91" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/><<FooType>></text> </g> + <g id="shape4-8" v:mID="4" v:groupContext="shape" transform="translate(237.64,80.0901) rotate(90)"> + <title>Foglio.4</title> + <path d="M0 163.01 L22.01 163.01" class="st5"/> + </g> + <g id="shape5-11" v:mID="5" v:groupContext="shape" transform="translate(71.5861,-72.6866)"> + <title>Foglio.5</title> + <path d="M5.67 163.01 L0 163.01 L2.83 153.38 L5.67 163.01 Z" class="st6"/> + </g> + <g id="shape6-13" v:mID="6" v:groupContext="shape" transform="translate(9.22394,-82.3173)"> + <title>Foglio.6</title> + <rect x="0" y="146.007" width="141.732" height="17.0079" class="st2"/> + </g> + <g id="shape7-15" v:mID="7" v:groupContext="shape" transform="translate(11.1137,-81.5074)"> + <title>Foglio.7</title> + <desc>JAXBElement<FooType></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="51.4961" cy="154.106" width="103" height="17.8178"/> + <rect x="0" y="145.197" width="102.992" height="17.8178" class="st3"/> + <text x="6.36" y="156.51" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>JAXBElement<FooType></text> </g> + <g id="shape8-18" v:mID="8" v:groupContext="shape" transform="translate(9.22394,-43.4325)"> + <title>Foglio.8</title> + <rect x="0" y="146.007" width="187.087" height="17.0079" class="st2"/> + </g> + <g id="shape9-20" v:mID="9" v:groupContext="shape" transform="translate(9.22394,-42.8656)"> + <title>Foglio.9</title> + <desc>Instance of JAXBElement<FooType></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="85.0394" cy="154.511" width="170.08" height="17.0079"/> + <rect x="0" y="146.007" width="170.079" height="17.0079" class="st3"/> + <text x="4" y="156.91" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Instance of JAXBElement<FooType></text> </g> + <g id="shape12-23" v:mID="12" v:groupContext="shape" transform="translate(188.912,-137.026)"> + <title>Foglio.12</title> + <rect x="0" y="146.007" width="239.84" height="17.0079" class="st2"/> + </g> + <g id="shape13-25" v:mID="13" v:groupContext="shape" transform="translate(218.988,-137.957)"> + <title>Foglio.13</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="80.7114" cy="154.977" width="161.43" height="16.0765"/> + <rect x="0" y="146.938" width="161.423" height="16.0765" class="st3"/> + <text x="55.81" y="157.38" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ObjectFactory</text> </g> + <g id="shape14-28" v:mID="14" v:groupContext="shape" transform="translate(188.912,-120.342)"> + <title>Foglio.14</title> + <rect x="0" y="146.007" width="239.84" height="17.0079" class="st2"/> + </g> + <g id="shape15-30" v:mID="15" v:groupContext="shape" transform="translate(188.912,-119.532)"> + <title>Foglio.15</title> + <desc>createFoo(FooType): JAXBElement<FooType></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="89.7638" cy="154.106" width="179.53" height="17.8178"/> + <rect x="0" y="145.197" width="179.528" height="17.8178" class="st3"/> + <text x="5.95" y="156.51" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>createFoo(FooType): JAXBElement<FooType></text> </g> + <g id="shape16-33" v:mID="16" v:groupContext="shape" transform="translate(151.289,-91.633)"> + <title>Foglio.16</title> + <path d="M0 163.01 L42.19 163.01" class="st5"/> + </g> + <g id="shape17-36" v:mID="17" v:groupContext="shape" transform="translate(-8.291,74.1373) rotate(-90)"> + <title>Foglio.17</title> + <path d="M5.67 163.01 L0 163.01 L2.83 159.7 L5.67 163.01 Z" class="st6"/> + </g> + <g id="shape18-38" v:mID="18" v:groupContext="shape" transform="translate(317.739,74.1373) rotate(90) scale(-1,1)"> + <title>Foglio.18</title> + <path d="M5.67 163.01 L0 163.01 L2.83 159.7 L5.67 163.01 Z" class="st6"/> + </g> + <g id="shape19-40" v:mID="19" v:groupContext="shape" transform="translate(155.208,-90.0113)"> + <title>Foglio.19</title> + <desc>1...1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.9197" cy="154.511" width="23.84" height="17.0079"/> + <rect x="0" y="146.007" width="23.8394" height="17.0079" class="st3"/> + <text x="4" y="156.91" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1...1</text> </g> + <g id="shape20-43" v:mID="20" v:groupContext="shape" transform="translate(9.22394,-9.22394)"> + <title>Foglio.20</title> + <rect x="0" y="128.999" width="187.087" height="34.0157" class="st2"/> + </g> + <g id="shape21-45" v:mID="21" v:groupContext="shape" transform="translate(9.22394,-25.6649)"> + <title>Foglio.21</title> + <desc>name=Qname(“ns”, “foo”, “un”);</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="85.0394" cy="154.511" width="170.08" height="17.0079"/> + <rect x="0" y="146.007" width="170.079" height="17.0079" class="st3"/> + <text x="4" y="156.91" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>name=Qname(“ns”, “foo”, “un”);</text> </g> + <g id="shape22-48" v:mID="22" v:groupContext="shape" transform="translate(9.22394,-12.0586)"> + <title>Foglio.22</title> + <desc>value=instanceOf<<FooType>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="85.0394" cy="154.511" width="170.08" height="17.0079"/> + <rect x="0" y="146.007" width="170.079" height="17.0079" class="st3"/> + <text x="4" y="156.91" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>value=instanceOf<<FooType>></text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-11.svg b/spec/src/main/asciidoc/images/xmlb-11.svg new file mode 100644 index 0000000..b1da7b3 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-11.svg
@@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-11.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.12236in" + height="1.79165in" viewBox="0 0 440.81 128.999" xml:space="preserve" color-interpolation-filters="sRGB" class="st7"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st6 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="439.37" height="127.559" class="st1"/> + </g> + <g id="shape2-3" v:mID="2" v:groupContext="shape" transform="translate(193.476,-48.6255)"> + <title>Foglio.2</title> + <rect x="0" y="111.991" width="73.7008" height="17.0079" class="st2"/> + </g> + <g id="shape3-5" v:mID="3" v:groupContext="shape" transform="translate(193.476,-47.4917)"> + <title>Foglio.3</title> + <desc><<FooType>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="120.495" width="59.53" height="17.0079"/> + <rect x="0" y="111.991" width="59.5276" height="17.0079" class="st3"/> + <text x="4.63" y="122.9" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/><<FooType>></text> </g> + <g id="shape4-8" v:mID="4" v:groupContext="shape" transform="translate(203.624,80.0901) rotate(90)"> + <title>Foglio.4</title> + <path d="M0 129 L22.01 129" class="st5"/> + </g> + <g id="shape5-11" v:mID="5" v:groupContext="shape" transform="translate(71.5861,-38.6709)"> + <title>Foglio.5</title> + <path d="M5.67 129 L0 129 L2.83 119.36 L5.67 129 Z" class="st6"/> + </g> + <g id="shape6-13" v:mID="6" v:groupContext="shape" transform="translate(9.22394,-48.3016)"> + <title>Foglio.6</title> + <rect x="0" y="111.991" width="141.732" height="17.0079" class="st2"/> + </g> + <g id="shape7-15" v:mID="7" v:groupContext="shape" transform="translate(11.1137,-47.4917)"> + <title>Foglio.7</title> + <desc>JAXBElement<FooType></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="51.4961" cy="120.09" width="103" height="17.8178"/> + <rect x="0" y="111.181" width="102.992" height="17.8178" class="st3"/> + <text x="6.36" y="122.49" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>JAXBElement<FooType></text> </g> + <g id="shape8-18" v:mID="8" v:groupContext="shape" transform="translate(42.2948,-9.41677)"> + <title>Foglio.8</title> + <rect x="0" y="111.991" width="62.3622" height="17.0079" class="st2"/> + </g> + <g id="shape9-20" v:mID="9" v:groupContext="shape" transform="translate(60.2476,-8.84985)"> + <title>Foglio.9</title> + <desc>Foo</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="25.5118" cy="120.495" width="51.03" height="17.0079"/> + <rect x="0" y="111.991" width="51.0236" height="17.0079" class="st3"/> + <text x="4" y="122.9" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Foo</text> </g> + <g id="shape12-23" v:mID="12" v:groupContext="shape" transform="translate(188.912,-103.01)"> + <title>Foglio.12</title> + <rect x="0" y="111.991" width="239.84" height="17.0079" class="st2"/> + </g> + <g id="shape13-25" v:mID="13" v:groupContext="shape" transform="translate(218.988,-103.942)"> + <title>Foglio.13</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="80.7114" cy="120.961" width="161.43" height="16.0765"/> + <rect x="0" y="112.923" width="161.423" height="16.0765" class="st3"/> + <text x="55.81" y="123.36" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ObjectFactory</text> </g> + <g id="shape14-28" v:mID="14" v:groupContext="shape" transform="translate(188.912,-86.3263)"> + <title>Foglio.14</title> + <rect x="0" y="111.991" width="239.84" height="17.0079" class="st2"/> + </g> + <g id="shape15-30" v:mID="15" v:groupContext="shape" transform="translate(188.912,-85.5164)"> + <title>Foglio.15</title> + <desc>createFoo(FooType): JAXBElement<FooType></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="89.7638" cy="120.09" width="179.53" height="17.8178"/> + <rect x="0" y="111.181" width="179.528" height="17.8178" class="st3"/> + <text x="5.95" y="122.49" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>createFoo(FooType): JAXBElement<FooType></text> </g> + <g id="shape16-33" v:mID="16" v:groupContext="shape" transform="translate(151.289,-57.6173)"> + <title>Foglio.16</title> + <path d="M0 129 L42.19 129" class="st5"/> + </g> + <g id="shape17-36" v:mID="17" v:groupContext="shape" transform="translate(25.7248,74.1373) rotate(-90)"> + <title>Foglio.17</title> + <path d="M5.67 129 L0 129 L2.83 125.68 L5.67 129 Z" class="st6"/> + </g> + <g id="shape18-38" v:mID="18" v:groupContext="shape" transform="translate(283.723,74.1373) rotate(90) scale(-1,1)"> + <title>Foglio.18</title> + <path d="M5.67 129 L0 129 L2.83 125.68 L5.67 129 Z" class="st6"/> + </g> + <g id="shape19-40" v:mID="19" v:groupContext="shape" transform="translate(155.208,-55.9956)"> + <title>Foglio.19</title> + <desc>1...1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.9197" cy="120.495" width="23.84" height="17.0079"/> + <rect x="0" y="111.991" width="23.8394" height="17.0079" class="st3"/> + <text x="4" y="122.9" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1...1</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-12.svg b/spec/src/main/asciidoc/images/xmlb-12.svg new file mode 100644 index 0000000..e5a4817 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-12.svg
@@ -0,0 +1,453 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-12.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.33496in" + height="3.99638in" viewBox="0 0 384.117 287.739" xml:space="preserve" color-interpolation-filters="sRGB" class="st11"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {fill:#000000;font-family:Arial;font-size:0.666664em;font-weight:bold} + .st6 {font-size:1em} + .st7 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#ffffff;stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {font-size:1em;font-weight:bold} + .st11 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="382.677" height="286.299" class="st1"/> + </g> + <g id="shape6-3" v:mID="6" v:groupContext="shape" transform="translate(131.114,-116.94)"> + <title>Foglio.6</title> + <rect x="0" y="270.731" width="116.22" height="17.0079" class="st2"/> + </g> + <g id="shape7-5" v:mID="7" v:groupContext="shape" transform="translate(133.003,-116.131)"> + <title>Foglio.7</title> + <desc>ConstraintPredicate</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="42.9921" cy="278.83" width="85.99" height="17.8178"/> + <rect x="0" y="269.921" width="85.9843" height="17.8178" class="st3"/> + <text x="7.86" y="281.23" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ConstraintPredicate</text> </g> + <g id="shape8-8" v:mID="8" v:groupContext="shape" transform="translate(9.64913,-77.2554)"> + <title>Foglio.8</title> + <rect x="0" y="260.038" width="109.134" height="27.7017" class="st2"/> + </g> + <g id="shape9-10" v:mID="9" v:groupContext="shape" transform="translate(14.1846,-81.1728)"> + <title>Foglio.9</title> + <desc>javax.xml.bind JAXBElement</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="4" y="274.54" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>javax.xml.bind<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">JAXBElement</tspan></text> </g> + <g id="shape12-14" v:mID="12" v:groupContext="shape" transform="translate(29.0665,-185.458)"> + <title>Foglio.12</title> + <rect x="0" y="279.721" width="189.921" height="8.018" class="st2"/> + </g> + <g id="shape14-16" v:mID="14" v:groupContext="shape" transform="translate(29.0665,-159.46)"> + <title>Foglio.14</title> + <rect x="0" y="261.418" width="189.921" height="26.3217" class="st2"/> + </g> + <g id="shape15-18" v:mID="15" v:groupContext="shape" transform="translate(29.0665,-159.055)"> + <title>Foglio.15</title> + <desc>elementFactory(T): JAXBElement<T></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="78.9177" cy="280.45" width="157.84" height="14.5782"/> + <rect x="0" y="273.161" width="157.835" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>elementFactory(T): JAXBElement<T></text> </g> + <g id="shape20-21" v:mID="20" v:groupContext="shape" transform="translate(9.64913,-12.9601)"> + <title>Foglio.20</title> + <rect x="0" y="223.96" width="109.134" height="63.7795" class="st2"/> + </g> + <g id="shape21-23" v:mID="21" v:groupContext="shape" transform="translate(8.79874,-59.1648)"> + <title>Foglio.21</title> + <desc>*name : Qname</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="279.235" width="104.89" height="17.0079"/> + <rect x="0" y="270.731" width="104.882" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*name : Qname</text> </g> + <g id="shape22-26" v:mID="22" v:groupContext="shape" transform="translate(9.64913,-52.6451)"> + <title>Foglio.22</title> + <desc>*value : T</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*value : T</text> </g> + <g id="shape23-29" v:mID="23" v:groupContext="shape" transform="translate(29.0665,-170.799)"> + <title>Foglio.23</title> + <desc>typeFactory()</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.0157" cy="280.45" width="68.04" height="14.5782"/> + <rect x="0" y="273.161" width="68.0315" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>typeFactory() </text> </g> + <g id="shape24-32" v:mID="24" v:groupContext="shape" transform="translate(29.0665,-193.476)"> + <title>Foglio.24</title> + <rect x="0" y="270.731" width="189.921" height="17.0079" class="st2"/> + </g> + <g id="shape25-34" v:mID="25" v:groupContext="shape" transform="translate(29.0665,-194.407)"> + <title>Foglio.25</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="85.4223" cy="279.701" width="170.85" height="16.0765"/> + <rect x="0" y="271.663" width="170.845" height="16.0765" class="st3"/> + <text x="58.53" y="282.1" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ObjectFactory</text> </g> + <g id="shape13-37" v:mID="13" v:groupContext="shape" transform="translate(38.5553,-257.012)"> + <title>Foglio.13</title> + <rect x="0" y="282.839" width="89.7237" height="4.89989" class="st2"/> + </g> + <g id="shape26-39" v:mID="26" v:groupContext="shape" transform="translate(38.5553,-253.003)"> + <title>Foglio.26</title> + <rect x="0" y="283.532" width="89.7237" height="4.20697" class="st2"/> + </g> + <g id="shape29-41" v:mID="29" v:groupContext="shape" transform="translate(38.5553,-261.912)"> + <title>Foglio.29</title> + <rect x="0" y="270.731" width="89.7237" height="17.0079" class="st2"/> + </g> + <g id="shape30-43" v:mID="30" v:groupContext="shape" transform="translate(47.0752,-262.844)"> + <title>Foglio.30</title> + <desc>EnumType</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.0149" cy="279.701" width="66.03" height="16.0765"/> + <rect x="0" y="271.663" width="66.0297" height="16.0765" class="st3"/> + <text x="4" y="282.1" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>EnumType</text> </g> + <g id="shape27-46" v:mID="27" v:groupContext="shape" transform="translate(188.792,-253.489)"> + <title>Foglio.27</title> + <rect x="0" y="279.721" width="89.7237" height="8.018" class="st2"/> + </g> + <g id="shape28-48" v:mID="28" v:groupContext="shape" transform="translate(188.792,-246.929)"> + <title>Foglio.28</title> + <rect x="0" y="280.855" width="89.7237" height="6.88414" class="st2"/> + </g> + <g id="shape31-50" v:mID="31" v:groupContext="shape" transform="translate(188.792,-261.507)"> + <title>Foglio.31</title> + <rect x="0" y="270.731" width="89.7237" height="17.0079" class="st2"/> + </g> + <g id="shape32-52" v:mID="32" v:groupContext="shape" transform="translate(197.311,-262.439)"> + <title>Foglio.32</title> + <desc>Package</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.0149" cy="279.701" width="66.03" height="16.0765"/> + <rect x="0" y="271.663" width="66.0297" height="16.0765" class="st3"/> + <text x="4" y="282.1" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Package</text> </g> + <g id="shape33-55" v:mID="33" v:groupContext="shape" transform="translate(228.477,-170.799)"> + <title>Foglio.33</title> + <rect x="0" y="279.721" width="103.897" height="8.018" class="st2"/> + </g> + <g id="shape34-57" v:mID="34" v:groupContext="shape" transform="translate(228.477,-178.29)"> + <title>Foglio.34</title> + <rect x="0" y="272.554" width="103.897" height="15.1856" class="st2"/> + </g> + <g id="shape36-59" v:mID="36" v:groupContext="shape" transform="translate(228.477,-178.493)"> + <title>Foglio.36</title> + <desc>*abstract: boolean</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="51.9485" cy="280.45" width="103.9" height="14.5782"/> + <rect x="0" y="273.161" width="103.897" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*abstract: boolean</text> </g> + <g id="shape37-62" v:mID="37" v:groupContext="shape" transform="translate(228.477,-193.678)"> + <title>Foglio.37</title> + <rect x="0" y="270.731" width="103.897" height="17.0079" class="st2"/> + </g> + <g id="shape38-64" v:mID="38" v:groupContext="shape" transform="translate(229.493,-194.61)"> + <title>Foglio.38</title> + <desc>ValueClass</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="41.5188" cy="279.701" width="83.04" height="16.0765"/> + <rect x="0" y="271.663" width="83.0376" height="16.0765" class="st3"/> + <text x="20.17" y="282.1" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ValueClass</text> </g> + <g id="shape35-67" v:mID="35" v:groupContext="shape" transform="translate(188.792,-265.964) scale(-1,1)"> + <title>Foglio.35</title> + <path d="M0 287.74 L60.51 287.74" class="st7"/> + </g> + <g id="shape39-70" v:mID="39" v:groupContext="shape" transform="translate(472.711,24.531) rotate(90) scale(-1,1)"> + <title>Foglio.39</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape40-72" v:mID="40" v:groupContext="shape" transform="translate(-102.767,24.531) rotate(-90)"> + <title>Foglio.40</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape41-74" v:mID="41" v:groupContext="shape" transform="translate(165.129,-266.468) scale(-1,1)"> + <title>Foglio.41</title> + <desc>0…*</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.9197" cy="282.779" width="23.84" height="9.92126"/> + <rect x="0" y="277.818" width="23.8394" height="9.92126" class="st3"/> + <text x="-19.84" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…*</text> </g> + <g id="shape42-77" v:mID="42" v:groupContext="shape" transform="translate(-81.5074,40.81) rotate(-90) scale(-1,1)"> + <title>Foglio.42</title> + <path d="M0 287.74 L36.45 287.74" class="st7"/> + </g> + <g id="shape43-80" v:mID="43" v:groupContext="shape" transform="translate(209.066,-243.283) scale(-1,1)"> + <title>Foglio.43</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape44-82" v:mID="44" v:groupContext="shape" transform="translate(209.066,332.195) rotate(180)"> + <title>Foglio.44</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape45-84" v:mID="45" v:groupContext="shape" transform="translate(203.411,-223.098) scale(-1,1)"> + <title>Foglio.45</title> + <desc>1…1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="12.7701" cy="282.779" width="25.55" height="9.92126"/> + <rect x="0" y="277.818" width="25.5402" height="9.92126" class="st3"/> + <text x="-21.54" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1…1</text> </g> + <g id="shape46-87" v:mID="46" v:groupContext="shape" transform="translate(-18.3515,40.8503) rotate(-90) scale(-1,1)"> + <title>Foglio.46</title> + <path d="M0 287.74 L36.45 287.74" class="st7"/> + </g> + <g id="shape47-90" v:mID="47" v:groupContext="shape" transform="translate(272.222,-243.243) scale(-1,1)"> + <title>Foglio.47</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape48-92" v:mID="48" v:groupContext="shape" transform="translate(272.222,332.236) rotate(180)"> + <title>Foglio.48</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape49-94" v:mID="49" v:groupContext="shape" transform="translate(264.342,-223.098) scale(-1,1)"> + <title>Foglio.49</title> + <desc>0…*</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.9197" cy="282.779" width="23.84" height="9.92126"/> + <rect x="0" y="277.818" width="23.8394" height="9.92126" class="st3"/> + <text x="-19.84" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…*</text> </g> + <g id="shape50-97" v:mID="50" v:groupContext="shape" transform="translate(-53.1468,117.345) rotate(-90) scale(-1,1)"> + <title>Foglio.50</title> + <path d="M0 287.74 L36.45 287.74" class="st7"/> + </g> + <g id="shape51-100" v:mID="51" v:groupContext="shape" transform="translate(237.427,-166.748) scale(-1,1)"> + <title>Foglio.51</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape52-102" v:mID="52" v:groupContext="shape" transform="translate(237.427,408.731) rotate(180)"> + <title>Foglio.52</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape53-104" v:mID="53" v:groupContext="shape" transform="translate(231.744,-143.161) scale(-1,1)"> + <title>Foglio.53</title> + <desc>1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="5.68346" cy="282.779" width="11.37" height="9.92126"/> + <rect x="0" y="277.818" width="11.3669" height="9.92126" class="st3"/> + <text x="-7.37" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1</text> </g> + <g id="shape54-107" v:mID="54" v:groupContext="shape" transform="translate(231.035,-134.046)"> + <title>Foglio.54</title> + <path d="M0 279.2 L3.63 287.74 L7.09 279.2" class="st7"/> + </g> + <g id="shape55-110" v:mID="55" v:groupContext="shape" transform="translate(34.0186,117.345) rotate(-90) scale(-1,1)"> + <title>Foglio.55</title> + <path d="M0 287.74 L64.82 287.74" class="st7"/> + </g> + <g id="shape56-113" v:mID="56" v:groupContext="shape" transform="translate(324.592,-166.748) scale(-1,1)"> + <title>Foglio.56</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape57-115" v:mID="57" v:groupContext="shape" transform="translate(324.592,408.731) rotate(180)"> + <title>Foglio.57</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape58-117" v:mID="58" v:groupContext="shape" transform="translate(349.381,-143.161) scale(-1,1)"> + <title>Foglio.58</title> + <desc>0…*</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="13.4646" cy="282.779" width="26.93" height="9.92126"/> + <rect x="0" y="277.818" width="26.9291" height="9.92126" class="st3"/> + <text x="-22.93" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…*</text> </g> + <g id="shape60-120" v:mID="60" v:groupContext="shape" transform="translate(113.369,-94.2633)"> + <title>Foglio.60</title> + <path d="M0 287.74 L12.5 287.74 L12.5 270.73 L0 270.73 L0 287.74 Z" class="st9"/> + </g> + <g id="shape59-122" v:mID="59" v:groupContext="shape" transform="translate(123.29,-98.2602) scale(-1,1)"> + <title>Foglio.59</title> + <desc>T</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="5.68346" cy="282.779" width="11.37" height="9.92126"/> + <rect x="0" y="277.818" width="11.3669" height="9.92126" class="st3"/> + <text x="-7.37" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>T</text> </g> + <g id="shape61-125" v:mID="61" v:groupContext="shape" transform="translate(9.36567,-36.4876)"> + <title>Foglio.61</title> + <desc>*isNil : boolean</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="279.235" width="104.89" height="17.0079"/> + <rect x="0" y="270.731" width="104.882" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*isNil : boolean</text> </g> + <g id="shape62-128" v:mID="62" v:groupContext="shape" transform="translate(9.36567,-29.968)"> + <title>Foglio.62</title> + <desc>*type : Class</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*type : Class</text> </g> + <g id="shape63-131" v:mID="63" v:groupContext="shape" transform="translate(9.64913,-17.779)"> + <title>Foglio.63</title> + <desc>*scope : Class</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*scope : Class</text> </g> + <g id="shape64-134" v:mID="64" v:groupContext="shape" transform="translate(9.64913,-5.87347)"> + <title>Foglio.64</title> + <rect x="0" y="280.911" width="109.134" height="6.8287" class="st2"/> + </g> + <g id="shape65-136" v:mID="65" v:groupContext="shape" transform="translate(135.791,-77.2554)"> + <title>Foglio.65</title> + <rect x="0" y="260.038" width="109.134" height="27.7017" class="st2"/> + </g> + <g id="shape66-138" v:mID="66" v:groupContext="shape" transform="translate(140.326,-81.1728)"> + <title>Foglio.66</title> + <desc><<enumeration>> PropertyStyle</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="4" y="274.54" class="st4" v:langID="1040"><v:paragraph/><v:tabList/><<enumeration>><v:newlineChar/><tspan + x="4" dy="1.2em" class="st10">PropertyStyle</tspan></text> </g> + <g id="shape67-142" v:mID="67" v:groupContext="shape" transform="translate(135.791,-12.9601)"> + <title>Foglio.67</title> + <rect x="0" y="223.96" width="109.134" height="63.7795" class="st2"/> + </g> + <g id="shape68-144" v:mID="68" v:groupContext="shape" transform="translate(152.94,-59.1648)"> + <title>Foglio.68</title> + <desc>*Simple</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="279.235" width="45.84" height="17.0079"/> + <rect x="0" y="270.731" width="45.8331" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Simple</text> </g> + <g id="shape69-147" v:mID="69" v:groupContext="shape" transform="translate(153.312,-52.6451)"> + <title>Foglio.69</title> + <desc>*List</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*List</text> </g> + <g id="shape72-150" v:mID="72" v:groupContext="shape" transform="translate(153.188,-36.4876)"> + <title>Foglio.72</title> + <desc>*Indexed</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="279.235" width="45.84" height="17.0079"/> + <rect x="0" y="270.731" width="45.8331" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Indexed</text> </g> + <g id="shape73-153" v:mID="73" v:groupContext="shape" transform="translate(153.188,-29.968)"> + <title>Foglio.73</title> + <desc>*Constant</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Constant</text> </g> + <g id="shape74-156" v:mID="74" v:groupContext="shape" transform="translate(153.312,-17.779)"> + <title>Foglio.74</title> + <desc>*Element</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Element</text> </g> + <g id="shape75-159" v:mID="75" v:groupContext="shape" transform="translate(135.791,-5.87347)"> + <title>Foglio.75</title> + <rect x="0" y="280.911" width="109.134" height="6.8287" class="st2"/> + </g> + <g id="shape70-161" v:mID="70" v:groupContext="shape" transform="translate(260.799,-77.9002)"> + <title>Foglio.70</title> + <rect x="0" y="260.038" width="116.929" height="27.7017" class="st2"/> + </g> + <g id="shape71-163" v:mID="71" v:groupContext="shape" transform="translate(260.799,-82.9247)"> + <title>Foglio.71</title> + <desc>Property</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="23.24" y="279.34" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Property</text> </g> + <g id="shape76-166" v:mID="76" v:groupContext="shape" transform="translate(260.799,-13.4759)"> + <title>Foglio.76</title> + <rect x="0" y="223.96" width="116.929" height="63.7795" class="st2"/> + </g> + <g id="shape77-168" v:mID="77" v:groupContext="shape" transform="translate(261.082,-59.6806)"> + <title>Foglio.77</title> + <desc>*style : PropertyStyle</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="279.235" width="108.68" height="17.0079"/> + <rect x="0" y="270.731" width="108.678" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*style : PropertyStyle</text> </g> + <g id="shape78-171" v:mID="78" v:groupContext="shape" transform="translate(261.963,-53.1609)"> + <title>Foglio.78</title> + <desc>*baseType: String</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*baseType: String</text> </g> + <g id="shape79-174" v:mID="79" v:groupContext="shape" transform="translate(261.67,-37.0035)"> + <title>Foglio.79</title> + <desc>*collectionType: String</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="279.235" width="108.68" height="17.0079"/> + <rect x="0" y="270.731" width="108.678" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*collectionType: String</text> </g> + <g id="shape80-177" v:mID="80" v:groupContext="shape" transform="translate(261.67,-30.4838)"> + <title>Foglio.80</title> + <desc>*defaultValue: Object</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*defaultValue: Object</text> </g> + <g id="shape81-180" v:mID="81" v:groupContext="shape" transform="translate(261.963,-18.2948)"> + <title>Foglio.81</title> + <desc>*unsettable: boolean</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*unsettable: boolean</text> </g> + <g id="shape82-183" v:mID="82" v:groupContext="shape" transform="translate(260.799,-6.38929)"> + <title>Foglio.82</title> + <rect x="0" y="280.911" width="116.929" height="6.8287" class="st2"/> + </g> + <g id="shape83-185" v:mID="83" v:groupContext="shape" transform="translate(571.881,182.137) rotate(90) scale(-1,1)"> + <title>Foglio.83</title> + <path d="M0 287.74 L21.26 287.74" class="st7"/> + </g> + <g id="shape84-188" v:mID="84" v:groupContext="shape" transform="translate(281.307,466.23) scale(1,-1)"> + <title>Foglio.84</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape85-190" v:mID="85" v:groupContext="shape" transform="translate(281.307,-109.248)"> + <title>Foglio.85</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape87-192" v:mID="87" v:groupContext="shape" transform="translate(535.073,157.334) rotate(90)"> + <title>Foglio.87</title> + <path d="M0 279.2 L3.63 287.74 L7.09 279.2" class="st7"/> + </g> + <g id="shape86-195" v:mID="86" v:groupContext="shape" transform="translate(311.822,-117.649) scale(-1,1)"> + <title>Foglio.86</title> + <desc>0…1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="13.4646" cy="282.779" width="26.93" height="9.92126"/> + <rect x="0" y="277.818" width="26.9291" height="9.92126" class="st3"/> + <text x="-22.93" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…1</text> </g> + <g id="shape88-198" v:mID="88" v:groupContext="shape" transform="translate(247.334,448.617) scale(1,-1)"> + <title>Foglio.88</title> + <path d="M0 287.74 L36.81 287.74" class="st7"/> + </g> + <g id="shape89-201" v:mID="89" v:groupContext="shape" transform="translate(95.3148,-170.799)"> + <title>Foglio.89</title> + <desc>: ValueClass</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="30.1296" cy="280.45" width="60.26" height="14.5782"/> + <rect x="0" y="273.161" width="60.2592" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>: ValueClass</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-13.svg b/spec/src/main/asciidoc/images/xmlb-13.svg new file mode 100644 index 0000000..9472b50 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-13.svg
@@ -0,0 +1,441 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-13.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.57118in" + height="3.99638in" viewBox="0 0 401.125 287.739" xml:space="preserve" color-interpolation-filters="sRGB" class="st12"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {fill:#000000;font-family:Arial;font-size:0.666664em;font-weight:bold} + .st6 {font-size:1em} + .st7 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#ffffff;stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {font-size:1em;font-weight:bold} + .st11 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic} + .st12 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="399.685" height="286.299" class="st1"/> + </g> + <g id="shape6-3" v:mID="6" v:groupContext="shape" transform="translate(148.122,-116.94)"> + <title>Foglio.6</title> + <rect x="0" y="270.731" width="116.22" height="17.0079" class="st2"/> + </g> + <g id="shape7-5" v:mID="7" v:groupContext="shape" transform="translate(150.011,-116.131)"> + <title>Foglio.7</title> + <desc>ConstraintPredicate</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="42.9921" cy="278.83" width="85.99" height="17.8178"/> + <rect x="0" y="269.921" width="85.9843" height="17.8178" class="st3"/> + <text x="7.86" y="281.23" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ConstraintPredicate</text> </g> + <g id="shape8-8" v:mID="8" v:groupContext="shape" transform="translate(7.23969,-152.631)"> + <title>Foglio.8</title> + <rect x="0" y="260.038" width="109.134" height="27.7017" class="st2"/> + </g> + <g id="shape9-10" v:mID="9" v:groupContext="shape" transform="translate(11.7751,-156.549)"> + <title>Foglio.9</title> + <desc>javax.xml.bind JAXBElement</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="4" y="274.54" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>javax.xml.bind<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">JAXBElement</tspan></text> </g> + <g id="shape12-14" v:mID="12" v:groupContext="shape" transform="translate(4.97197,-219.676)"> + <title>Foglio.12</title> + <rect x="0" y="279.721" width="189.921" height="8.018" class="st2"/> + </g> + <g id="shape14-16" v:mID="14" v:groupContext="shape" transform="translate(4.97197,-193.678)"> + <title>Foglio.14</title> + <rect x="0" y="261.418" width="189.921" height="26.3217" class="st2"/> + </g> + <g id="shape15-18" v:mID="15" v:groupContext="shape" transform="translate(4.97197,-193.273)"> + <title>Foglio.15</title> + <desc>elementFactory(T): JAXBElement<T></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="78.9177" cy="280.45" width="157.84" height="14.5782"/> + <rect x="0" y="273.161" width="157.835" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>elementFactory(T): JAXBElement<T></text> </g> + <g id="shape20-21" v:mID="20" v:groupContext="shape" transform="translate(7.23969,-88.3361)"> + <title>Foglio.20</title> + <rect x="0" y="223.96" width="109.134" height="63.7795" class="st2"/> + </g> + <g id="shape21-23" v:mID="21" v:groupContext="shape" transform="translate(6.38929,-134.541)"> + <title>Foglio.21</title> + <desc>*name : Qname</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="279.235" width="104.89" height="17.0079"/> + <rect x="0" y="270.731" width="104.882" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*name : Qname</text> </g> + <g id="shape22-26" v:mID="22" v:groupContext="shape" transform="translate(7.23969,-128.021)"> + <title>Foglio.22</title> + <desc>*value : T</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*value : T</text> </g> + <g id="shape23-29" v:mID="23" v:groupContext="shape" transform="translate(4.97197,-205.017)"> + <title>Foglio.23</title> + <desc>typeFactory()</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.0157" cy="280.45" width="68.04" height="14.5782"/> + <rect x="0" y="273.161" width="68.0315" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>typeFactory() </text> </g> + <g id="shape27-32" v:mID="27" v:groupContext="shape" transform="translate(205.799,-253.489)"> + <title>Foglio.27</title> + <rect x="0" y="279.721" width="89.7237" height="8.018" class="st2"/> + </g> + <g id="shape28-34" v:mID="28" v:groupContext="shape" transform="translate(205.799,-246.929)"> + <title>Foglio.28</title> + <rect x="0" y="280.855" width="89.7237" height="6.88414" class="st2"/> + </g> + <g id="shape31-36" v:mID="31" v:groupContext="shape" transform="translate(205.799,-261.507)"> + <title>Foglio.31</title> + <rect x="0" y="270.731" width="89.7237" height="17.0079" class="st2"/> + </g> + <g id="shape32-38" v:mID="32" v:groupContext="shape" transform="translate(214.319,-262.439)"> + <title>Foglio.32</title> + <desc>Package</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.0149" cy="279.701" width="66.03" height="16.0765"/> + <rect x="0" y="271.663" width="66.0297" height="16.0765" class="st3"/> + <text x="4" y="282.1" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Package</text> </g> + <g id="shape33-41" v:mID="33" v:groupContext="shape" transform="translate(245.484,-170.799)"> + <title>Foglio.33</title> + <rect x="0" y="279.721" width="103.897" height="8.018" class="st2"/> + </g> + <g id="shape34-43" v:mID="34" v:groupContext="shape" transform="translate(245.484,-178.29)"> + <title>Foglio.34</title> + <rect x="0" y="272.554" width="103.897" height="15.1856" class="st2"/> + </g> + <g id="shape37-45" v:mID="37" v:groupContext="shape" transform="translate(245.484,-193.678)"> + <title>Foglio.37</title> + <rect x="0" y="270.731" width="103.897" height="17.0079" class="st2"/> + </g> + <g id="shape38-47" v:mID="38" v:groupContext="shape" transform="translate(246.501,-194.61)"> + <title>Foglio.38</title> + <desc>Element</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="41.5188" cy="279.701" width="83.04" height="16.0765"/> + <rect x="0" y="271.663" width="83.0376" height="16.0765" class="st3"/> + <text x="25.96" y="282.1" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Element</text> </g> + <g id="shape42-50" v:mID="42" v:groupContext="shape" transform="translate(-119.775,27.4482) rotate(-90) scale(-1,1)"> + <title>Foglio.42</title> + <path d="M0 287.74 L26.93 287.74" class="st7"/> + </g> + <g id="shape43-53" v:mID="43" v:groupContext="shape" transform="translate(489.719,30.2829) rotate(90) scale(-1,1)"> + <title>Foglio.43</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape44-55" v:mID="44" v:groupContext="shape" transform="translate(-85.7594,30.2829) rotate(-90)"> + <title>Foglio.44</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape45-57" v:mID="45" v:groupContext="shape" transform="translate(163.74,-251.586) scale(-1,1)"> + <title>Foglio.45</title> + <desc>1…1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="12.7701" cy="282.779" width="25.55" height="9.92126"/> + <rect x="0" y="277.818" width="25.5402" height="9.92126" class="st3"/> + <text x="-21.54" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1…1</text> </g> + <g id="shape46-60" v:mID="46" v:groupContext="shape" transform="translate(-1.34362,40.8503) rotate(-90) scale(-1,1)"> + <title>Foglio.46</title> + <path d="M0 287.74 L36.45 287.74" class="st7"/> + </g> + <g id="shape47-63" v:mID="47" v:groupContext="shape" transform="translate(289.23,-243.243) scale(-1,1)"> + <title>Foglio.47</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape48-65" v:mID="48" v:groupContext="shape" transform="translate(289.23,332.236) rotate(180)"> + <title>Foglio.48</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape49-67" v:mID="49" v:groupContext="shape" transform="translate(281.35,-223.098) scale(-1,1)"> + <title>Foglio.49</title> + <desc>0…*</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.9197" cy="282.779" width="23.84" height="9.92126"/> + <rect x="0" y="277.818" width="23.8394" height="9.92126" class="st3"/> + <text x="-19.84" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…*</text> </g> + <g id="shape50-70" v:mID="50" v:groupContext="shape" transform="translate(-36.1389,117.345) rotate(-90) scale(-1,1)"> + <title>Foglio.50</title> + <path d="M0 287.74 L36.45 287.74" class="st7"/> + </g> + <g id="shape53-73" v:mID="53" v:groupContext="shape" transform="translate(248.751,-143.161) scale(-1,1)"> + <title>Foglio.53</title> + <desc>1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="5.68346" cy="282.779" width="11.37" height="9.92126"/> + <rect x="0" y="277.818" width="11.3669" height="9.92126" class="st3"/> + <text x="-7.37" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>1</text> </g> + <g id="shape54-76" v:mID="54" v:groupContext="shape" transform="translate(248.043,-134.046)"> + <title>Foglio.54</title> + <path d="M0 279.2 L3.63 287.74 L7.09 279.2" class="st7"/> + </g> + <g id="shape55-79" v:mID="55" v:groupContext="shape" transform="translate(51.0265,117.345) rotate(-90) scale(-1,1)"> + <title>Foglio.55</title> + <path d="M0 287.74 L64.82 287.74" class="st7"/> + </g> + <g id="shape56-82" v:mID="56" v:groupContext="shape" transform="translate(341.6,-166.748) scale(-1,1)"> + <title>Foglio.56</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape57-84" v:mID="57" v:groupContext="shape" transform="translate(341.6,408.731) rotate(180)"> + <title>Foglio.57</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape58-86" v:mID="58" v:groupContext="shape" transform="translate(366.389,-143.161) scale(-1,1)"> + <title>Foglio.58</title> + <desc>0…*</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="13.4646" cy="282.779" width="26.93" height="9.92126"/> + <rect x="0" y="277.818" width="26.9291" height="9.92126" class="st3"/> + <text x="-22.93" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…*</text> </g> + <g id="shape60-89" v:mID="60" v:groupContext="shape" transform="translate(110.959,-169.639)"> + <title>Foglio.60</title> + <path d="M0 287.74 L12.5 287.74 L12.5 270.73 L0 270.73 L0 287.74 Z" class="st9"/> + </g> + <g id="shape59-91" v:mID="59" v:groupContext="shape" transform="translate(120.881,-173.636) scale(-1,1)"> + <title>Foglio.59</title> + <desc>T</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="5.68346" cy="282.779" width="11.37" height="9.92126"/> + <rect x="0" y="277.818" width="11.3669" height="9.92126" class="st3"/> + <text x="-7.37" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>T</text> </g> + <g id="shape61-94" v:mID="61" v:groupContext="shape" transform="translate(6.95622,-111.864)"> + <title>Foglio.61</title> + <desc>*isNil : boolean</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="279.235" width="104.89" height="17.0079"/> + <rect x="0" y="270.731" width="104.882" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*isNil : boolean</text> </g> + <g id="shape62-97" v:mID="62" v:groupContext="shape" transform="translate(6.95622,-105.344)"> + <title>Foglio.62</title> + <desc>*type : Class</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*type : Class</text> </g> + <g id="shape63-100" v:mID="63" v:groupContext="shape" transform="translate(7.23969,-93.155)"> + <title>Foglio.63</title> + <desc>*scope : Class</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="283.487" width="104.89" height="8.50394"/> + <rect x="0" y="279.235" width="104.882" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*scope : Class</text> </g> + <g id="shape64-103" v:mID="64" v:groupContext="shape" transform="translate(7.23969,-81.2495)"> + <title>Foglio.64</title> + <rect x="0" y="280.911" width="109.134" height="6.8287" class="st2"/> + </g> + <g id="shape65-105" v:mID="65" v:groupContext="shape" transform="translate(152.799,-77.2554)"> + <title>Foglio.65</title> + <rect x="0" y="260.038" width="109.134" height="27.7017" class="st2"/> + </g> + <g id="shape66-107" v:mID="66" v:groupContext="shape" transform="translate(157.334,-81.1728)"> + <title>Foglio.66</title> + <desc><<enumeration>> PropertyStyle</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="4" y="274.54" class="st4" v:langID="1040"><v:paragraph/><v:tabList/><<enumeration>><v:newlineChar/><tspan + x="4" dy="1.2em" class="st10">PropertyStyle</tspan></text> </g> + <g id="shape67-111" v:mID="67" v:groupContext="shape" transform="translate(152.799,-12.9601)"> + <title>Foglio.67</title> + <rect x="0" y="223.96" width="109.134" height="63.7795" class="st2"/> + </g> + <g id="shape68-113" v:mID="68" v:groupContext="shape" transform="translate(169.948,-59.1648)"> + <title>Foglio.68</title> + <desc>*Simple</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="279.235" width="45.84" height="17.0079"/> + <rect x="0" y="270.731" width="45.8331" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Simple</text> </g> + <g id="shape69-116" v:mID="69" v:groupContext="shape" transform="translate(170.32,-52.6451)"> + <title>Foglio.69</title> + <desc>*List</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*List</text> </g> + <g id="shape72-119" v:mID="72" v:groupContext="shape" transform="translate(170.196,-36.4876)"> + <title>Foglio.72</title> + <desc>*Indexed</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="279.235" width="45.84" height="17.0079"/> + <rect x="0" y="270.731" width="45.8331" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Indexed</text> </g> + <g id="shape73-122" v:mID="73" v:groupContext="shape" transform="translate(170.196,-29.968)"> + <title>Foglio.73</title> + <desc>*Constant</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Constant</text> </g> + <g id="shape74-125" v:mID="74" v:groupContext="shape" transform="translate(170.32,-17.779)"> + <title>Foglio.74</title> + <desc>*Element</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="22.9166" cy="283.487" width="45.84" height="8.50394"/> + <rect x="0" y="279.235" width="45.8331" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*Element</text> </g> + <g id="shape75-128" v:mID="75" v:groupContext="shape" transform="translate(152.799,-5.87347)"> + <title>Foglio.75</title> + <rect x="0" y="280.911" width="109.134" height="6.8287" class="st2"/> + </g> + <g id="shape70-130" v:mID="70" v:groupContext="shape" transform="translate(277.807,-77.9002)"> + <title>Foglio.70</title> + <rect x="0" y="260.038" width="116.929" height="27.7017" class="st2"/> + </g> + <g id="shape71-132" v:mID="71" v:groupContext="shape" transform="translate(277.807,-82.9247)"> + <title>Foglio.71</title> + <desc>Property</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="276.942" width="79.38" height="21.5944"/> + <rect x="0" y="266.145" width="79.3701" height="21.5944" class="st3"/> + <text x="23.24" y="279.34" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Property</text> </g> + <g id="shape76-135" v:mID="76" v:groupContext="shape" transform="translate(277.807,-13.4759)"> + <title>Foglio.76</title> + <rect x="0" y="223.96" width="116.929" height="63.7795" class="st2"/> + </g> + <g id="shape77-137" v:mID="77" v:groupContext="shape" transform="translate(278.09,-59.6806)"> + <title>Foglio.77</title> + <desc>*style : PropertyStyle</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="279.235" width="108.68" height="17.0079"/> + <rect x="0" y="270.731" width="108.678" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*style : PropertyStyle</text> </g> + <g id="shape78-140" v:mID="78" v:groupContext="shape" transform="translate(278.971,-53.1609)"> + <title>Foglio.78</title> + <desc>*baseType: String</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*baseType: String</text> </g> + <g id="shape79-143" v:mID="79" v:groupContext="shape" transform="translate(278.678,-37.0035)"> + <title>Foglio.79</title> + <desc>*collectionType: String</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="279.235" width="108.68" height="17.0079"/> + <rect x="0" y="270.731" width="108.678" height="17.0079" class="st3"/> + <text x="4" y="281.64" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*collectionType: String</text> </g> + <g id="shape80-146" v:mID="80" v:groupContext="shape" transform="translate(278.678,-30.4838)"> + <title>Foglio.80</title> + <desc>*defaultValue: Object</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*defaultValue: Object</text> </g> + <g id="shape81-149" v:mID="81" v:groupContext="shape" transform="translate(278.971,-18.2948)"> + <title>Foglio.81</title> + <desc>*unsettable: boolean</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="54.3389" cy="283.487" width="108.68" height="8.50394"/> + <rect x="0" y="279.235" width="108.678" height="8.50394" class="st3"/> + <text x="4" y="285.89" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>*unsettable: boolean</text> </g> + <g id="shape82-152" v:mID="82" v:groupContext="shape" transform="translate(277.807,-6.38929)"> + <title>Foglio.82</title> + <rect x="0" y="280.911" width="116.929" height="6.8287" class="st2"/> + </g> + <g id="shape83-154" v:mID="83" v:groupContext="shape" transform="translate(588.889,182.137) rotate(90) scale(-1,1)"> + <title>Foglio.83</title> + <path d="M0 287.74 L21.26 287.74" class="st7"/> + </g> + <g id="shape84-157" v:mID="84" v:groupContext="shape" transform="translate(298.315,466.23) scale(1,-1)"> + <title>Foglio.84</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape85-159" v:mID="85" v:groupContext="shape" transform="translate(298.315,-109.248)"> + <title>Foglio.85</title> + <path d="M5.67 287.74 L0 287.74 L2.83 284.42 L5.67 287.74 Z" class="st8"/> + </g> + <g id="shape87-161" v:mID="87" v:groupContext="shape" transform="translate(552.081,157.334) rotate(90)"> + <title>Foglio.87</title> + <path d="M0 279.2 L3.63 287.74 L7.09 279.2" class="st7"/> + </g> + <g id="shape86-164" v:mID="86" v:groupContext="shape" transform="translate(328.83,-117.649) scale(-1,1)"> + <title>Foglio.86</title> + <desc>0…1</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="13.4646" cy="282.779" width="26.93" height="9.92126"/> + <rect x="0" y="277.818" width="26.9291" height="9.92126" class="st3"/> + <text x="-22.93" y="285.18" transform="scale(-1,1)" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>0…1</text> </g> + <g id="shape88-167" v:mID="88" v:groupContext="shape" transform="translate(264.342,448.617) scale(1,-1)"> + <title>Foglio.88</title> + <path d="M0 287.74 L36.81 287.74" class="st7"/> + </g> + <g id="shape89-170" v:mID="89" v:groupContext="shape" transform="translate(73.0035,-205.017)"> + <title>Foglio.89</title> + <desc>: JAXBContent</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.9073" cy="280.45" width="69.82" height="14.5782"/> + <rect x="0" y="273.161" width="69.8146" height="14.5782" class="st3"/> + <text x="4" y="282.85" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>: JAXBContent</text> </g> + <g id="shape13-173" v:mID="13" v:groupContext="shape" transform="translate(205.299,-260.291) scale(-1,1)"> + <title>Foglio.13</title> + <path d="M0 287.74 L37.33 287.74" class="st7"/> + </g> + <g id="shape24-176" v:mID="24" v:groupContext="shape" transform="translate(4.97197,-227.694)"> + <title>Foglio.24</title> + <rect x="0" y="270.731" width="189.921" height="17.0079" class="st2"/> + </g> + <g id="shape25-178" v:mID="25" v:groupContext="shape" transform="translate(4.97197,-228.626)"> + <title>Foglio.25</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="85.4223" cy="279.701" width="170.85" height="16.0765"/> + <rect x="0" y="271.663" width="170.845" height="16.0765" class="st3"/> + <text x="58.53" y="282.1" class="st5" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>ObjectFactory</text> </g> + <g id="shape16-181" v:mID="16" v:groupContext="shape" transform="translate(123.281,-173.633) rotate(-0.0356055)"> + <title>Foglio.16</title> + <path d="M0 287.74 L122.46 287.74" class="st7"/> + </g> + <g id="shape17-184" v:mID="17" v:groupContext="shape" transform="translate(-154.641,116.94) rotate(-90)"> + <title>Foglio.17</title> + <path d="M5.67 287.74 L0 287.74 L2.83 278.1 L5.67 287.74 Z" class="st2"/> + </g> + <g id="shape18-186" v:mID="18" v:groupContext="shape" transform="translate(348.814,-196.311)"> + <title>Foglio.18</title> + <path d="M0 287.74 L23.24 287.74" class="st7"/> + </g> + <g id="shape19-189" v:mID="19" v:groupContext="shape" transform="translate(70.7131,94.2633) rotate(-90)"> + <title>Foglio.19</title> + <path d="M5.67 287.74 L0 287.74 L2.83 278.1 L5.67 287.74 Z" class="st2"/> + </g> + <g id="shape26-191" v:mID="26" v:groupContext="shape" transform="translate(84.3194,91.4287) rotate(-90)"> + <title>Foglio.26</title> + <path d="M0 287.74 L29.76 287.74" class="st7"/> + </g> + <g id="shape29-194" v:mID="29" v:groupContext="shape" transform="translate(336.626,-226.074)"> + <title>Foglio.29</title> + <path d="M0 287.74 L35.43 287.74" class="st7"/> + </g> + <g id="shape30-197" v:mID="30" v:groupContext="shape" transform="translate(48.8863,77.053) rotate(-90)"> + <title>Foglio.30</title> + <path d="M0 287.74 L15.39 287.74" class="st7"/> + </g> + <g id="shape35-200" v:mID="35" v:groupContext="shape" transform="translate(318.2,-233.161)"> + <title>Foglio.35</title> + <desc>Substitution Group</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="30.6986" cy="278.189" width="61.4" height="19.1001"/> + <rect x="0" y="268.639" width="61.3973" height="19.1001" class="st3"/> + <text x="4" y="275.79" class="st11" v:langID="1040"><v:paragraph/><v:tabList/>Substitution<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">Group</tspan></text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-15.png b/spec/src/main/asciidoc/images/xmlb-15.png new file mode 100644 index 0000000..95d5f26 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-15.png Binary files differ
diff --git a/spec/src/main/asciidoc/images/xmlb-16.svg b/spec/src/main/asciidoc/images/xmlb-16.svg new file mode 100644 index 0000000..df3cf14 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-16.svg
@@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-16.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.94303in" + height="3.16961in" viewBox="0 0 355.898 228.212" xml:space="preserve" color-interpolation-filters="sRGB" class="st10"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#ffffff;stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st5 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st6 {stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic} + .st9 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.847559,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="354.331" height="226.772" class="st1"/> + </g> + <g id="shape6-3" v:mID="6" v:groupContext="shape" transform="translate(34.8633,-142.452)"> + <title>Foglio.6</title> + <rect x="0" y="180.023" width="113.386" height="48.189" class="st2"/> + </g> + <g id="shape23-5" v:mID="23" v:groupContext="shape" transform="translate(68.8791,-148.122)"> + <title>Foglio.23</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape20-7" v:mID="20" v:groupContext="shape" transform="translate(29.194,-195.501)"> + <title>Foglio.20</title> + <desc>XML Schema Components</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>XML Schema Components</text> </g> + <g id="shape21-10" v:mID="21" v:groupContext="shape" transform="translate(34.8633,-172.823)"> + <title>Foglio.21</title> + <desc>ComplexType A</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>ComplexType A</text> </g> + <g id="shape22-13" v:mID="22" v:groupContext="shape" transform="translate(68.8791,-147.312)"> + <title>Foglio.22</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape24-16" v:mID="24" v:groupContext="shape" transform="translate(233.005,-131.397)"> + <title>Foglio.24</title> + <rect x="0" y="157.346" width="113.386" height="70.8661" class="st2"/> + </g> + <g id="shape25-18" v:mID="25" v:groupContext="shape" transform="translate(253.131,-136.783)"> + <title>Foglio.25</title> + <rect x="0" y="193.791" width="85.0394" height="34.4207" class="st2"/> + </g> + <g id="shape26-20" v:mID="26" v:groupContext="shape" transform="translate(227.619,-204.005)"> + <title>Foglio.26</title> + <desc>JAXB Java Representation</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>JAXB Java Representation</text> </g> + <g id="shape27-23" v:mID="27" v:groupContext="shape" transform="translate(236.123,-181.732)"> + <title>Foglio.27</title> + <desc>class A</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="219.303" width="104.89" height="17.8178"/> + <rect x="0" y="210.394" width="104.882" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>class A</text> </g> + <g id="shape28-26" v:mID="28" v:groupContext="shape" transform="translate(253.131,-153.386)"> + <title>Foglio.28</title> + <desc>PropertySet</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>PropertySet</text> </g> + <g id="shape29-29" v:mID="29" v:groupContext="shape" transform="translate(253.131,301.419) rotate(180)"> + <title>Foglio.29</title> + <path d="M0 228.21 L110.55 228.21" class="st6"/> + </g> + <g id="shape30-32" v:mID="30" v:groupContext="shape" transform="translate(471.705,70.4523) rotate(90)"> + <title>Foglio.30</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape31-34" v:mID="31" v:groupContext="shape" transform="translate(156.626,-153.791)"> + <title>Foglio.31</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape2-37" v:mID="2" v:groupContext="shape" transform="translate(34.8633,-16.3106)"> + <title>Foglio.2</title> + <rect x="0" y="180.023" width="113.386" height="48.189" class="st2"/> + </g> + <g id="shape3-39" v:mID="3" v:groupContext="shape" transform="translate(68.8791,-21.9798)"> + <title>Foglio.3</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape5-41" v:mID="5" v:groupContext="shape" transform="translate(34.8633,-46.6818)"> + <title>Foglio.5</title> + <desc>ComplexType C</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>ComplexType C</text> </g> + <g id="shape7-44" v:mID="7" v:groupContext="shape" transform="translate(68.8791,-21.1699)"> + <title>Foglio.7</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape8-47" v:mID="8" v:groupContext="shape" transform="translate(233.289,-9.22394)"> + <title>Foglio.8</title> + <rect x="0" y="157.346" width="113.386" height="70.8661" class="st2"/> + </g> + <g id="shape9-49" v:mID="9" v:groupContext="shape" transform="translate(253.131,-14.8932)"> + <title>Foglio.9</title> + <rect x="0" y="193.791" width="85.0394" height="34.4207" class="st2"/> + </g> + <g id="shape11-51" v:mID="11" v:groupContext="shape" transform="translate(236.123,-59.8426)"> + <title>Foglio.11</title> + <desc>class C</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="219.303" width="104.89" height="17.8178"/> + <rect x="0" y="210.394" width="104.882" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>class C</text> </g> + <g id="shape12-54" v:mID="12" v:groupContext="shape" transform="translate(253.131,-31.4962)"> + <title>Foglio.12</title> + <desc>PropertySet</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>PropertySet</text> </g> + <g id="shape13-57" v:mID="13" v:groupContext="shape" transform="translate(253.131,427.561) rotate(180)"> + <title>Foglio.13</title> + <path d="M0 228.21 L110.55 228.21" class="st6"/> + </g> + <g id="shape14-60" v:mID="14" v:groupContext="shape" transform="translate(471.705,196.594) rotate(90)"> + <title>Foglio.14</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape15-62" v:mID="15" v:groupContext="shape" transform="translate(156.626,-10.6413)"> + <title>Foglio.15</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape4-65" v:mID="4" v:groupContext="shape" transform="translate(-126.55,312.457) rotate(-121.091)"> + <title>Foglio.4</title> + <path d="M-0 228.21 A46.5784 83.9946 0 0 1 65.87 228.21" class="st9"/> + </g> + <g id="shape10-68" v:mID="10" v:groupContext="shape" transform="translate(0.72,-46.0743)"> + <title>Foglio.10</title> + <desc>refs</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>refs</text> </g> + <g id="shape16-71" v:mID="16" v:groupContext="shape" transform="translate(34.8633,-75.8381)"> + <title>Foglio.16</title> + <rect x="0" y="180.023" width="113.386" height="48.189" rx="11.3386" ry="11.3386" class="st2"/> + </g> + <g id="shape17-73" v:mID="17" v:groupContext="shape" transform="translate(68.8791,-81.5074)"> + <title>Foglio.17</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape18-75" v:mID="18" v:groupContext="shape" transform="translate(34.8633,-106.209)"> + <title>Foglio.18</title> + <desc>Model Group B</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Model Group B</text> </g> + <g id="shape19-78" v:mID="19" v:groupContext="shape" transform="translate(68.8791,-80.6975)"> + <title>Foglio.19</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape32-81" v:mID="32" v:groupContext="shape" transform="translate(141.599,-52.0036) rotate(30)"> + <title>Foglio.32</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape33-83" v:mID="33" v:groupContext="shape" transform="translate(-146.498,104.185) rotate(-90)"> + <title>Foglio.33</title> + <path d="M0 228.21 L23.28 228.21" class="st9"/> + </g> + <g id="shape34-86" v:mID="34" v:groupContext="shape" transform="translate(84.4696,322.758) rotate(180)"> + <title>Foglio.34</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape35-88" v:mID="35" v:groupContext="shape" transform="translate(85.7594,-126.457)"> + <title>Foglio.35</title> + <desc>refs</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>refs</text> </g> + <g id="shape36-91" v:mID="36" v:groupContext="shape" transform="translate(347.003,294.904) rotate(155.711)"> + <title>Foglio.36</title> + <path d="M0 228.21 L121.29 228.21" class="st6"/> + </g> + <g id="shape37-94" v:mID="37" v:groupContext="shape" transform="translate(449.867,-8.02989) rotate(65)"> + <title>Foglio.37</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape38-96" v:mID="38" v:groupContext="shape" transform="translate(173.506,-80.6975)"> + <title>Foglio.38</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape39-99" v:mID="39" v:groupContext="shape" transform="translate(46.9459,348.242) rotate(24.7751) scale(1,-1)"> + <title>Foglio.39</title> + <path d="M0 228.21 L121.76 228.21" class="st6"/> + </g> + <g id="shape40-102" v:mID="40" v:groupContext="shape" transform="translate(452.011,281.782) rotate(115)"> + <title>Foglio.40</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-17.svg b/spec/src/main/asciidoc/images/xmlb-17.svg new file mode 100644 index 0000000..4ad709b --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-17.svg
@@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-17.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.13988in" + height="3.16961in" viewBox="0 0 370.071 228.212" xml:space="preserve" color-interpolation-filters="sRGB" class="st13"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#ffffff;stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st5 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st6 {stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic} + .st9 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:#000000;font-family:Arial;font-size:0.666664em;font-weight:bold} + .st11 {font-size:1em;font-weight:normal} + .st12 {font-size:1em;font-weight:bold} + .st13 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.847559,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="368.504" height="226.772" class="st1"/> + </g> + <g id="shape6-3" v:mID="6" v:groupContext="shape" transform="translate(34.8633,-142.452)"> + <title>Foglio.6</title> + <rect x="0" y="180.023" width="113.386" height="48.189" class="st2"/> + </g> + <g id="shape23-5" v:mID="23" v:groupContext="shape" transform="translate(68.8791,-148.122)"> + <title>Foglio.23</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape20-7" v:mID="20" v:groupContext="shape" transform="translate(29.194,-195.501)"> + <title>Foglio.20</title> + <desc>XML Schema Components</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>XML Schema Components</text> </g> + <g id="shape21-10" v:mID="21" v:groupContext="shape" transform="translate(34.8633,-172.823)"> + <title>Foglio.21</title> + <desc>ComplexType A</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>ComplexType A</text> </g> + <g id="shape22-13" v:mID="22" v:groupContext="shape" transform="translate(68.8791,-147.312)"> + <title>Foglio.22</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape24-16" v:mID="24" v:groupContext="shape" transform="translate(233.005,-131.397)"> + <title>Foglio.24</title> + <rect x="0" y="157.346" width="119.041" height="70.8661" class="st2"/> + </g> + <g id="shape25-18" v:mID="25" v:groupContext="shape" transform="translate(254.135,-136.783)"> + <title>Foglio.25</title> + <rect x="0" y="193.791" width="89.2807" height="34.4207" class="st2"/> + </g> + <g id="shape26-20" v:mID="26" v:groupContext="shape" transform="translate(227.619,-204.005)"> + <title>Foglio.26</title> + <desc>JAXB Java Representation</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>JAXB Java Representation</text> </g> + <g id="shape27-23" v:mID="27" v:groupContext="shape" transform="translate(236.123,-181.732)"> + <title>Foglio.27</title> + <desc>class A</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="219.303" width="104.89" height="17.8178"/> + <rect x="0" y="210.394" width="104.882" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>class A</text> </g> + <g id="shape28-26" v:mID="28" v:groupContext="shape" transform="translate(253.131,-153.386)"> + <title>Foglio.28</title> + <desc>PropertySet</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>PropertySet</text> </g> + <g id="shape29-29" v:mID="29" v:groupContext="shape" transform="translate(253.131,301.419) rotate(180)"> + <title>Foglio.29</title> + <path d="M0 228.21 L110.55 228.21" class="st6"/> + </g> + <g id="shape30-32" v:mID="30" v:groupContext="shape" transform="translate(471.705,70.4523) rotate(90)"> + <title>Foglio.30</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape31-34" v:mID="31" v:groupContext="shape" transform="translate(184.844,-133.948)"> + <title>Foglio.31</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape2-37" v:mID="2" v:groupContext="shape" transform="translate(34.8633,-9.22394)"> + <title>Foglio.2</title> + <rect x="0" y="180.023" width="113.386" height="48.189" class="st2"/> + </g> + <g id="shape3-39" v:mID="3" v:groupContext="shape" transform="translate(68.8791,-14.8932)"> + <title>Foglio.3</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape5-41" v:mID="5" v:groupContext="shape" transform="translate(34.8633,-39.5951)"> + <title>Foglio.5</title> + <desc>ComplexType C</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>ComplexType C</text> </g> + <g id="shape7-44" v:mID="7" v:groupContext="shape" transform="translate(68.8791,-14.0833)"> + <title>Foglio.7</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape8-47" v:mID="8" v:groupContext="shape" transform="translate(233.303,-2.13732)"> + <title>Foglio.8</title> + <rect x="0" y="157.346" width="119.041" height="70.8661" class="st2"/> + </g> + <g id="shape9-49" v:mID="9" v:groupContext="shape" transform="translate(254.135,-7.80661)"> + <title>Foglio.9</title> + <rect x="0" y="193.791" width="89.2807" height="34.4207" class="st2"/> + </g> + <g id="shape11-51" v:mID="11" v:groupContext="shape" transform="translate(236.123,-52.756)"> + <title>Foglio.11</title> + <desc>class C</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="219.303" width="104.89" height="17.8178"/> + <rect x="0" y="210.394" width="104.882" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>class C</text> </g> + <g id="shape12-54" v:mID="12" v:groupContext="shape" transform="translate(253.131,-24.4095)"> + <title>Foglio.12</title> + <desc>PropertySet</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>PropertySet</text> </g> + <g id="shape13-57" v:mID="13" v:groupContext="shape" transform="translate(253.131,434.648) rotate(180)"> + <title>Foglio.13</title> + <path d="M0 228.21 L110.55 228.21" class="st6"/> + </g> + <g id="shape14-60" v:mID="14" v:groupContext="shape" transform="translate(471.705,203.681) rotate(90)"> + <title>Foglio.14</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape15-62" v:mID="15" v:groupContext="shape" transform="translate(184.972,-22.5873)"> + <title>Foglio.15</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape4-65" v:mID="4" v:groupContext="shape" transform="translate(-130.395,310.368) rotate(-119.168)"> + <title>Foglio.4</title> + <path d="M0 228.21 A49.3526 83.9946 0 0 1 69.8 228.21" class="st9"/> + </g> + <g id="shape10-68" v:mID="10" v:groupContext="shape" transform="translate(0.72,-38.9877)"> + <title>Foglio.10</title> + <desc>refs</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>refs</text> </g> + <g id="shape16-71" v:mID="16" v:groupContext="shape" transform="translate(34.8633,-75.8381)"> + <title>Foglio.16</title> + <rect x="0" y="180.023" width="113.386" height="48.189" rx="11.3386" ry="11.3386" class="st2"/> + </g> + <g id="shape17-73" v:mID="17" v:groupContext="shape" transform="translate(68.8791,-81.5074)"> + <title>Foglio.17</title> + <path d="M0 228.21 L73.7 228.21 L73.7 211.2 L0 211.2 L0 228.21 Z" class="st3"/> + </g> + <g id="shape18-75" v:mID="18" v:groupContext="shape" transform="translate(34.8633,-106.209)"> + <title>Foglio.18</title> + <desc>Model Group Foo</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="56.6929" cy="219.303" width="113.39" height="17.8178"/> + <rect x="0" y="210.394" width="113.386" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Model Group Foo</text> </g> + <g id="shape19-78" v:mID="19" v:groupContext="shape" transform="translate(68.8791,-80.6975)"> + <title>Foglio.19</title> + <desc>content model</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="31.1811" cy="219.303" width="62.37" height="17.8178"/> + <rect x="0" y="210.394" width="62.3622" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>content model</text> </g> + <g id="shape32-81" v:mID="32" v:groupContext="shape" transform="translate(141.599,-52.0036) rotate(30)"> + <title>Foglio.32</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape33-83" v:mID="33" v:groupContext="shape" transform="translate(-146.498,104.185) rotate(-90)"> + <title>Foglio.33</title> + <path d="M0 228.21 L23.28 228.21" class="st9"/> + </g> + <g id="shape34-86" v:mID="34" v:groupContext="shape" transform="translate(84.4696,322.758) rotate(180)"> + <title>Foglio.34</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape35-88" v:mID="35" v:groupContext="shape" transform="translate(85.7594,-126.457)"> + <title>Foglio.35</title> + <desc>refs</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>refs</text> </g> + <g id="shape36-91" v:mID="36" v:groupContext="shape" transform="translate(347.003,294.904) rotate(155.711)"> + <title>Foglio.36</title> + <path d="M0 228.21 L121.29 228.21" class="st6"/> + </g> + <g id="shape37-94" v:mID="37" v:groupContext="shape" transform="translate(449.867,-8.02989) rotate(65)"> + <title>Foglio.37</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape38-96" v:mID="38" v:groupContext="shape" transform="translate(182.01,-71.1812)"> + <title>Foglio.38</title> + <desc>derive</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="19.9701" cy="219.303" width="39.95" height="17.8178"/> + <rect x="0" y="210.394" width="39.9402" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st8" v:langID="1040"><v:paragraph/><v:tabList/>derive</text> </g> + <g id="shape39-99" v:mID="39" v:groupContext="shape" transform="translate(46.9459,355.328) rotate(24.7751) scale(1,-1)"> + <title>Foglio.39</title> + <path d="M0 228.21 L121.76 228.21" class="st6"/> + </g> + <g id="shape40-102" v:mID="40" v:groupContext="shape" transform="translate(452.011,288.869) rotate(115)"> + <title>Foglio.40</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + <g id="shape41-104" v:mID="41" v:groupContext="shape" transform="translate(253.131,-135.973)"> + <title>Foglio.41</title> + <desc>FooBar getBar();</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.7244" cy="219.303" width="69.45" height="17.8178"/> + <rect x="0" y="210.394" width="69.4488" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st10" v:langID="1040"><v:paragraph/><v:tabList/>FooBar<tspan class="st11"> </tspan><tspan + class="st11">getBar</tspan><tspan class="st11">()</tspan><tspan class="st11">;</tspan></text> </g> + <g id="shape42-111" v:mID="42" v:groupContext="shape" transform="translate(253.131,-5.98434)"> + <title>Foglio.42</title> + <desc>FooBar getBar();</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.7244" cy="219.303" width="69.45" height="17.8178"/> + <rect x="0" y="210.394" width="69.4488" height="17.8178" class="st4"/> + <text x="4" y="221.7" class="st10" v:langID="1040"><v:paragraph/><v:tabList/>FooBar<tspan class="st11"> </tspan><tspan + class="st11">getBar</tspan><tspan class="st11">()</tspan><tspan class="st11">;</tspan></text> </g> + <g id="shape43-118" v:mID="43" v:groupContext="shape" transform="translate(233.303,-80.0901)"> + <title>Foglio.43</title> + <rect x="0" y="184.275" width="119.041" height="43.937" class="st2"/> + </g> + <g id="shape44-120" v:mID="44" v:groupContext="shape" transform="translate(236.407,-111.298)"> + <title>Foglio.44</title> + <desc>class FooBar</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="222.688" width="104.89" height="11.047"/> + <rect x="0" y="217.165" width="104.882" height="11.047" class="st4"/> + <text x="4" y="225.09" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>class <tspan class="st12">FooBar</tspan></text> </g> + <g id="shape45-124" v:mID="45" v:groupContext="shape" transform="translate(233.289,368.317) rotate(180)"> + <title>Foglio.45</title> + <path d="M0 228.21 L90.43 228.21" class="st6"/> + </g> + <g id="shape46-127" v:mID="46" v:groupContext="shape" transform="translate(451.295,137.35) rotate(90)"> + <title>Foglio.46</title> + <path d="M5.67 228.21 L0 228.21 L2.83 218.57 L5.67 228.21 Z" class="st7"/> + </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-18.svg b/spec/src/main/asciidoc/images/xmlb-18.svg new file mode 100644 index 0000000..0d99fd7 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-18.svg
@@ -0,0 +1,145 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-18.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="4.15386in" + height="4.66567in" viewBox="0 0 299.078 335.928" xml:space="preserve" color-interpolation-filters="sRGB" class="st8"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic} + .st6 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape139-1" v:mID="139" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.139</title> + <rect x="0" y="1.44" width="297.638" height="334.488" class="st1"/> + </g> + <g id="shape167-3" v:mID="167" v:groupContext="shape" transform="translate(14.8932,-46.0743)"> + <title>Foglio.167</title> + <rect x="0" y="66.6369" width="269.291" height="269.291" class="st2"/> + </g> + <g id="shape168-5" v:mID="168" v:groupContext="shape" transform="translate(12.0586,-313.948)"> + <title>Foglio.168</title> + <desc>GlobalScope</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="327.019" width="67.88" height="17.8178"/> + <rect x="0" y="318.11" width="67.8794" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>GlobalScope</text> </g> + <g id="shape171-8" v:mID="171" v:groupContext="shape" transform="translate(19.7643,-298.965)"> + <title>Foglio.171</title> + <desc><globalBindings></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.814" cy="327.019" width="69.63" height="17.8178"/> + <rect x="0" y="318.11" width="69.6279" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st5" v:langID="1040"><v:paragraph/><v:tabList/><globalBindings></text> </g> + <g id="shape172-11" v:mID="172" v:groupContext="shape" transform="translate(48.2003,-76.9011)"> + <title>Foglio.172</title> + <rect x="0" y="131.125" width="204.803" height="204.803" class="st2"/> + </g> + <g id="shape173-13" v:mID="173" v:groupContext="shape" transform="translate(43.3917,-280.54)"> + <title>Foglio.173</title> + <desc>SchemaScope</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="327.019" width="67.88" height="17.8178"/> + <rect x="0" y="318.11" width="67.8794" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>SchemaScope</text> </g> + <g id="shape174-16" v:mID="174" v:groupContext="shape" transform="translate(50.6903,-265.962)"> + <title>Foglio.174</title> + <desc><schemaBindings></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.7944" cy="327.019" width="77.59" height="17.8178"/> + <rect x="0" y="318.11" width="77.5888" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st5" v:langID="1040"><v:paragraph/><v:tabList/><schemaBindings></text> </g> + <g id="shape175-19" v:mID="175" v:groupContext="shape" transform="translate(78.6728,-99.9326)"> + <title>Foglio.175</title> + <rect x="0" y="187.109" width="148.819" height="148.819" class="st2"/> + </g> + <g id="shape176-21" v:mID="176" v:groupContext="shape" transform="translate(73.169,-246.524)"> + <title>Foglio.176</title> + <desc>Definition Scope</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="327.019" width="67.88" height="17.8178"/> + <rect x="0" y="318.11" width="67.8794" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Definition Scope</text> </g> + <g id="shape177-24" v:mID="177" v:groupContext="shape" transform="translate(91.4287,-231.946)"> + <title>Foglio.177</title> + <desc>Binding Declaration</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.7944" cy="327.019" width="77.59" height="17.8178"/> + <rect x="0" y="318.11" width="77.5888" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Binding Declaration</text> </g> + <g id="shape178-27" v:mID="178" v:groupContext="shape" transform="translate(102.767,-125.444)"> + <title>Foglio.178</title> + <rect x="0" y="245.22" width="102.047" height="90.7087" class="st2"/> + </g> + <g id="shape1-29" v:mID="1" v:groupContext="shape" transform="translate(105.602,-213.723)"> + <title>Foglio.1</title> + <desc>Component Scope</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.685" cy="327.019" width="79.38" height="17.8178"/> + <rect x="0" y="318.11" width="79.3701" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Component Scope</text> </g> + <g id="shape2-32" v:mID="2" v:groupContext="shape" transform="translate(103.658,-187.402)"> + <title>Foglio.2</title> + <desc>Binding Declaration</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="38.7944" cy="327.019" width="77.59" height="17.8178"/> + <rect x="0" y="318.11" width="77.5888" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Binding Declaration</text> </g> + <g id="shape3-35" v:mID="3" v:groupContext="shape" transform="translate(81.5454,-3.55465)"> + <title>Foglio.3</title> + <desc>Indicates inheritance and overriding of scope</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="86.4187" cy="327.019" width="172.84" height="17.8178"/> + <rect x="0" y="318.11" width="172.837" height="17.8178" class="st3"/> + <text x="4" y="329.42" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Indicates inheritance and overriding of scope</text> </g> + <g id="shape4-38" v:mID="4" v:groupContext="shape" transform="translate(50.0686,-114.454) rotate(-30) scale(-1,1)"> + <title>Foglio.4</title> + <path d="M0 335.93 L23.98 335.93" class="st6"/> + </g> + <g id="shape5-41" v:mID="5" v:groupContext="shape" transform="translate(501.608,16.2548) rotate(60) scale(-1,1)"> + <title>Foglio.5</title> + <path d="M5.67 335.93 L0 335.93 L2.83 326.29 L5.67 335.93 Z" class="st7"/> + </g> + <g id="shape6-43" v:mID="6" v:groupContext="shape" transform="translate(73.7008,-148.796) rotate(-30) scale(-1,1)"> + <title>Foglio.6</title> + <path d="M0 335.93 L23.98 335.93" class="st6"/> + </g> + <g id="shape7-46" v:mID="7" v:groupContext="shape" transform="translate(525.24,-18.0866) rotate(60) scale(-1,1)"> + <title>Foglio.7</title> + <path d="M5.67 335.93 L0 335.93 L2.83 326.29 L5.67 335.93 Z" class="st7"/> + </g> + <g id="shape8-48" v:mID="8" v:groupContext="shape" transform="translate(98.2576,-183.137) rotate(-30) scale(-1,1)"> + <title>Foglio.8</title> + <path d="M0 335.93 L23.98 335.93" class="st6"/> + </g> + <g id="shape9-51" v:mID="9" v:groupContext="shape" transform="translate(549.797,-52.428) rotate(60) scale(-1,1)"> + <title>Foglio.9</title> + <path d="M5.67 335.93 L0 335.93 L2.83 326.29 L5.67 335.93 Z" class="st7"/> + </g> + <g id="shape10-53" v:mID="10" v:groupContext="shape" transform="translate(-85.9944,24.1177) rotate(-30) scale(-1,1)"> + <title>Foglio.10</title> + <path d="M0 335.93 L23.98 335.93" class="st6"/> + </g> + <g id="shape11-56" v:mID="11" v:groupContext="shape" transform="translate(365.545,154.827) rotate(60) scale(-1,1)"> + <title>Foglio.11</title> + <path d="M5.67 335.93 L0 335.93 L2.83 326.29 L5.67 335.93 Z" class="st7"/> + </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-2.svg b/spec/src/main/asciidoc/images/xmlb-2.svg new file mode 100644 index 0000000..3200893 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-2.svg
@@ -0,0 +1,149 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-2.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="3.95701in" + height="1.71291in" viewBox="0 0 284.905 123.33" xml:space="preserve" color-interpolation-filters="sRGB" class="st11"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#000000;font-family:Arial;font-size:1.16666em} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em;font-weight:bold} + .st5 {font-size:1em} + .st6 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st8 {stroke:#a6a6a6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#bfbfbf;stroke:#a6a6a6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:#000000;font-family:Arial;font-size:0.583328em;font-style:italic} + .st11 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape139-1" v:mID="139" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.139</title> + <rect x="0" y="1.44" width="283.465" height="121.89" class="st1"/> + </g> + <g id="shape9-3" v:mID="9" v:groupContext="shape" transform="translate(20.5625,-90.3657)"> + <title>Foglio.9</title> + <desc>schema</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="111.283" width="59.53" height="24.0945"/> + <rect x="0" y="99.2353" width="59.5276" height="24.0945" class="st2"/> + <text x="5.25" y="115.48" class="st3" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>schema</text> </g> + <g id="shape140-6" v:mID="140" v:groupContext="shape" transform="translate(4.26331,-23.3972)"> + <title>Foglio.140</title> + <desc>document</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.5591" cy="111.283" width="75.12" height="24.0945"/> + <rect x="0" y="99.2353" width="75.1181" height="24.0945" class="st2"/> + <text x="6.82" y="115.48" class="st3" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>document</text> </g> + <g id="shape141-9" v:mID="141" v:groupContext="shape" transform="translate(176.468,-22.6885)"> + <title>Foglio.141</title> + <desc>objects</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.5591" cy="111.283" width="75.12" height="24.0945"/> + <rect x="0" y="99.2353" width="75.1181" height="24.0945" class="st2"/> + <text x="15.38" y="115.48" class="st3" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>objects</text> </g> + <g id="shape142-12" v:mID="142" v:groupContext="shape" transform="translate(183.555,-91.0743)"> + <title>Foglio.142</title> + <desc>JAXB mapped classes</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.7244" cy="111.283" width="69.45" height="24.0945"/> + <rect x="0" y="99.2353" width="69.4488" height="24.0945" class="st2"/> + <text x="7.61" y="108.88" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>JAXB mapped <tspan + x="20.27" dy="1.2em" class="st5">classes</tspan></text> </g> + <g id="shape143-16" v:mID="143" v:groupContext="shape" transform="translate(180.763,151.183) rotate(180)"> + <title>Foglio.143</title> + <path d="M0 123.33 L76.62 123.33" class="st6"/> + </g> + <g id="shape144-19" v:mID="144" v:groupContext="shape" transform="translate(293.855,24.8145) rotate(90)"> + <title>Foglio.144</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st7"/> + </g> + <g id="shape145-21" v:mID="145" v:groupContext="shape" transform="translate(176.695,31.8143) rotate(90)"> + <title>Foglio.145</title> + <path d="M0 123.33 L44.02 123.33" class="st8"/> + </g> + <g id="shape146-24" v:mID="146" v:groupContext="shape" transform="translate(50.3263,-81.2773)"> + <title>Foglio.146</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st9"/> + </g> + <g id="shape147-26" v:mID="147" v:groupContext="shape" transform="translate(9.47906,-60.0208)"> + <title>Foglio.147</title> + <desc>follows</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="20.4236" cy="117.434" width="40.85" height="11.7921"/> + <rect x="0" y="111.538" width="40.8472" height="11.7921" class="st2"/> + <text x="9.73" y="119.53" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>follows</text> </g> + <g id="shape148-29" v:mID="148" v:groupContext="shape" transform="translate(101.123,34.7357) rotate(-90) scale(-1,1)"> + <title>Foglio.148</title> + <path d="M0 123.33 L44.02 123.33" class="st8"/> + </g> + <g id="shape149-32" v:mID="149" v:groupContext="shape" transform="translate(227.492,-78.3559) scale(-1,1)"> + <title>Foglio.149</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st9"/> + </g> + <g id="shape150-34" v:mID="150" v:groupContext="shape" transform="translate(275.681,-65.6901) scale(-1,1)"> + <title>Foglio.150</title> + <desc>instance of</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="24.0945" cy="117.434" width="48.19" height="11.7921"/> + <rect x="0" y="111.538" width="48.189" height="11.7921" class="st2"/> + <text x="-41.02" y="119.53" transform="scale(-1,1)" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>instance of</text> </g> + <g id="shape151-37" v:mID="151" v:groupContext="shape" transform="translate(102.767,137.01) scale(1,-1)"> + <title>Foglio.151</title> + <path d="M0 123.33 L76.62 123.33" class="st6"/> + </g> + <g id="shape152-40" v:mID="152" v:groupContext="shape" transform="translate(-10.3244,10.6413) rotate(-90) scale(-1,1)"> + <title>Foglio.152</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st7"/> + </g> + <g id="shape153-42" v:mID="153" v:groupContext="shape" transform="translate(128.279,-96.6444)"> + <title>Foglio.153</title> + <desc>bind</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="16.8803" cy="117.434" width="33.77" height="11.7921"/> + <rect x="0" y="111.538" width="33.7606" height="11.7921" class="st2"/> + <text x="10.26" y="119.53" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>bind</text> </g> + <g id="shape154-45" v:mID="154" v:groupContext="shape" transform="translate(103.454,219.215) scale(1,-1)"> + <title>Foglio.154</title> + <path d="M0 123.33 L76.62 123.33" class="st6"/> + </g> + <g id="shape155-48" v:mID="155" v:groupContext="shape" transform="translate(-9.63745,92.846) rotate(-90) scale(-1,1)"> + <title>Foglio.155</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st7"/> + </g> + <g id="shape156-50" v:mID="156" v:groupContext="shape" transform="translate(181.45,205.042) rotate(180)"> + <title>Foglio.156</title> + <path d="M0 123.33 L76.62 123.33" class="st6"/> + </g> + <g id="shape157-53" v:mID="157" v:groupContext="shape" transform="translate(294.542,78.6728) rotate(90)"> + <title>Foglio.157</title> + <path d="M5.67 123.33 L0 123.33 L2.83 113.69 L5.67 123.33 Z" class="st7"/> + </g> + <g id="shape158-55" v:mID="158" v:groupContext="shape" transform="translate(164.786,-42.7861) scale(-1,1)"> + <title>Foglio.158</title> + <desc>unmarshal</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="25.1683" cy="117.434" width="50.34" height="11.7921"/> + <rect x="0" y="111.538" width="50.3367" height="11.7921" class="st2"/> + <text x="-41.51" y="119.53" transform="scale(-1,1)" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>unmarshal</text> </g> + <g id="shape159-58" v:mID="159" v:groupContext="shape" transform="translate(165.129,-12.0586) scale(-1,1)"> + <title>Foglio.159</title> + <desc>marshal</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="25.1683" cy="117.434" width="50.34" height="11.7921"/> + <rect x="0" y="111.538" width="50.3367" height="11.7921" class="st2"/> + <text x="-37.62" y="119.53" transform="scale(-1,1)" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>marshal</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-23.svg b/spec/src/main/asciidoc/images/xmlb-23.svg new file mode 100644 index 0000000..57cf4f1 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-23.svg
@@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-23.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.00425in" + height="4.13417in" viewBox="0 0 432.306 297.66" xml:space="preserve" color-interpolation-filters="sRGB" class="st10"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {font-size:1em} + .st6 {fill:#000000;font-family:Arial;font-size:0.833336em;font-style:italic;font-weight:bold} + .st7 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic;font-weight:bold} + .st8 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape139-1" v:mID="139" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.139</title> + <rect x="0" y="1.44" width="430.866" height="296.22" class="st1"/> + </g> + <g id="shape146-3" v:mID="146" v:groupContext="shape" transform="translate(6.38929,-228.909)"> + <title>Foglio.146</title> + <rect x="0" y="235.298" width="85.0394" height="62.3622" class="st2"/> + </g> + <g id="shape171-5" v:mID="171" v:groupContext="shape" transform="translate(12.0586,-241.26)"> + <title>Foglio.171</title> + <desc>Original XML Infoset</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="28.2704" cy="278.83" width="56.55" height="37.6603"/> + <rect x="0" y="260" width="56.5409" height="37.6603" class="st3"/> + <text x="14.49" y="271.63" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Original <v:newlineChar/><tspan + x="20.05" dy="1.2em" class="st5">XML <v:newlineChar/></tspan><tspan x="16.26" dy="1.2em" class="st5">Infoset</tspan></text> </g> + <g id="shape174-10" v:mID="174" v:groupContext="shape" transform="translate(332.374,-228.909)"> + <title>Foglio.174</title> + <rect x="0" y="235.298" width="85.0394" height="62.3622" class="st2"/> + </g> + <g id="shape175-12" v:mID="175" v:groupContext="shape" transform="translate(338.043,-241.26)"> + <title>Foglio.175</title> + <desc>Reconstituted XML Infoset</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.6878" cy="278.83" width="59.38" height="37.6603"/> + <rect x="0" y="260" width="59.3755" height="37.6603" class="st3"/> + <text x="5.23" y="271.63" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Reconstituted <v:newlineChar/><tspan + x="21.46" dy="1.2em" class="st5">XML <v:newlineChar/></tspan><tspan x="17.68" dy="1.2em" class="st5">Infoset</tspan></text> </g> + <g id="shape176-17" v:mID="176" v:groupContext="shape" transform="translate(148.122,-7.80661)"> + <title>Foglio.176</title> + <rect x="0" y="28.3691" width="127.559" height="269.291" class="st2"/> + </g> + <g id="shape1-19" v:mID="1" v:groupContext="shape" transform="translate(133.948,-243.507)"> + <title>Foglio.1</title> + <desc>MIME-based Package</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="70.8661" cy="281.22" width="141.74" height="32.8819"/> + <rect x="0" y="264.779" width="141.732" height="32.8819" class="st3"/> + <text x="41.7" y="278.22" class="st6" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>MIME-based<v:newlineChar/><tspan + x="50.57" dy="1.2em" class="st5">Package</tspan></text> </g> + <g id="shape2-23" v:mID="2" v:groupContext="shape" transform="translate(162.295,-149.539)"> + <title>Foglio.2</title> + <rect x="0" y="209.786" width="102.047" height="87.874" class="st2"/> + </g> + <g id="shape3-25" v:mID="3" v:groupContext="shape" transform="translate(166.074,-212.297)"> + <title>Foglio.3</title> + <desc>Document (Root Part)</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.6939" cy="286.718" width="75.39" height="21.8857"/> + <rect x="0" y="275.775" width="75.3878" height="21.8857" class="st3"/> + <text x="19.46" y="284.32" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Document<v:newlineChar/><tspan + x="18.13" dy="1.2em" class="st5">(</tspan>Root Part)</text> </g> + <g id="shape4-29" v:mID="4" v:groupContext="shape" transform="translate(34.7357,-112.689)"> + <title>Foglio.4</title> + <rect x="0" y="235.298" width="85.0394" height="62.3622" rx="31.1811" ry="31.1811" class="st2"/> + </g> + <g id="shape5-31" v:mID="5" v:groupContext="shape" transform="translate(33.8922,-135.366)"> + <title>Foglio.5</title> + <desc>marshal</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.6939" cy="286.718" width="75.39" height="21.8857"/> + <rect x="0" y="275.775" width="75.3878" height="21.8857" class="st3"/> + <text x="23.47" y="289.12" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>marshal</text> </g> + <g id="shape6-34" v:mID="6" v:groupContext="shape" transform="translate(304.027,-112.689)"> + <title>Foglio.6</title> + <rect x="0" y="235.298" width="85.0394" height="62.3622" rx="31.1811" ry="31.1811" class="st2"/> + </g> + <g id="shape7-36" v:mID="7" v:groupContext="shape" transform="translate(303.184,-135.366)"> + <title>Foglio.7</title> + <desc>unmarshal</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.6939" cy="286.718" width="75.39" height="21.8857"/> + <rect x="0" y="275.775" width="75.3878" height="21.8857" class="st3"/> + <text x="19.02" y="289.12" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>unmarshal</text> </g> + <g id="shape8-39" v:mID="8" v:groupContext="shape" transform="translate(167.964,-152.629)"> + <title>Foglio.8</title> + <rect x="0" y="280.908" width="24.3185" height="16.7528" class="st2"/> + </g> + <g id="shape9-41" v:mID="9" v:groupContext="shape" transform="translate(166.865,-152.769)"> + <title>Foglio.9</title> + <desc>cid</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.8879" cy="289.354" width="23.78" height="16.6121"/> + <rect x="0" y="281.048" width="23.7758" height="16.6121" class="st3"/> + <text x="6.77" y="291.75" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>cid</text> </g> + <g id="shape10-44" v:mID="10" v:groupContext="shape" transform="translate(201.756,-152.629)"> + <title>Foglio.10</title> + <rect x="0" y="280.908" width="24.3185" height="16.7528" class="st2"/> + </g> + <g id="shape11-46" v:mID="11" v:groupContext="shape" transform="translate(200.657,-152.769)"> + <title>Foglio.11</title> + <desc>cid</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.8879" cy="289.354" width="23.78" height="16.6121"/> + <rect x="0" y="281.048" width="23.7758" height="16.6121" class="st3"/> + <text x="6.77" y="291.75" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>cid</text> </g> + <g id="shape12-49" v:mID="12" v:groupContext="shape" transform="translate(235.724,-152.629)"> + <title>Foglio.12</title> + <rect x="0" y="280.908" width="24.3185" height="16.7528" class="st2"/> + </g> + <g id="shape13-51" v:mID="13" v:groupContext="shape" transform="translate(234.626,-152.769)"> + <title>Foglio.13</title> + <desc>cid</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="11.8879" cy="289.354" width="23.78" height="16.6121"/> + <rect x="0" y="281.048" width="23.7758" height="16.6121" class="st3"/> + <text x="6.77" y="291.75" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>cid</text> </g> + <g id="shape14-54" v:mID="14" v:groupContext="shape" transform="translate(182.137,-21.9798)"> + <title>Foglio.14</title> + <rect x="0" y="209.786" width="77.2441" height="87.874" class="st2"/> + </g> + <g id="shape15-56" v:mID="15" v:groupContext="shape" transform="translate(174.342,-31.9011)"> + <title>Foglio.15</title> + <rect x="0" y="209.786" width="77.2441" height="87.874" class="st2"/> + </g> + <g id="shape16-58" v:mID="16" v:groupContext="shape" transform="translate(165.129,-41.8224)"> + <title>Foglio.16</title> + <rect x="0" y="209.786" width="77.2441" height="87.874" class="st2"/> + </g> + <g id="shape17-60" v:mID="17" v:groupContext="shape" transform="translate(159.46,-107.415)"> + <title>Foglio.17</title> + <desc>MIME PART</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="37.6939" cy="286.718" width="75.39" height="21.8857"/> + <rect x="0" y="275.775" width="75.3878" height="21.8857" class="st3"/> + <text x="15.47" y="289.12" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>MIME PART</text> </g> + <g id="shape18-63" v:mID="18" v:groupContext="shape" transform="translate(165.129,-82.1583)"> + <title>Foglio.18</title> + <desc>Binary Content</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="34.0157" cy="286.718" width="68.04" height="21.8857"/> + <rect x="0" y="275.775" width="68.0315" height="21.8857" class="st3"/> + <text x="21.57" y="284.32" class="st7" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Binary<v:newlineChar/><tspan + x="18.91" dy="1.2em" class="st5">Content</tspan></text> </g> + <g id="shape19-67" v:mID="19" v:groupContext="shape" transform="translate(340.906,30.9877) rotate(71.8675) scale(-1,1)"> + <title>Foglio.19</title> + <path d="M0 297.66 L56.62 297.66" class="st8"/> + </g> + <g id="shape20-70" v:mID="20" v:groupContext="shape" transform="translate(153.826,394.71) rotate(-20) scale(1,-1)"> + <title>Foglio.20</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape21-72" v:mID="21" v:groupContext="shape" transform="translate(20.5625,-41.8224)"> + <title>Foglio.21</title> + <desc>Extraction: AttachmentMarshaller.add*Attachment(data)</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="45.3163" cy="283.082" width="90.64" height="29.1564"/> + <rect x="0" y="268.504" width="90.6326" height="29.1564" class="st3"/> + <text x="4" y="275.88" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Extraction:<v:newlineChar/><tspan x="4" + dy="1.2em" class="st5">AttachmentMarshaller</tspan>.<tspan x="4" dy="1.2em" class="st5">add</tspan>*Attachment(data)</text> </g> + <g id="shape22-77" v:mID="22" v:groupContext="shape" transform="translate(348.242,20.5697) rotate(38.6598) scale(-1,1)"> + <title>Foglio.22</title> + <path d="M0 297.66 L108.9 297.66" class="st8"/> + </g> + <g id="shape23-80" v:mID="23" v:groupContext="shape" transform="translate(381.394,440.742) rotate(-50) scale(1,-1)"> + <title>Foglio.23</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape24-82" v:mID="24" v:groupContext="shape" transform="translate(124.239,-62.935) rotate(-63.1325) scale(-1,1)"> + <title>Foglio.24</title> + <path d="M0 297.66 L56.62 297.66" class="st8"/> + </g> + <g id="shape25-85" v:mID="25" v:groupContext="shape" transform="translate(513.715,-187.84) rotate(25) scale(-1,1)"> + <title>Foglio.25</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape26-87" v:mID="26" v:groupContext="shape" transform="translate(73.0092,20.5697) rotate(-38.6598)"> + <title>Foglio.26</title> + <path d="M0 297.66 L108.9 297.66" class="st8"/> + </g> + <g id="shape27-90" v:mID="27" v:groupContext="shape" transform="translate(39.8567,440.742) rotate(-130)"> + <title>Foglio.27</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape28-92" v:mID="28" v:groupContext="shape" transform="translate(149.249,-145.463) rotate(0.217013) scale(-1,1)"> + <title>Foglio.28</title> + <path d="M0 297.66 L28.39 297.66" class="st8"/> + </g> + <g id="shape29-95" v:mID="29" v:groupContext="shape" transform="translate(435.566,145.858) rotate(88.2) scale(-1,1)"> + <title>Foglio.29</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape30-97" v:mID="30" v:groupContext="shape" transform="translate(305.201,-144.803) rotate(0.217013) scale(-1,1)"> + <title>Foglio.30</title> + <path d="M0 297.66 L28.39 297.66" class="st8"/> + </g> + <g id="shape31-100" v:mID="31" v:groupContext="shape" transform="translate(591.518,146.518) rotate(88.2) scale(-1,1)"> + <title>Foglio.31</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape33-102" v:mID="33" v:groupContext="shape" transform="translate(31.0804,-87.3043)"> + <title>Foglio.33</title> + <rect x="0" y="280.908" width="88.6947" height="16.7528" class="st1"/> + </g> + <g id="shape32-104" v:mID="32" v:groupContext="shape" transform="translate(32.0532,-87.1767)"> + <title>Foglio.32</title> + <desc>For each binary data</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="41.0263" cy="287.739" width="82.06" height="19.8425"/> + <rect x="0" y="277.818" width="82.0527" height="19.8425" class="st3"/> + <text x="4.34" y="290.14" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>For each binary data</text> </g> + <g id="shape34-107" v:mID="34" v:groupContext="shape" transform="translate(289.854,-87.3043)"> + <title>Foglio.34</title> + <rect x="0" y="280.908" width="88.6947" height="16.7528" class="st1"/> + </g> + <g id="shape35-109" v:mID="35" v:groupContext="shape" transform="translate(290.827,-87.1767)"> + <title>Foglio.35</title> + <desc>For each content-id</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="41.0263" cy="287.739" width="82.06" height="19.8425"/> + <rect x="0" y="277.818" width="82.0527" height="19.8425" class="st3"/> + <text x="6.56" y="290.14" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>For each content-id</text> </g> + <g id="shape36-112" v:mID="36" v:groupContext="shape" transform="translate(455.629,247.117) rotate(-74.5785) scale(1,-1)"> + <title>Foglio.36</title> + <path d="M0 297.66 L23.93 297.66" class="st8"/> + </g> + <g id="shape37-115" v:mID="37" v:groupContext="shape" transform="translate(91.5874,445.075) rotate(15) scale(1,-1)"> + <title>Foglio.37</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape38-117" v:mID="38" v:groupContext="shape" transform="translate(438.279,-53.7856) rotate(38.8943) scale(-1,1)"> + <title>Foglio.38</title> + <path d="M0 297.66 L52.55 297.66" class="st8"/> + </g> + <g id="shape39-120" v:mID="39" v:groupContext="shape" transform="translate(469.552,364.559) rotate(-50) scale(1,-1)"> + <title>Foglio.39</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape40-122" v:mID="40" v:groupContext="shape" transform="translate(-41.9988,188.981) rotate(-90.217)"> + <title>Foglio.40</title> + <path d="M0 297.66 L42.96 297.66" class="st8"/> + </g> + <g id="shape41-125" v:mID="41" v:groupContext="shape" transform="translate(249.323,475.535) rotate(-178.2)"> + <title>Foglio.41</title> + <path d="M5.67 297.66 L0 297.66 L2.83 288.02 L5.67 297.66 Z" class="st9"/> + </g> + <g id="shape42-127" v:mID="42" v:groupContext="shape" transform="translate(295.523,-41.4174)"> + <title>Foglio.42</title> + <desc>Reconstitute: AttachmentUnmarshaller.getAttachmentAs*(cid)</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="51.0236" cy="283.082" width="102.05" height="29.1564"/> + <rect x="0" y="268.504" width="102.047" height="29.1564" class="st3"/> + <text x="4" y="275.88" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>Reconstitute:<v:newlineChar/><tspan x="4" + dy="1.2em" class="st5">AttachmentUnmarshaller</tspan>.<tspan x="4" dy="1.2em" class="st5">getAttachmentAs</tspan>*(cid)</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-3.svg b/spec/src/main/asciidoc/images/xmlb-3.svg new file mode 100644 index 0000000..51a390f --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-3.svg
@@ -0,0 +1,249 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-3.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.27984in" + height="4.35071in" viewBox="0 0 452.149 313.251" xml:space="preserve" color-interpolation-filters="sRGB" class="st12"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st5 {fill:#000000;font-family:Arial;font-size:0.833336em;font-weight:bold} + .st6 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st7 {font-size:1em} + .st8 {stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st11 {font-size:1em;font-weight:bold} + .st12 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="450.709" height="311.811" class="st1"/> + </g> + <g id="shape23-3" v:mID="23" v:groupContext="shape" transform="translate(6.38929,-46.0743)"> + <title>Foglio.23</title> + <path d="M0 313.25 L96.38 313.25 L96.38 106.32 L0 106.32 L0 313.25 Z" class="st2"/> + </g> + <g id="shape6-5" v:mID="6" v:groupContext="shape" transform="translate(9.22394,-200.563)"> + <title>Foglio.6</title> + <rect x="0" y="265.062" width="90.7087" height="48.189" class="st3"/> + </g> + <g id="shape21-7" v:mID="21" v:groupContext="shape" transform="translate(12.0586,-216.153)"> + <title>Foglio.21</title> + <desc>Schema</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="25.5118" cy="304.342" width="51.03" height="17.8178"/> + <rect x="0" y="295.433" width="51.0236" height="17.8178" class="st4"/> + <text x="4" y="307.34" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Schema</text> </g> + <g id="shape47-10" v:mID="47" v:groupContext="shape" transform="translate(9.22394,-51.7436)"> + <title>Foglio.47</title> + <rect x="0" y="253.723" width="90.7087" height="59.5276" class="st3"/> + </g> + <g id="shape20-12" v:mID="20" v:groupContext="shape" transform="translate(12.0586,-60.2476)"> + <title>Foglio.20</title> + <desc>XML/Java Customization Binding Declaration</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="287.739" width="104.89" height="51.0236"/> + <rect x="0" y="262.227" width="104.882" height="51.0236" class="st4"/> + <text x="4" y="275.74" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>XML/Java <v:newlineChar/><tspan x="4" + dy="1.2em" class="st7">Customization<v:newlineChar/></tspan><tspan x="4" dy="1.2em" class="st7">Binding<v:newlineChar/></tspan><tspan + x="4" dy="1.2em" class="st7">Declaration</tspan></text> </g> + <g id="shape48-18" v:mID="48" v:groupContext="shape" transform="translate(111.271,-124.027)"> + <title>Foglio.48</title> + <rect x="0" y="265.062" width="73.7008" height="48.189" rx="14.1732" ry="14.1732" class="st3"/> + </g> + <g id="shape49-20" v:mID="49" v:groupContext="shape" transform="translate(114.106,-138.808)"> + <title>Foglio.49</title> + <desc>Schema Compiler</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="301.507" width="59.53" height="23.4871"/> + <rect x="0" y="289.764" width="59.5276" height="23.4871" class="st4"/> + <text x="4" y="298.51" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Schema<v:newlineChar/><tspan x="4" + dy="1.2em" class="st7">Compiler</tspan></text> </g> + <g id="shape50-24" v:mID="50" v:groupContext="shape" transform="translate(321.435,-130.802) rotate(45)"> + <title>Foglio.50</title> + <path d="M-0 313.25 A39.685 43.9576 0 0 1 56.12 313.25" class="st8"/> + </g> + <g id="shape51-27" v:mID="51" v:groupContext="shape" transform="translate(142.452,440.396) rotate(180)"> + <title>Foglio.51</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape52-29" v:mID="52" v:groupContext="shape" transform="translate(340.223,444.436) rotate(-50) scale(1,-1)"> + <title>Foglio.52</title> + <path d="M-0 313.25 A39.685 43.9576 0 0 1 56.12 313.25" class="st8"/> + </g> + <g id="shape53-32" v:mID="53" v:groupContext="shape" transform="translate(139.618,-109.287) scale(-1,1)"> + <title>Foglio.53</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape29-34" v:mID="29" v:groupContext="shape" transform="translate(362.475,421.343) rotate(157.299)"> + <title>Foglio.29</title> + <path d="M0 313.25 L61.04 313.25" class="st8"/> + </g> + <g id="shape30-37" v:mID="30" v:groupContext="shape" transform="translate(525.715,26.0219) rotate(70)"> + <title>Foglio.30</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape54-39" v:mID="54" v:groupContext="shape" transform="translate(120.775,483.907) rotate(-157.299)"> + <title>Foglio.54</title> + <path d="M0 313.25 L61.04 313.25" class="st8"/> + </g> + <g id="shape55-42" v:mID="55" v:groupContext="shape" transform="translate(527.706,296.071) rotate(110)"> + <title>Foglio.55</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape56-44" v:mID="56" v:groupContext="shape" transform="translate(114.106,-9.22394)"> + <title>Foglio.56</title> + <rect x="0" y="265.062" width="121.89" height="48.189" class="st3"/> + </g> + <g id="shape57-46" v:mID="57" v:groupContext="shape" transform="translate(116.94,-39.5951)"> + <title>Foglio.57</title> + <desc>Binding Legend</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="43.937" cy="304.342" width="87.88" height="17.8178"/> + <rect x="0" y="295.433" width="87.874" height="17.8178" class="st4"/> + <text x="4" y="307.34" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Binding Legend</text> </g> + <g id="shape58-49" v:mID="58" v:groupContext="shape" transform="translate(134.181,594.753) rotate(180)"> + <title>Foglio.58</title> + <path d="M0 313.25 L14.41 313.25" class="st8"/> + </g> + <g id="shape59-52" v:mID="59" v:groupContext="shape" transform="translate(446.066,278.515) rotate(90)"> + <title>Foglio.59</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape60-54" v:mID="60" v:groupContext="shape" transform="translate(134.181,608.926) rotate(180)"> + <title>Foglio.60</title> + <path d="M0 313.25 L14.41 313.25" class="st10"/> + </g> + <g id="shape61-57" v:mID="61" v:groupContext="shape" transform="translate(446.066,292.689) rotate(90)"> + <title>Foglio.61</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape27-59" v:mID="27" v:groupContext="shape" transform="translate(142.452,-22.9922)"> + <title>Foglio.27</title> + <desc>Schema to Java</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="36.8504" cy="304.342" width="73.71" height="17.8178"/> + <rect x="0" y="295.433" width="73.7008" height="17.8178" class="st4"/> + <text x="4" y="306.74" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Schema to Java</text> </g> + <g id="shape62-62" v:mID="62" v:groupContext="shape" transform="translate(142.452,-8.81899)"> + <title>Foglio.62</title> + <desc>Java to Schema</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="36.8504" cy="304.342" width="73.71" height="17.8178"/> + <rect x="0" y="295.433" width="73.7008" height="17.8178" class="st4"/> + <text x="4" y="306.74" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Java to Schema</text> </g> + <g id="shape63-65" v:mID="63" v:groupContext="shape" transform="translate(241.665,-9.22394)"> + <title>Foglio.63</title> + <path d="M0 313.25 L204.09 313.25 L204.09 49.63 L0 49.63 L0 313.25 Z" class="st2"/> + </g> + <g id="shape25-67" v:mID="25" v:groupContext="shape" transform="translate(245.715,-233.161)"> + <title>Foglio.25</title> + <rect x="0" y="278.83" width="197.209" height="34.4207" class="st3"/> + </g> + <g id="shape28-69" v:mID="28" v:groupContext="shape" transform="translate(290.066,-240.855)"> + <title>Foglio.28</title> + <desc>Application Code</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.579" cy="304.342" width="79.16" height="17.8178"/> + <rect x="0" y="295.433" width="79.158" height="17.8178" class="st4"/> + <text x="4" y="306.74" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Application Code</text> </g> + <g id="shape64-72" v:mID="64" v:groupContext="shape" transform="translate(246.525,-179.303)"> + <title>Foglio.64</title> + <rect x="0" y="264.86" width="94.3527" height="48.3915" class="st3"/> + </g> + <g id="shape65-74" v:mID="65" v:groupContext="shape" transform="translate(247.44,-190.641)"> + <title>Foglio.65</title> + <desc>Portable JAXB-annotated classes</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.579" cy="296.243" width="79.16" height="34.0157"/> + <rect x="0" y="279.235" width="79.158" height="34.0157" class="st4"/> + <text x="4" y="289.04" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Portable<v:newlineChar/><tspan x="4" + dy="1.2em" class="st11">JAXB</tspan><tspan class="st11">-</tspan><tspan class="st11">annotated<v:newlineChar/></tspan><tspan + x="4" dy="1.2em" class="st11">classes</tspan></text> </g> + <g id="shape66-81" v:mID="66" v:groupContext="shape" transform="translate(346.547,-193.071)"> + <title>Foglio.66</title> + <rect x="0" y="278.83" width="96.378" height="34.4207" class="st3"/> + </g> + <g id="shape67-83" v:mID="67" v:groupContext="shape" transform="translate(347.462,-193.273)"> + <title>Foglio.67</title> + <desc>Package javax.xml.bind</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="30.7234" cy="296.243" width="61.45" height="34.0157"/> + <rect x="0" y="279.235" width="61.4468" height="34.0157" class="st4"/> + <text x="4" y="293.84" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Package<v:newlineChar/><tspan x="4" + dy="1.2em" class="st7">javax</tspan>.xml.bind</text> </g> + <g id="shape68-87" v:mID="68" v:groupContext="shape" transform="translate(247.334,-85.7594)"> + <title>Foglio.68</title> + <rect x="0" y="267.694" width="85.0394" height="45.5568" class="st3"/> + </g> + <g id="shape69-89" v:mID="69" v:groupContext="shape" transform="translate(253.003,-97.098)"> + <title>Foglio.69</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="30.7234" cy="296.243" width="61.45" height="34.0157"/> + <rect x="0" y="279.235" width="61.4468" height="34.0157" class="st4"/> + <text x="4" y="298.64" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>ObjectFactory</text> </g> + <g id="shape70-92" v:mID="70" v:groupContext="shape" transform="translate(335.208,-85.7594)"> + <title>Foglio.70</title> + <rect x="0" y="267.694" width="107.717" height="45.5568" class="st3"/> + </g> + <g id="shape71-94" v:mID="71" v:groupContext="shape" transform="translate(340.877,-94.2633)"> + <title>Foglio.71</title> + <desc>Annotation-driven Binding Framework Implementation</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="49.1486" cy="296.243" width="98.3" height="34.0157"/> + <rect x="0" y="279.235" width="98.2972" height="34.0157" class="st4"/> + <text x="4" y="289.04" class="st6" v:langID="1040"><v:paragraph/><v:tabList/>Annotation-driven <v:newlineChar/><tspan + x="4" dy="1.2em" class="st7">Binding Framework<v:newlineChar/></tspan><tspan x="4" dy="1.2em" class="st7">Implementation</tspan></text> </g> + <g id="shape72-99" v:mID="72" v:groupContext="shape" transform="translate(111.271,-258.673)"> + <title>Foglio.72</title> + <rect x="0" y="265.062" width="73.7008" height="48.189" rx="14.1732" ry="14.1732" class="st3"/> + </g> + <g id="shape73-101" v:mID="73" v:groupContext="shape" transform="translate(114.106,-273.453)"> + <title>Foglio.73</title> + <desc>Schema Generator</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="301.507" width="59.53" height="23.4871"/> + <rect x="0" y="289.764" width="59.5276" height="23.4871" class="st4"/> + <text x="4" y="298.51" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Schema<v:newlineChar/><tspan x="4" + dy="1.2em" class="st7">Generator</tspan></text> </g> + <g id="shape74-105" v:mID="74" v:groupContext="shape" transform="translate(-113.871,-159.139) rotate(-45)"> + <title>Foglio.74</title> + <path d="M0 313.25 L14.41 313.25" class="st10"/> + </g> + <g id="shape75-108" v:mID="75" v:groupContext="shape" transform="translate(-110.231,284.341) rotate(-135)"> + <title>Foglio.75</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape76-110" v:mID="76" v:groupContext="shape" transform="translate(374.302,-196.828) rotate(37.0559)"> + <title>Foglio.76</title> + <path d="M0 313.25 L70.33 313.25" class="st10"/> + </g> + <g id="shape77-113" v:mID="77" v:groupContext="shape" transform="translate(-52.6165,-143.301) rotate(-50)"> + <title>Foglio.77</title> + <path d="M5.67 313.25 L0 313.25 L2.83 303.61 L5.67 313.25 Z" class="st9"/> + </g> + <g id="shape2-115" v:mID="2" v:groupContext="shape" transform="translate(291.271,-11.2487)"> + <title>Foglio.2</title> + <desc>Application</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="32.5984" cy="304.342" width="65.2" height="17.8178"/> + <rect x="0" y="295.433" width="65.1969" height="17.8178" class="st4"/> + <text x="4" y="307.34" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Application</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-4.svg b/spec/src/main/asciidoc/images/xmlb-4.svg new file mode 100644 index 0000000..ead96f3 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-4.svg
@@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-4.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="6.27984in" + height="3.28772in" viewBox="0 0 452.149 236.716" xml:space="preserve" color-interpolation-filters="sRGB" class="st10"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-dasharray:5.04,3.6;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st5 {fill:#000000;font-family:Arial;font-size:0.833336em;font-weight:bold} + .st6 {font-size:1em} + .st7 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st8 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape1-1" v:mID="1" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.1</title> + <rect x="0" y="1.44" width="450.709" height="235.276" class="st1"/> + </g> + <g id="shape23-3" v:mID="23" v:groupContext="shape" transform="translate(6.67276,-9.22394)"> + <title>Foglio.23</title> + <path d="M0 236.72 L96.38 236.72 L96.38 29.79 L0 29.79 L0 236.72 Z" class="st2"/> + </g> + <g id="shape6-5" v:mID="6" v:groupContext="shape" transform="translate(9.5074,-163.712)"> + <title>Foglio.6</title> + <rect x="0" y="188.527" width="90.7087" height="48.189" class="st3"/> + </g> + <g id="shape21-7" v:mID="21" v:groupContext="shape" transform="translate(12.342,-173.228)"> + <title>Foglio.21</title> + <desc>Source Schema</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="25.5118" cy="222.137" width="51.03" height="29.1564"/> + <rect x="0" y="207.559" width="51.0236" height="29.1564" class="st4"/> + <text x="4" y="219.14" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Source<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">Schema</tspan></text> </g> + <g id="shape47-11" v:mID="47" v:groupContext="shape" transform="translate(9.5074,-14.8932)"> + <title>Foglio.47</title> + <rect x="0" y="177.188" width="90.7087" height="59.5276" class="st3"/> + </g> + <g id="shape20-13" v:mID="20" v:groupContext="shape" transform="translate(12.342,-23.3972)"> + <title>Foglio.20</title> + <desc>XML/Java Customization Binding Declarations</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="52.4409" cy="211.204" width="104.89" height="51.0236"/> + <rect x="0" y="185.692" width="104.882" height="51.0236" class="st4"/> + <text x="4" y="199.2" class="st7" v:langID="1040"><v:paragraph/><v:tabList/>XML/Java <v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">Customization<v:newlineChar/></tspan><tspan x="4" dy="1.2em" class="st6">Binding<v:newlineChar/></tspan><tspan + x="4" dy="1.2em" class="st6">Declarations</tspan></text> </g> + <g id="shape48-19" v:mID="48" v:groupContext="shape" transform="translate(111.555,-87.1767)"> + <title>Foglio.48</title> + <rect x="0" y="188.527" width="73.7008" height="48.189" rx="14.1732" ry="14.1732" class="st3"/> + </g> + <g id="shape49-21" v:mID="49" v:groupContext="shape" transform="translate(114.389,-101.957)"> + <title>Foglio.49</title> + <desc>Binding Compiler</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="224.972" width="59.53" height="23.4871"/> + <rect x="0" y="213.229" width="59.5276" height="23.4871" class="st4"/> + <text x="4" y="221.97" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Binding<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">Compiler</tspan></text> </g> + <g id="shape50-25" v:mID="50" v:groupContext="shape" transform="translate(267.599,-116.368) rotate(45)"> + <title>Foglio.50</title> + <path d="M-0 236.72 A39.685 43.9576 0 0 1 56.12 236.72" class="st8"/> + </g> + <g id="shape51-28" v:mID="51" v:groupContext="shape" transform="translate(142.736,324.176) rotate(180)"> + <title>Foglio.51</title> + <path d="M5.67 236.72 L0 236.72 L2.83 227.08 L5.67 236.72 Z" class="st9"/> + </g> + <g id="shape52-30" v:mID="52" v:groupContext="shape" transform="translate(281.877,355.555) rotate(-50) scale(1,-1)"> + <title>Foglio.52</title> + <path d="M-0 236.72 A39.685 43.9576 0 0 1 56.12 236.72" class="st8"/> + </g> + <g id="shape53-33" v:mID="53" v:groupContext="shape" transform="translate(139.901,-72.4365) scale(-1,1)"> + <title>Foglio.53</title> + <path d="M5.67 236.72 L0 236.72 L2.83 227.08 L5.67 236.72 Z" class="st9"/> + </g> + <g id="shape29-35" v:mID="29" v:groupContext="shape" transform="translate(333.222,311.052) rotate(157.299)"> + <title>Foglio.29</title> + <path d="M0 236.72 L61.04 236.72" class="st8"/> + </g> + <g id="shape30-38" v:mID="30" v:groupContext="shape" transform="translate(454.079,12.5135) rotate(70)"> + <title>Foglio.30</title> + <path d="M5.67 236.72 L0 236.72 L2.83 227.08 L5.67 236.72 Z" class="st9"/> + </g> + <g id="shape54-40" v:mID="54" v:groupContext="shape" transform="translate(150.595,373.616) rotate(-157.299)"> + <title>Foglio.54</title> + <path d="M0 236.72 L61.04 236.72" class="st8"/> + </g> + <g id="shape55-43" v:mID="55" v:groupContext="shape" transform="translate(456.07,230.21) rotate(110)"> + <title>Foglio.55</title> + <path d="M5.67 236.72 L0 236.72 L2.83 227.08 L5.67 236.72 Z" class="st9"/> + </g> + <g id="shape25-45" v:mID="25" v:groupContext="shape" transform="translate(245.999,-196.311)"> + <title>Foglio.25</title> + <rect x="0" y="202.295" width="197.209" height="34.4207" class="st3"/> + </g> + <g id="shape28-47" v:mID="28" v:groupContext="shape" transform="translate(275.964,-204.005)"> + <title>Foglio.28</title> + <desc>Application Code</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="46.7717" cy="227.807" width="93.55" height="17.8178"/> + <rect x="0" y="218.898" width="93.5433" height="17.8178" class="st4"/> + <text x="4" y="230.81" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Application Code</text> </g> + <g id="shape64-50" v:mID="64" v:groupContext="shape" transform="translate(245.796,-122.61)"> + <title>Foglio.64</title> + <rect x="0" y="163.015" width="101.035" height="73.7008" class="st3"/> + </g> + <g id="shape65-52" v:mID="65" v:groupContext="shape" transform="translate(246.306,-149.539)"> + <title>Foglio.65</title> + <desc>Schema Derived Interfaces, Factory Methods</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="39.579" cy="219.708" width="79.16" height="34.0157"/> + <rect x="0" y="202.7" width="79.158" height="34.0157" class="st4"/> + <text x="4" y="212.51" class="st7" v:langID="1040"><v:paragraph/><v:tabList/>Schema Derived <tspan x="4" dy="1.2em" + class="st6">Interfaces</tspan>,<v:newlineChar/><tspan x="4" dy="1.2em" class="st6">Factory Methods</tspan></text> </g> + <g id="shape66-57" v:mID="66" v:groupContext="shape" transform="translate(346.83,-122.918)"> + <title>Foglio.66</title> + <rect x="0" y="163.632" width="96.378" height="73.084" class="st3"/> + </g> + <g id="shape67-59" v:mID="67" v:groupContext="shape" transform="translate(349.163,-150.956)"> + <title>Foglio.67</title> + <desc>Package javax.xml.bind</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="30.7234" cy="219.708" width="61.45" height="34.0157"/> + <rect x="0" y="202.7" width="61.4468" height="34.0157" class="st4"/> + <text x="4" y="217.31" class="st7" v:langID="1040"><v:paragraph/><v:tabList/>Package<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">javax</tspan>.xml.bind</text> </g> + <g id="shape68-63" v:mID="68" v:groupContext="shape" transform="translate(245.775,-48.909)"> + <title>Foglio.68</title> + <rect x="0" y="163.015" width="101.055" height="73.7008" class="st3"/> + </g> + <g id="shape69-65" v:mID="69" v:groupContext="shape" transform="translate(246.2,-71.5861)"> + <title>Foglio.69</title> + <desc>Implementation classes, helper classes, ...</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.558" cy="215.557" width="67.12" height="42.3172"/> + <rect x="0" y="194.398" width="67.1161" height="42.3172" class="st4"/> + <text x="4" y="208.36" class="st7" v:langID="1040"><v:paragraph/><v:tabList/>Implementation <tspan x="4" dy="1.2em" + class="st6">classes</tspan>, helper <tspan x="4" dy="1.2em" class="st6">classes</tspan>, ...</text> </g> + <g id="shape70-70" v:mID="70" v:groupContext="shape" transform="translate(346.83,-48.909)"> + <title>Foglio.70</title> + <rect x="0" y="163.015" width="96.378" height="73.7008" class="st3"/> + </g> + <g id="shape71-72" v:mID="71" v:groupContext="shape" transform="translate(346.83,-75.7369)"> + <title>Foglio.71</title> + <desc>Binding Framework Implementation</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="49.1486" cy="219.708" width="98.3" height="34.0157"/> + <rect x="0" y="202.7" width="98.2972" height="34.0157" class="st4"/> + <text x="4" y="212.51" class="st7" v:langID="1040"><v:paragraph/><v:tabList/>Binding<v:newlineChar/><tspan x="4" + dy="1.2em" class="st6">Framework<v:newlineChar/></tspan><tspan x="4" dy="1.2em" class="st6">Implementation</tspan></text> </g> + <g id="shape2-77" v:mID="2" v:groupContext="shape" transform="translate(314.232,-27.6491)"> + <title>Foglio.2</title> + <desc>Application</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="32.5984" cy="227.807" width="65.2" height="17.8178"/> + <rect x="0" y="218.898" width="65.1969" height="17.8178" class="st4"/> + <text x="4" y="230.81" class="st5" v:langID="1040"><v:paragraph/><v:tabList/>Application</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-8.svg b/spec/src/main/asciidoc/images/xmlb-8.svg new file mode 100644 index 0000000..e7c1ef7 --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-8.svg
@@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-8.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.45307in" + height="2.57906in" viewBox="0 0 392.621 185.692" xml:space="preserve" color-interpolation-filters="sRGB" class="st16"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.833336em;font-weight:bold} + .st5 {font-size:1em} + .st6 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {font-size:1em;font-style:italic;font-weight:normal} + .st8 {stroke:#000000;stroke-dasharray:0.72,1.44;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st9 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st10 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st11 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st12 {fill:#000000;font-family:Arial;font-size:0.666664em;font-style:italic} + .st13 {font-size:1em;font-style:normal} + .st14 {fill:#000000;font-family:Arial;font-size:0.666664em;font-weight:bold} + .st15 {font-size:1em;font-weight:normal} + .st16 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape139-1" v:mID="139" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.139</title> + <rect x="0" y="1.44" width="391.181" height="184.252" class="st1"/> + </g> + <g id="shape160-3" v:mID="160" v:groupContext="shape" transform="translate(9.22394,-131.114)"> + <title>Foglio.160</title> + <path d="M0 185.69 L73.7 185.69 L73.7 143.17 L0 143.17 L0 185.69 Z" class="st2"/> + </g> + <g id="shape9-5" v:mID="9" v:groupContext="shape" transform="translate(9.22394,-139.618)"> + <title>Foglio.9</title> + <desc>new instance</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="169.251" width="59.53" height="32.8819"/> + <rect x="0" y="152.81" width="59.5276" height="32.8819" class="st3"/> + <text x="20.04" y="166.25" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>new<v:newlineChar/><tspan + x="9.48" dy="1.2em" class="st5">instance</tspan></text> </g> + <g id="shape161-9" v:mID="161" v:groupContext="shape" transform="translate(200.137,-131.114)"> + <title>Foglio.161</title> + <rect x="0" y="143.172" width="141.732" height="42.5197" rx="11.3386" ry="11.3386" class="st6"/> + </g> + <g id="shape162-11" v:mID="162" v:groupContext="shape" transform="translate(207.649,-136.783)"> + <title>Foglio.162</title> + <desc>Unset (default, null or nil)</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="48.189" cy="168.684" width="96.38" height="34.0157"/> + <rect x="0" y="151.676" width="96.378" height="34.0157" class="st3"/> + <text x="34.3" y="165.68" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Unset<v:newlineChar/><tspan + x="7.06" dy="1.2em" class="st7">(</tspan><tspan class="st7">default</tspan><tspan class="st7">, </tspan><tspan + class="st7">null or nil</tspan><tspan class="st7">)</tspan></text> </g> + <g id="shape165-19" v:mID="165" v:groupContext="shape" transform="translate(199.613,-150.956) rotate(0.10063) scale(-1,1)"> + <title>Foglio.165</title> + <path d="M0 185.69 L116.36 185.69" class="st8"/> + </g> + <g id="shape166-22" v:mID="166" v:groupContext="shape" transform="translate(375.341,37.5704) rotate(90) scale(-1,1)"> + <title>Foglio.166</title> + <path d="M5.67 185.69 L0 185.69 L2.83 176.05 L5.67 185.69 Z" class="st9"/> + </g> + <g id="shape171-24" v:mID="171" v:groupContext="shape" transform="translate(83.0768,-129.291)"> + <title>Foglio.171</title> + <desc>contains 0...N properties</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="176.783" width="67.88" height="17.8178"/> + <rect x="0" y="167.874" width="67.8794" height="17.8178" class="st3"/> + <text x="9.48" y="174.38" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>contains 0...N<v:newlineChar/><tspan + x="16.15" dy="1.2em" class="st5">properties</tspan></text> </g> + <g id="shape172-28" v:mID="172" v:groupContext="shape" transform="translate(200.563,-6.38929)"> + <title>Foglio.172</title> + <rect x="0" y="143.172" width="141.732" height="42.5197" rx="11.3386" ry="11.3386" class="st6"/> + </g> + <g id="shape173-30" v:mID="173" v:groupContext="shape" transform="translate(204.814,-14.8932)"> + <title>Foglio.173</title> + <desc>Set value</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="48.189" cy="168.684" width="96.38" height="34.0157"/> + <rect x="0" y="151.676" width="96.378" height="34.0157" class="st3"/> + <text x="26.23" y="171.69" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>Set value</text> </g> + <g id="shape140-33" v:mID="140" v:groupContext="shape" transform="translate(421.688,136.783) rotate(90) scale(-1,1)"> + <title>Foglio.140</title> + <path d="M0 185.69 L82.2 185.69" class="st11"/> + </g> + <g id="shape141-36" v:mID="141" v:groupContext="shape" transform="translate(233.161,312.837) scale(1,-1)"> + <title>Foglio.141</title> + <path d="M5.67 185.69 L0 185.69 L2.83 176.05 L5.67 185.69 Z" class="st9"/> + </g> + <g id="shape142-38" v:mID="142" v:groupContext="shape" transform="translate(121.17,54.5783) rotate(-90) scale(-1,1)"> + <title>Foglio.142</title> + <path d="M0 185.69 L82.2 185.69" class="st11"/> + </g> + <g id="shape143-41" v:mID="143" v:groupContext="shape" transform="translate(309.696,-121.476) scale(-1,1)"> + <title>Foglio.143</title> + <path d="M5.67 185.69 L0 185.69 L2.83 176.05 L5.67 185.69 Z" class="st9"/> + </g> + <g id="shape144-43" v:mID="144" v:groupContext="shape" transform="translate(148.198,-76.4455)"> + <title>Foglio.144</title> + <desc>unmarshal or set(v) or List.size()>0</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="171.114" width="67.88" height="29.1564"/> + <rect x="0" y="156.536" width="67.8794" height="29.1564" class="st3"/> + <text x="15.26" y="163.91" class="st12" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>unmarshal<v:newlineChar/><tspan + x="19.27" dy="1.2em" class="st13">or set</tspan><tspan class="st13">(</tspan><tspan class="st13">v</tspan><tspan + class="st13">)<v:newlineChar/></tspan><tspan x="7.6" dy="1.2em" class="st13">or List</tspan><tspan + class="st13">.</tspan><tspan class="st13">size</tspan><tspan class="st13">()</tspan><tspan class="st13">></tspan><tspan + class="st13">0</tspan></text> </g> + <g id="shape145-56" v:mID="145" v:groupContext="shape" transform="translate(306.862,-76.8505)"> + <title>Foglio.145</title> + <desc>unset() or set(null) or List.size()==0</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="171.114" width="67.88" height="29.1564"/> + <rect x="0" y="156.536" width="67.8794" height="29.1564" class="st3"/> + <text x="16.82" y="163.91" class="st10" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/>unset() or<v:newlineChar/><tspan + x="15.05" dy="1.2em" class="st5">set</tspan>(null) or<v:newlineChar/><tspan x="9.93" dy="1.2em" class="st5">List</tspan>.size()==0</text> </g> + <g id="shape146-61" v:mID="146" v:groupContext="shape" transform="translate(9.22394,-3.55465)"> + <title>Foglio.146</title> + <rect x="0" y="123.33" width="178.583" height="62.3622" class="st6"/> + </g> + <g id="shape147-63" v:mID="147" v:groupContext="shape" transform="translate(9.22394,-17.7279)"> + <title>Foglio.147</title> + <desc>Legend: new instance – create JAXB object default – schema sp...</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="70.8661" cy="161.597" width="141.74" height="48.189"/> + <rect x="0" y="137.503" width="141.732" height="48.189" class="st3"/> + <text x="4" y="149.56" class="st14" v:langID="1040"><v:paragraph/><v:tabList/>Legend:<v:newlineChar/><v:paragraph/><tspan + x="4" dy="1.202em" class="st7">new instance</tspan><tspan class="st15"> </tspan><tspan class="st15">–</tspan><tspan + class="st15"> </tspan><tspan class="st15">create JAXB object<v:newlineChar/></tspan><tspan x="4" + dy="1.203em" class="st7">default</tspan><tspan class="st15"> </tspan><tspan class="st15">–</tspan><tspan + class="st15"> </tspan><tspan class="st15">schema specified default<v:newlineChar/></tspan><tspan x="4" + dy="1.203em" class="st7">null</tspan><tspan class="st15"> </tspan><tspan class="st15">–</tspan><tspan + class="st15"> </tspan><tspan class="st15">uninitialized JVM field default</tspan></text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/images/xmlb-9.svg b/spec/src/main/asciidoc/images/xmlb-9.svg new file mode 100644 index 0000000..44018da --- /dev/null +++ b/spec/src/main/asciidoc/images/xmlb-9.svg
@@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<!-- Generato da Microsoft Visio 11.0, SVG Export, v1.0 xmlb-9.svg Pagina 1 --> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.05937in" + height="1.16173in" viewBox="0 0 364.275 83.6447" xml:space="preserve" color-interpolation-filters="sRGB" class="st7"> + <v:documentProperties v:langID="1040" v:metric="true" v:viewMarkup="false"> + <v:userDefs> + <v:ud v:nameU="MBSAAddinOutlineVisible" v:prompt="" v:val="VT0(1):26"/> + </v:userDefs> + </v:documentProperties> + + <style type="text/css"> + <![CDATA[ + .st1 {fill:#ffffff;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st2 {fill:#ffffff;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st3 {fill:none;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st4 {fill:#000000;font-family:Arial;font-size:0.666664em} + .st5 {stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st6 {fill:#000000;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.72} + .st7 {fill:none;fill-rule:evenodd;font-size:12;overflow:visible;stroke-linecap:square;stroke-miterlimit:3} + ]]> + </style> + + <g v:mID="0" v:index="1" v:groupContext="foregroundPage"> + <title>Pagina 1</title> + <v:pageProperties v:drawingScale="0.0393701" v:pageScale="0.0393701" v:drawingUnits="24" v:shadowOffsetX="8.50394" + v:shadowOffsetY="-8.50394"/> + <g id="shape139-1" v:mID="139" v:groupContext="shape" transform="translate(0.72,-0.72)"> + <title>Foglio.139</title> + <rect x="0" y="1.44" width="362.835" height="82.2047" class="st1"/> + </g> + <g id="shape160-3" v:mID="160" v:groupContext="shape" transform="translate(9.22394,-57.4129)"> + <title>Foglio.160</title> + <rect x="0" y="66.6369" width="73.7008" height="17.0079" class="st2"/> + </g> + <g id="shape9-5" v:mID="9" v:groupContext="shape" transform="translate(9.22394,-56.2791)"> + <title>Foglio.9</title> + <desc><<FooType>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="75.1408" width="59.53" height="17.0079"/> + <rect x="0" y="66.6369" width="59.5276" height="17.0079" class="st3"/> + <text x="4.63" y="77.54" class="st4" v:langID="1040"><v:paragraph v:horizAlign="1"/><v:tabList/><<FooType>></text> </g> + <g id="shape145-8" v:mID="145" v:groupContext="shape" transform="translate(95.2988,-32.9139) rotate(45)"> + <title>Foglio.145</title> + <path d="M0 83.64 L44.02 83.64" class="st5"/> + </g> + <g id="shape146-11" v:mID="146" v:groupContext="shape" transform="translate(-17.9022,-23.5256) rotate(-45)"> + <title>Foglio.146</title> + <path d="M5.67 83.64 L0 83.64 L2.83 74.01 L5.67 83.64 Z" class="st6"/> + </g> + <g id="shape161-13" v:mID="161" v:groupContext="shape" transform="translate(94.2633,-57.4129)"> + <title>Foglio.161</title> + <rect x="0" y="66.6369" width="141.732" height="17.0079" class="st2"/> + </g> + <g id="shape162-15" v:mID="162" v:groupContext="shape" transform="translate(94.2633,-56.603)"> + <title>Foglio.162</title> + <desc><<javax.xml.bind.Element>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="70.8661" cy="74.7358" width="141.74" height="17.8178"/> + <rect x="0" y="65.827" width="141.732" height="17.8178" class="st3"/> + <text x="4" y="77.14" class="st4" v:langID="1040"><v:paragraph/><v:tabList/><<javax.xml.bind.Element>></text> </g> + <g id="shape163-18" v:mID="163" v:groupContext="shape" transform="translate(46.0743,-9.22394)"> + <title>Foglio.163</title> + <rect x="0" y="66.6369" width="62.3622" height="17.0079" class="st2"/> + </g> + <g id="shape164-20" v:mID="164" v:groupContext="shape" transform="translate(48.6255,-8.65701)"> + <title>Foglio.164</title> + <desc><<Foo>></desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="29.7638" cy="75.1408" width="59.53" height="17.0079"/> + <rect x="0" y="66.6369" width="59.5276" height="17.0079" class="st3"/> + <text x="4" y="77.54" class="st4" v:langID="1040"><v:paragraph/><v:tabList/><<Foo>></text> </g> + <g id="shape165-23" v:mID="165" v:groupContext="shape" transform="translate(56.3258,-32.8623) rotate(-45) scale(-1,1)"> + <title>Foglio.165</title> + <path d="M0 83.64 L44.02 83.64" class="st5"/> + </g> + <g id="shape166-26" v:mID="166" v:groupContext="shape" transform="translate(169.527,-23.474) rotate(45) scale(-1,1)"> + <title>Foglio.166</title> + <path d="M5.67 83.64 L0 83.64 L2.83 74.01 L5.67 83.64 Z" class="st6"/> + </g> + <g id="shape167-28" v:mID="167" v:groupContext="shape" transform="translate(270.011,-58.2228)"> + <title>Foglio.167</title> + <rect x="0" y="66.6369" width="87.874" height="17.0079" class="st2"/> + </g> + <g id="shape168-30" v:mID="168" v:groupContext="shape" transform="translate(274.339,-57.4129)"> + <title>Foglio.168</title> + <desc>ObjectFactory</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="74.7358" width="67.88" height="17.8178"/> + <rect x="0" y="65.827" width="67.8794" height="17.8178" class="st3"/> + <text x="4" y="77.14" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>ObjectFactory</text> </g> + <g id="shape169-33" v:mID="169" v:groupContext="shape" transform="translate(270.011,-41.5389)"> + <title>Foglio.169</title> + <rect x="0" y="66.6369" width="87.874" height="17.0079" class="st2"/> + </g> + <g id="shape170-35" v:mID="170" v:groupContext="shape" transform="translate(270.011,-40.729)"> + <title>Foglio.170</title> + <desc>createFoo(): Foo</desc> + <v:textBlock v:margins="rect(4,4,4,4)" v:tabSpace="42.5197"/> + <v:textRect cx="33.9397" cy="74.7358" width="67.88" height="17.8178"/> + <rect x="0" y="65.827" width="67.8794" height="17.8178" class="st3"/> + <text x="4" y="77.14" class="st4" v:langID="1040"><v:paragraph/><v:tabList/>createFoo(): Foo</text> </g> + </g> +</svg>
diff --git a/spec/src/main/asciidoc/license-efsl.adoc b/spec/src/main/asciidoc/license-efsl.adoc new file mode 100644 index 0000000..f03046e --- /dev/null +++ b/spec/src/main/asciidoc/license-efsl.adoc
@@ -0,0 +1,79 @@ +[subs="normal"] +.... +Specification: {doctitle} + +Version: {revnumber} + +ifeval::["{revremark}" != ""] +Status: {revremark} +endif::[] +ifeval::["{revremark}" == ""] +Status: Final Release +endif::[] + +Release: {revdate} +.... + +Copyright (c) 2019, 2022 Eclipse Foundation. + +=== Eclipse Foundation Specification License + +By using and/or copying this document, or the Eclipse Foundation +document from which this statement is linked, you (the licensee) agree +that you have read, understood, and will comply with the following +terms and conditions: + +Permission to copy, and distribute the contents of this document, or +the Eclipse Foundation document from which this statement is linked, in +any medium for any purpose and without fee or royalty is hereby +granted, provided that you include the following on ALL copies of the +document, or portions thereof, that you use: + +* link or URL to the original Eclipse Foundation document. +* All existing copyright notices, or if one does not exist, a notice + (hypertext is preferred, but a textual representation is permitted) + of the form: "Copyright (c) [$date-of-document] + Eclipse Foundation, Inc. <<url to this license>>" + +Inclusion of the full text of this NOTICE must be provided. We +request that authorship attribution be provided in any software, +documents, or other items or products that you create pursuant to the +implementation of the contents of this document, or any portion +thereof. + +No right to create modifications or derivatives of Eclipse Foundation +documents is granted pursuant to this license, except anyone may +prepare and distribute derivative works and portions of this document +in software that implements the specification, in supporting materials +accompanying such software, and in documentation of such software, +PROVIDED that all such works include the notice below. HOWEVER, the +publication of derivative works of this document for use as a technical +specification is expressly prohibited. + +The notice is: + +"Copyright (c) 2018 Eclipse Foundation. This software or +document includes material copied from or derived from [title and URI +of the Eclipse Foundation specification document]." + +==== Disclaimers + +THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT +HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, +NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE +SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS +WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR +OTHER RIGHTS. + +THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE +FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT +OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE +CONTENTS THEREOF. + +The name and trademarks of the copyright holders or the Eclipse +Foundation may NOT be used in advertising or publicity pertaining to +this document or its contents without specific, written prior +permission. Title to copyright in this document will at all times +remain with copyright holders. \ No newline at end of file
diff --git a/spec/src/main/asciidoc/scope.adoc b/spec/src/main/asciidoc/scope.adoc new file mode 100644 index 0000000..62cee9c --- /dev/null +++ b/spec/src/main/asciidoc/scope.adoc
@@ -0,0 +1,7 @@ +// +// Copyright (c) 2017, 2020 Contributors to the Eclipse Foundation +// +== Scope + +The Jakarta XML Binding provides an API and tools that automate the mapping +between XML documents and Java objects. \ No newline at end of file
diff --git a/spec/src/main/asciidoc/xml-binding-spec.adoc b/spec/src/main/asciidoc/xml-binding-spec.adoc new file mode 100644 index 0000000..77cbb7e --- /dev/null +++ b/spec/src/main/asciidoc/xml-binding-spec.adoc
@@ -0,0 +1,32 @@ +// +// Copyright (c) 2017, 2023 Contributors to the Eclipse Foundation +// + += Jakarta XML Binding +:authors: Jakarta XML Binding Team, https://projects.eclipse.org/projects/ee4j.jaxb +:email: https://dev.eclipse.org/mailman/listinfo/jaxb-dev +:version-label!: +:doctype: book +:license: Eclipse Foundation Specification License v1.0 +:source-highlighter: coderay +:toc: left +:toclevels: 4 +:sectnumlevels: 4 +:sectanchors: +ifdef::backend-pdf[] +:pagenums: +:numbered: +:title-logo-image: image:jakarta_ee_logo_schooner_color_stacked_default.png[pdfwidth=4.25in,align=right] +endif::[] + +// == License +:sectnums!: +include::license-efsl.adoc[] + +// == Scope +:sectnums!: +include::scope.adoc[] + +// == Jakarta XML Binding +:sectnums: +include::XMLBinding.adoc[]
diff --git a/spec/src/main/asciidoc/xml-binding.adoc b/spec/src/main/asciidoc/xml-binding.adoc new file mode 100644 index 0000000..62cee9c --- /dev/null +++ b/spec/src/main/asciidoc/xml-binding.adoc
@@ -0,0 +1,7 @@ +// +// Copyright (c) 2017, 2020 Contributors to the Eclipse Foundation +// +== Scope + +The Jakarta XML Binding provides an API and tools that automate the mapping +between XML documents and Java objects. \ No newline at end of file
diff --git a/spec/src/theme/jakartaee-theme.yml b/spec/src/theme/jakartaee-theme.yml new file mode 100644 index 0000000..6092a2f --- /dev/null +++ b/spec/src/theme/jakartaee-theme.yml
@@ -0,0 +1,299 @@ +# +# Following is the asciidoctor-pdf default theme [1], with small +# customizations, mostly for header and footer, marked "EE". +# +# [1] https://github.com/asciidoctor/asciidoctor-pdf/blob/master/data/themes/default-theme.yml +# +font: + catalog: + # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols + Noto Serif: + normal: notoserif-regular-subset.ttf + bold: notoserif-bold-subset.ttf + italic: notoserif-italic-subset.ttf + bold_italic: notoserif-bold_italic-subset.ttf + # M+ 1mn supports ASCII and the circled numbers used for conums + M+ 1mn: + normal: mplus1mn-regular-ascii-conums.ttf + bold: mplus1mn-bold-ascii.ttf + italic: mplus1mn-italic-ascii.ttf + bold_italic: mplus1mn-bold_italic-ascii.ttf + # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols + # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font + M+ 1p Fallback: + normal: mplus1p-regular-fallback.ttf + bold: mplus1p-regular-fallback.ttf + italic: mplus1p-regular-fallback.ttf + bold_italic: mplus1p-regular-fallback.ttf + fallbacks: + - M+ 1p Fallback +page: + background_color: ffffff + layout: portrait + margin: [0.5in, 0.67in, 0.67in, 0.67in] + # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress + margin_inner: 0.75in + margin_outer: 0.59in + #size: A4 # EE + size: Letter # EE +base: + align: justify + # color as hex string (leading # is optional) + font_color: 333333 + # color as RGB array + #font_color: [51, 51, 51] + # color as CMYK array (approximated) + #font_color: [0, 0, 0, 0.92] + #font_color: [0, 0, 0, 92%] + font_family: Noto Serif + # choose one of these font_size/line_height_length combinations + #font_size: 14 + #line_height_length: 20 + #font_size: 11.25 + #line_height_length: 18 + #font_size: 11.2 + #line_height_length: 16 + font_size: 10.5 + #line_height_length: 15 + # correct line height for Noto Serif metrics + line_height_length: 12 + #font_size: 11.25 + #line_height_length: 18 + line_height: $base_line_height_length / $base_font_size + font_size_large: round($base_font_size * 1.25) + font_size_small: round($base_font_size * 0.85) + font_size_min: $base_font_size * 0.75 + font_style: normal + border_color: eeeeee + border_radius: 4 + border_width: 0.5 +# FIXME vertical_rhythm is weird; we should think in terms of ems +#vertical_rhythm: $base_line_height_length * 2 / 3 +# correct line height for Noto Serif metrics (comes with built-in line height) +vertical_rhythm: $base_line_height_length +horizontal_rhythm: $base_line_height_length +# QUESTION should vertical_spacing be block_spacing instead? +vertical_spacing: $vertical_rhythm +link: + font_color: 428bca +# literal is currently used for inline monospaced in prose and table cells +literal: + font_color: b12146 + font_family: M+ 1mn +menu_caret_content: " <font size=\"1.15em\"><color rgb=\"b12146\">\u203a</color></font> " +heading: + align: left + #font_color: 181818 + font_color: $base_font_color + font_family: $base_font_family + font_style: bold + # h1 is used for part titles (book doctype) or the doctitle (article doctype) + #h1_font_size: floor($base_font_size * 2.6) # EE + h1_font_size: floor($base_font_size * 2.5) # EE, squeeze title onto one line + # h2 is used for chapter titles (book doctype only) + h2_font_size: floor($base_font_size * 2.15) + h3_font_size: round($base_font_size * 1.7) + h4_font_size: $base_font_size_large + h5_font_size: $base_font_size + h6_font_size: $base_font_size_small + #line_height: 1.4 + # correct line height for Noto Serif metrics (comes with built-in line height) + line_height: 1 + margin_top: $vertical_rhythm * 0.4 + margin_bottom: $vertical_rhythm * 0.9 +title_page: + align: right + logo: + top: 10% + title: + top: 55% + font_size: $heading_h1_font_size + font_color: 999999 + line_height: 0.9 + subtitle: + font_size: $heading_h3_font_size + font_style: bold_italic + line_height: 1 + authors: + margin_top: $base_font_size * 1.25 + font_size: $base_font_size_large + font_color: 181818 + revision: + margin_top: $base_font_size * 1.25 +block: + margin_top: 0 + margin_bottom: $vertical_rhythm +caption: + align: left + font_size: $base_font_size * 0.95 + font_style: italic + # FIXME perhaps set line_height instead of / in addition to margins? + margin_inside: $vertical_rhythm / 3 + #margin_inside: $vertical_rhythm / 4 + margin_outside: 0 +lead: + font_size: $base_font_size_large + line_height: 1.4 +abstract: + font_color: 5c6266 + font_size: $lead_font_size + line_height: $lead_line_height + font_style: italic + first_line_font_style: bold + title: + align: center + font_color: $heading_font_color + font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +admonition: + column_rule_color: $base_border_color + column_rule_width: $base_border_width + padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] + #icon: + # tip: + # name: fa-lightbulb-o + # stroke_color: 111111 + # size: 24 + label: + text_transform: uppercase + font_style: bold +blockquote: + font_color: $base_font_color + font_size: $base_font_size_large + border_color: $base_border_color + border_width: 5 + # FIXME disable negative padding bottom once margin collapsing is implemented + padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] + cite_font_size: $base_font_size_small + cite_font_color: 999999 +# code is used for source blocks (perhaps change to source or listing?) +code: + font_color: $base_font_color + font_family: $literal_font_family + font_size: ceil($base_font_size) + padding: $code_font_size + line_height: 1.25 + # line_gap is an experimental property to control how a background color is applied to an inline block element + line_gap: 3.8 + background_color: f5f5f5 + border_color: cccccc + border_radius: $base_border_radius + border_width: 0.75 +conum: + font_family: M+ 1mn + font_color: $literal_font_color + font_size: $base_font_size + line_height: 4 / 3 +example: + border_color: $base_border_color + border_radius: $base_border_radius + border_width: 0.75 + background_color: ffffff + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] +image: + align: left +prose: + margin_top: $block_margin_top + margin_bottom: $block_margin_bottom +sidebar: + background_color: eeeeee + border_color: e1e1e1 + border_radius: $base_border_radius + border_width: $base_border_width + # FIXME reenable padding bottom once margin collapsing is implemented + padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] + title: + align: center + font_color: $heading_font_color + font_family: $heading_font_family + font_size: $heading_h4_font_size + font_style: $heading_font_style +thematic_break: + border_color: $base_border_color + border_style: solid + border_width: $base_border_width + margin_top: $vertical_rhythm * 0.5 + margin_bottom: $vertical_rhythm * 1.5 +description_list: + term_font_style: bold + term_spacing: $vertical_rhythm / 4 + description_indent: $horizontal_rhythm * 1.25 +outline_list: + indent: $horizontal_rhythm * 1.5 + #marker_font_color: 404040 + # NOTE outline_list_item_spacing applies to list items that do not have complex content + item_spacing: $vertical_rhythm / 2 +table: + background_color: $page_background_color + #head_background_color: <hex value> + #head_font_color: $base_font_color + head_font_style: bold + #body_background_color: <hex value> + body_stripe_background_color: f9f9f9 + foot_background_color: f0f0f0 + border_color: dddddd + border_width: $base_border_width + cell_padding: 3 +toc: + indent: $horizontal_rhythm + line_height: 1.4 + dot_leader: + #content: ". " + font_color: a9a9a9 + #levels: 2 3 +# NOTE in addition to footer, header is also supported +footer: + font_size: $base_font_size_small + # NOTE if background_color is set, background and border will span width of page + #border_color: dddddd # EE + #border_width: 0.25 # EE + height: $base_line_height_length * 2.5 + line_height: 1 + padding: [$base_line_height_length / 2, 1, 0, 1] + vertical_align: top + #image_vertical_align: <alignment> or <number> + # additional attributes for content: + # * {page-count} + # * {page-number} + # * {document-title} + # * {document-subtitle} + # * {chapter-title} + # * {section-title} + # * {section-or-chapter-title} + recto: + #columns: "<50% =0% >50%" + right: + #content: '{page-number}' # EE + #content: '{section-or-chapter-title} | {page-number}' + #content: '{document-title} | {page-number}' + content: '{document-title}{nbsp}{nbsp}{nbsp} *{page-number}*' # EE + #center: + # content: '{page-number}' + left: # EE + content: '{status}' # EE + verso: + #columns: $footer_recto_columns + left: + #content: $footer_recto_right_content # EE + #content: '{page-number} | {chapter-title}' + content: '*{page-number}* {nbsp}{nbsp}{nbsp}{document-title}' # EE + #center: + # content: '{page-number}' + right: # EE + content: '{status}' # EE +header: # EE + font_size: $base_font_size_small # EE + border_color: dddddd # EE + border_width: 0.25 # EE + height: $base_line_height_length * 2.5 # EE + line_height: 1 # EE + padding: [$base_line_height_length / 2, 1, 0, 1] # EE + vertical_align: top # EE + recto: # EE + right: # EE + content: '{section-or-chapter-title}' # EE + verso: # EE + left: # EE + content: '{section-or-chapter-title}' # EE
diff --git a/tools/rewrite_poms_git.sh b/tools/rewrite_poms_git.sh new file mode 100755 index 0000000..315054b --- /dev/null +++ b/tools/rewrite_poms_git.sh
@@ -0,0 +1,213 @@ +#!/bin/bash +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# +# This program and the accompanying materials are made available under the +# terms of the Eclipse Distribution License v. 1.0, which is available at +# http://www.eclipse.org/org/documents/edl-v10.php. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# if option -n ... do not commit +COMMIT=Y +RELEASE=false + +while getopts ":nv:r" opt; do + case $opt in + n) + COMMIT=N + ;; + v) + CUSTOM_VERSION=${OPTARG} + echo "Using custom version: ${CUSTOM_VERSION}" + ;; + r) + RELEASE=true + echo "Using release mode, to append buildnumber remove -r flag." + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + esac +done +echo "Script will commit changes: [$COMMIT] (pass option -n not to commit)" + +CURRENT_VERSION=`cat pom.xml | grep '<version' -m 1 | cut -d ">" -f 2 | cut -d "<" -f 1 | cut -d "-" -f 1` +echo "Current version: ${CURRENT_VERSION}" + +SCRIPT_DIR=$(cd $(dirname $0); pwd -P) + +cd $SCRIPT_DIR/.. || { + echo >&2 "Cannot change to top of GIT working directory" + exit 1 +} + +command -v git > /dev/null 2>&1 || { + echo >&2 "Cannot locate git executable" + exit 1 +} + +GIT=$(command -v git 2>&1) +#GIT=$(command -v echo 2>&1) +LAST_GIT_COMMIT=$(${GIT} rev-parse --short HEAD) || exit 1 + +DATESTAMP=`date +%y%m%d.%H%M` +BUILD_NUMBER=b${DATESTAMP} +DEVELOPER_VERSION=${CURRENT_VERSION}-SNAPSHOT +RELEASE_QUALIFIER=${BUILD_NUMBER} + +if [ -z "${CUSTOM_VERSION}" ]; then + echo "No version specified, reading release version from pom file" + RELEASE_VERSION=${CURRENT_VERSION} +else + RELEASE_VERSION=${CUSTOM_VERSION} +fi; + +if [ "${RELEASE}" = true ]; then + echo "Release version: ${RELEASE_VERSION}" +else + RELEASE_VERSION="${RELEASE_VERSION}-${RELEASE_QUALIFIER}" + echo "Pre-release version: ${RELEASE_VERSION}" +fi; + + + +RELEASE_TAG=${RELEASE_VERSION} + +cleanup() +{ + ${GIT} clean -d -f -x + exit 1 +} + +edit_poms() +{ + TMPFILE=`mktemp $TMPDIR/${RELEASE_VERSION}.XXXXXXXX` || cleanup + find \ + $SCRIPT_DIR/../ \ + -name pom.xml \ + >> $TMPFILE + + echo "Updating pom files to have release versions ..." + while read line + do + echo -n "Editing $line..." + perl -i -pe "s|<version>${DEVELOPER_VERSION}|<version>${RELEASE_VERSION}|g" $line + if [ $? -ne 0 ]; then + echo "FAILED." + echo "Replace versions failed for $line: $!" + cleanup + fi + echo "DONE." + + echo -n "Adding $line to git index..." + ${GIT} add $line + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git add failed for $line: $!" + cleanup + fi + echo "DONE." + done < "$TMPFILE" +} + +function commit_changes() { + echo -n "Committing rewritten POMs to git..." + ${GIT} commit --verbose -m "Preparing for release ${RELEASE_VERSION}" + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git commit failed: $!" + cleanup + fi + echo "DONE." + + echo -n "Preparing tag ${RELEASE_TAG}..." + ${GIT} tag -m "Tagging for Release ${RELEASE_VERSION}" ${RELEASE_TAG} + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git tag failed: $!" + cleanup + fi + echo "DONE." + + echo -n "Reverting to developer versions..." + ${GIT} revert --no-edit --no-commit HEAD + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git revert failed: $!" + cleanup + fi + echo "DONE." + + echo -n "Committing rewritten POMs to git..." + ${GIT} commit --verbose -m "Preparing for development ${DEVELOPER_VERSION}" + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git commit failed: $!" + cleanup + fi + echo "DONE." +} + +push_changes() +{ + + echo -n "Pushing changes..." + ${GIT} push + if [ $? -ne 0 ]; then + ${GIT} pull --rebase + ${GIT} push + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git push failed: $!" + cleanup + fi + fi + echo "DONE." + + echo -n "Pushing tag..." + ${GIT} push origin ${RELEASE_TAG} + if [ $? -ne 0 ]; then + ${GIT} pull --rebase + ${GIT} push + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git push failed: $!" + cleanup + fi + fi + echo "DONE." + +} + +checkout_tag() +{ + echo -n "Checking out tag ${RELEASE_TAG}..." + ${GIT} checkout ${RELEASE_TAG} + if [ $? -ne 0 ]; then + echo "FAILED." + echo "git checkout failed: $!" + cleanup + fi + echo "DONE." +} + +############# + +echo "Rewriting Web Services POM Files" +echo "DEVELOPER_VERSION = ${DEVELOPER_VERSION}" +echo "RELEASE_VERSION = ${RELEASE_VERSION}" + +${GIT} clean -d -f -x + +edit_poms + +if [ "$COMMIT" = "Y" ]; then + commit_changes + push_changes + checkout_tag +fi + +exit 0