Update appendix D Signed-off-by: Lukas Jungmann <lukas.jungmann@oracle.com>
diff --git a/spec/src/main/asciidoc/XMLBinding.adoc b/spec/src/main/asciidoc/XMLBinding.adoc index baae33a..23ebed7 100644 --- a/spec/src/main/asciidoc/XMLBinding.adoc +++ b/spec/src/main/asciidoc/XMLBinding.adoc
@@ -21,19 +21,3 @@ include::appG-deprecated.adoc[] include::appH-binary_data.adoc[] include::appI-changelog.adoc[] - -''''' - -[.footnoteNumber]# 29.# [[a5380]]Exception case: -Underscore is not considered a punctuation mark for schema customization -_<jaxb:globalBindings underscoreHandling="asCharInWord"/>_ specified in -link:jaxb.html#a1613[See Underscore Handling]". For this -customization, underscore is considered a special letter that never -results in a word break as defined in link:jaxb.html#a4681[See -XML Word Breaks] and it is definitely not considered an uncased letter. -See example bindings in link:jaxb.html#a4755[See XML Names and -derived Java Class, Method, and Constant Names when <jaxb:globalBindings -underscoreHandling=”asCharInWord”>]. - -[.footnoteNumber]# 30.# [[a5381]]Sample URN -"urn:hl7-org:v3" \{"h17-org", "v3") transforms to \{"h17.org", "v3"}.
diff --git a/spec/src/main/asciidoc/appD-binding_xml.adoc b/spec/src/main/asciidoc/appD-binding_xml.adoc index 423abd1..ae9c22e 100644 --- a/spec/src/main/asciidoc/appD-binding_xml.adoc +++ b/spec/src/main/asciidoc/appD-binding_xml.adoc
@@ -3,7 +3,7 @@ // [appendix] -== [[a4649]]Binding XML Names to Java Identifiers +== Binding XML Names to Java Identifiers === Overview @@ -13,10 +13,9 @@ * Model group to Java identifier * Namespace URI to Java package name -=== [[a4656]]The Name to Identifier Mapping Algorithm +=== The Name to Identifier Mapping Algorithm -Java identifiers typically follow three -simple, well-known conventions: +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, @@ -42,34 +41,41 @@ 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 +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, +* 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 exceptionlink:#a5380[29] +* \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 +link:jaxb.html#a1613[See Underscore Handling]". For this +customization, underscore is considered a special letter that never +results in a word break as defined in link:jaxb.html#a4681[See +XML Word Breaks] and it is definitely not considered an uncased letter. +See example bindings in link:jaxb.html#a4755[See XML Names and +derived Java Class, Method, and Constant Names when <jaxb:globalBindings +underscoreHandling=”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 +`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 +`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 +`Character.isJavaIdentifierPart` method returns `true`. This category includes numeric letters, combining marks, non-spacing marks, and ignorable control characters. @@ -77,112 +83,42 @@ 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 _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 +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: -=== [[a4681]]XML Word Breaks +.XML Word Breaks +[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` | +|=== -Prefix - -Separator - -Suffix - -Example - -{empty}[^punct] - -punct+1 - -{empty}[^punct] - -foo|--|bar - -digit - - - -{empty}[^ _digit_ ] - -foo|22|bar - -{empty}[^digit] - - - -digit - -foo|22 - -lower - - - -{empty}[^lower] - -foo|Bar - -upper - - - -upper lower - -FOO|Bar - -letter - - - -{empty}[^letter] - -Foo|\u2160 - -{empty}[^letter] - - - -letter - -\u2160|Foo - -uncased - - - -{empty}[^uncased] - - - -{empty}[^uncased] - - - -uncased - - - -(The character _\u2160_ is ROMAN NUMERAL ONE, -a numeric letter.) +(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 case1). +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. @@ -192,8 +128,8 @@ * 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. +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. @@ -206,71 +142,29 @@ To improve user experience with default binding, the automated resolution of frequent naming collision is specified in link:jaxb.html#a4770[See Standardized Name -Collision Resolution]“. +Collision Resolution]. -=== Example +*_Example_* -=== [[a4734]]XML Names and derived Java Class, Method, and Constant Names - -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 - -=== [[a4755]]XML Names and derived Java Class, Method, and Constant Names when <jaxb:globalBindings underscoreHandling=”asCharInWord”> - -[width="100%",cols="25%,25%,25%,25%",options="header",] +.XML Names and derived Java Class, Method, and Constant Names +[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 +| 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 |=== -=== [[a4767]]Collisions and conflicts +.XML Names and derived Java Class, Method, and Constant Names when <jaxb:globalBindings underscoreHandling=”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 @@ -286,25 +180,49 @@ one of the two XML names to an alternative Java identifier. A class name must not conflict with the -generated JAXB class, _ObjectFactory_ , link:jaxb.html#a482[See +generated JAXB class, `ObjectFactory`, link:jaxb.html#a482[See 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 +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. -=== [[a4770]]Standardized Name Collision Resolution +===== 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()_ , +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. -=== [[a4773]]Deriving a legal Java identifier from an enum facet value +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 @@ -312,19 +230,17 @@ 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, +* 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_ +* There is no derived Java constant identifier when any of the following occur: +** `javaId.length() == 0` +** `java.lang.Character.isJavaIdentifierStart(javaId.get(0)) == false` -=== [[a4780]]Deriving an identifier for a model group +=== 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 @@ -336,34 +252,34 @@ 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 +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_ _”_ . +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: - +*_Example:_* + Given XML Schema fragment: -<xs:choice> + -<xs:sequence> + -<xs:element ref="A"/> + -<xs:any processContents="strict"/> + -</xs:sequence> + -<xs:element ref="C"/> - +[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_ . +The generated Java identifier would be `AAndAnyOrC`. -=== [[a4788]]Generating a Java package name +=== Generating a Java package name This section describes how to generate a package name to hold the derived Java representation. The motivation for @@ -376,7 +292,7 @@ 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 +==== 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 @@ -385,87 +301,105 @@ 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. +`http://www.acme.com/go/espeak.xsd`, is used to illustrate each step. -. Remove the scheme and _":"_ part from the +. 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_ ” and “ _urn_ ”. - - _//www.acme.com/go/espeak.xsd_ - -. Remove the trailing file type, one of _.??_ -or _.???_ or _.html_ . - - _//www.acme.com/go/espeak_ - +schemes `"http"` 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 +strings using `'/'` and `':'` as separators. Treat consecutive separators as a single separator. - - _\{"www.acme.com", "go", "espeak" }_ - ++ +[source] +---- +{"www.acme.com", "go", "espeak"} +---- . For each string in the list produced by previous step, unescape each escape sequence octet. - - _\{"www.acme.com", "go", "espeak" }_ - -. If the scheme is a “urn”, replace all -dashes, “-”, occurring in the first component with -“.”.link:#a5381[30] ++ +[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 +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. - - _\{“com”, “acme”, “go”, “espeak”}_ - -. For each string in the list, convert each -string to be all lower case. - - _\{"com”, “acme”, "go", "espeak" }_ - ++ +[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, +.. 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 +.. If any of the resulting package name components are keywords then append underscore to them. -. If any of the resulting package name +.. 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. - _\{"com”, “acme”, "go", "espeak" }_ ++ +[source] +---- +{"com", "acme", "go", "espeak"} +---- . Concatenate the resultant list of strings -using _’.’_ as a separating character to produce a package name. - - _Final package name: "com.acme.go.espeak"._ +using `"."` as a separating character to produce a package name. ++ +[source] +---- +Final package name: "com.acme.go.espeak". +---- link:jaxb.html#a4767[See Collisions and conflicts], specifies what to do when the above algorithm results in an invalid Java package name. -=== [[a4816]]Conforming Java Identifier Algorithm +=== 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. -link:jaxb.html#a1608[See Customized Name Mapping]“discusses when +link:jaxb.html#a1608[See 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 link:jaxb.html#a4656[See The -Name to Identifier Mapping Algorithm]” with the following exception: +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.