This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch dupother in repository https://gitbox.apache.org/repos/asf/camel.git
commit 49d42e6a4cee16a62d97436f655151690568a655 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Jan 20 14:09:35 2025 +0100 CAMEL-21632: camel-spring-xml - Fix XSD to not include duplicate ##other entry that is caused by the parser support for importing legacy spring or blueprint xml files for migration and tooling purposes. Added XSD validation test to validate the generated XSD onwards. Thanks to Tobias Kleinschmidt for validation example --- components/camel-spring-xml/pom.xml | 6 +++ .../camel/spring/CamelSpringXSDValidateTest.java | 41 ++++++++++++++++++++ .../spi/annotations/ExternalSchemaElement.java | 23 ++++++++--- .../apache/camel/model/app/BeansDefinition.java | 45 +++++++--------------- .../java/org/apache/camel/xml/in/ModelParser.java | 12 +++--- .../java/org/apache/camel/xml/out/ModelWriter.java | 5 +-- .../org/apache/camel/xml/in/ModelParserTest.java | 19 ++++----- .../org/apache/camel/yaml/out/ModelWriter.java | 5 +-- .../camel/dsl/xml/io/XmlRoutesBuilderLoader.java | 30 +++++++-------- .../org/apache/camel/dsl/xml/io/springBeans.xml | 29 +++++++++++--- .../src/main/resources/velocity/model-parser.vm | 8 ++++ .../spi/annotations/ExternalSchemaElement.java | 23 ++++++++--- 12 files changed, 159 insertions(+), 87 deletions(-) diff --git a/components/camel-spring-xml/pom.xml b/components/camel-spring-xml/pom.xml index 4a0cb38d130..d3df2783140 100644 --- a/components/camel-spring-xml/pom.xml +++ b/components/camel-spring-xml/pom.xml @@ -84,6 +84,12 @@ <version>${spring-version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework.ws</groupId> + <artifactId>spring-xml</artifactId> + <version>${spring-ws-version}</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java new file mode 100644 index 00000000000..f3697ea4522 --- /dev/null +++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/CamelSpringXSDValidateTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.spring; + +import org.xml.sax.SAXParseException; + +import org.apache.camel.util.xml.BytesSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.xml.validation.XmlValidator; +import org.springframework.xml.validation.XmlValidatorFactory; + +public class CamelSpringXSDValidateTest { + + @Test + public void testValidateXSD() throws Exception { + Resource r = new ClassPathResource("camel-spring.xsd"); + Resource r2 = new ClassPathResource("org/springframework/beans/factory/xml/spring-beans.xsd"); + XmlValidator val = XmlValidatorFactory.createValidator(new Resource[] { r, r2 }, XmlValidatorFactory.SCHEMA_W3C_XML); + + Resource r3 = new ClassPathResource("org/apache/camel/spring/processor/choice.xml"); + SAXParseException[] err = val.validate(new BytesSource(r3.getContentAsByteArray())); + Assertions.assertEquals(0, err.length); + } +} diff --git a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java index da87308e0e9..5b77eb68d6c 100644 --- a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java +++ b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java @@ -33,25 +33,36 @@ public @interface ExternalSchemaElement { /** * Names of external XML element we expect - * - * @return */ String[] names() default {}; + /** + * Names of external XML element we expect + */ + String[] names2() default {}; + /** * XSD namespace of XML elements expected - * - * @return */ String namespace() default ""; + /** + * XSD namespace of XML elements expected + */ + String namespace2() default ""; + /** * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the actual objects used are of * {@link org.w3c.dom.Element} class. These elements should be part of wrapping {@link org.w3c.dom.Document} and * this parameter allows to specify this root element name (in {@link #namespace()}). - * - * @return */ String documentElement(); + /** + * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the actual objects used are of + * {@link org.w3c.dom.Element} class. These elements should be part of wrapping {@link org.w3c.dom.Document} and + * this parameter allows to specify this root element name (in {@link #namespace2()}). + */ + String documentElement2(); + } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java index 72d6faae36b..40f0522dbfe 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/app/BeansDefinition.java @@ -52,8 +52,7 @@ import org.apache.camel.spi.annotations.ExternalSchemaElement; @XmlType(propOrder = { "componentScanning", "beans", - "springBeans", - "blueprintBeans", + "springOrBlueprintBeans", "dataFormats", "restConfigurations", "rests", @@ -72,26 +71,19 @@ public class BeansDefinition { // this is a place for <bean> element definition, without conflicting with <bean> elements referring // to "bean processors" - @XmlElement(name = "bean") private List<BeanFactoryDefinition> beans = new ArrayList<>(); - // this is the only way I found to generate usable Schema without imports, while allowing elements - // from different namespaces - @ExternalSchemaElement(names = { "beans", "bean", "alias" }, + // support for legacy spring <beans> and blueprint <bean> files to be parsed and loaded + // for migration and tooling effort (need to be in a single @XmlAnyElement as otherwise + // this causes camel-spring-xml to generate an invalid XSD + @ExternalSchemaElement(names = { "beans", "bean", "alias" }, names2 = "bean", namespace = "http://www.springframework.org/schema/beans", - documentElement = "beans") + namespace2 = "http://www.osgi.org/xmlns/blueprint/v1.0.0", + documentElement = "beans", + documentElement2 = "blueprint") @XmlAnyElement - private List<Element> springBeans = new ArrayList<>(); - - // Blueprint XML is deprecated, but we need those so that Camel JBang can - // load the routes and transform them - - @ExternalSchemaElement(names = { "bean" }, - namespace = "http://www.osgi.org/xmlns/blueprint/v1.0.0", - documentElement = "blueprint") - @XmlAnyElement - private List<Element> blueprintBeans = new ArrayList<>(); + private List<Element> springOrBlueprintBeans = new ArrayList<>(); // the order comes from <camelContext> (org.apache.camel.spring.xml.CamelContextFactoryBean) // to make things less confusing, as it's not easy to simply tell JAXB to use <xsd:choice maxOccurs="unbounded"> @@ -139,26 +131,15 @@ public class BeansDefinition { this.beans = beans; } - public List<Element> getSpringBeans() { - return springBeans; + public List<Element> getSpringOrBlueprintBeans() { + return springOrBlueprintBeans; } /** * Spring XML beans */ - public void setSpringBeans(List<Element> springBeans) { - this.springBeans = springBeans; - } - - public List<Element> getBlueprintBeans() { - return blueprintBeans; - } - - /** - * Blueprint XML beans - */ - public void setBlueprintBeans(List<Element> blueprintBeans) { - this.blueprintBeans = blueprintBeans; + public void setSpringOrBlueprintBeans(List<Element> springOrBlueprintBeans) { + this.springOrBlueprintBeans = springOrBlueprintBeans; } public List<RestConfigurationDefinition> getRestConfigurations() { diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index 6b289389e57..46fa4335bdd 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -1368,18 +1368,18 @@ public class ModelParser extends BaseParser { } protected <T extends BeansDefinition> ElementHandler<T> beansDefinitionElementHandler() { return (def, key) -> { - if ("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(parser.getNamespace())) { - Element el = doParseDOMElement("blueprint", "http://www.osgi.org/xmlns/blueprint/v1.0.0", def.getBlueprintBeans()); + if ("http://www.springframework.org/schema/beans".equals(parser.getNamespace())) { + Element el = doParseDOMElement("beans", "http://www.springframework.org/schema/beans", def.getSpringOrBlueprintBeans()); if (el != null) { - doAddElement(el, def.getBlueprintBeans(), def::setBlueprintBeans); + doAddElement(el, def.getSpringOrBlueprintBeans(), def::setSpringOrBlueprintBeans); return true; } return false; } - if ("http://www.springframework.org/schema/beans".equals(parser.getNamespace())) { - Element el = doParseDOMElement("beans", "http://www.springframework.org/schema/beans", def.getSpringBeans()); + if ("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(parser.getNamespace())) { + Element el = doParseDOMElement("blueprint", "http://www.osgi.org/xmlns/blueprint/v1.0.0", def.getSpringOrBlueprintBeans()); if (el != null) { - doAddElement(el, def.getSpringBeans(), def::setSpringBeans); + doAddElement(el, def.getSpringOrBlueprintBeans(), def::setSpringOrBlueprintBeans); return true; } return false; diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 931fc47b8b3..e185a32151c 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -2038,11 +2038,10 @@ public class ModelWriter extends BaseWriter { } protected void doWriteBeansDefinitionElements(BeansDefinition def) throws IOException { doWriteList(null, "route", def.getRoutes(), this::doWriteRouteDefinition); - domElements(def.getSpringBeans()); + domElements(def.getSpringOrBlueprintBeans()); doWriteList("dataFormats", "dataFormat", def.getDataFormats(), this::doWriteDataFormatDefinition); - domElements(def.getBlueprintBeans()); - doWriteList(null, "bean", def.getBeans(), this::doWriteBeanFactoryDefinition); doWriteList(null, "component-scan", def.getComponentScanning(), this::doWriteComponentScanDefinition); + doWriteList(null, "bean", def.getBeans(), this::doWriteBeanFactoryDefinition); doWriteList(null, "restConfiguration", def.getRestConfigurations(), this::doWriteRestConfigurationDefinition); doWriteList(null, "rest", def.getRests(), this::doWriteRestDefinition); doWriteList(null, "routeConfiguration", def.getRouteConfigurations(), this::doWriteRouteConfigurationDefinition); diff --git a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java index cda187e1fb8..c311c5b2ade 100644 --- a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java +++ b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java @@ -246,7 +246,7 @@ public class ModelParserTest { BeansDefinition beans = parser.parseBeansDefinition().orElse(null); assertNotNull(beans); assertTrue(beans.getBeans().isEmpty()); - assertTrue(beans.getSpringBeans().isEmpty()); + assertTrue(beans.getSpringOrBlueprintBeans().isEmpty()); } @Test @@ -257,7 +257,7 @@ public class ModelParserTest { BeansDefinition beans = parser.parseBeansDefinition().orElse(null); assertNotNull(beans); assertEquals(2, beans.getBeans().size()); - assertTrue(beans.getSpringBeans().isEmpty()); + assertTrue(beans.getSpringOrBlueprintBeans().isEmpty()); BeanFactoryDefinition b1 = beans.getBeans().get(0); BeanFactoryDefinition b2 = beans.getBeans().get(1); @@ -287,7 +287,7 @@ public class ModelParserTest { BeansDefinition beans = parser.parseBeansDefinition().orElse(null); assertNotNull(beans); assertEquals(2, beans.getBeans().size()); - assertTrue(beans.getSpringBeans().isEmpty()); + assertTrue(beans.getSpringOrBlueprintBeans().isEmpty()); BeanFactoryDefinition b1 = beans.getBeans().get(0); BeanFactoryDefinition b2 = beans.getBeans().get(1); @@ -314,7 +314,7 @@ public class ModelParserTest { BeansDefinition beans = parser.parseBeansDefinition().orElse(null); assertNotNull(beans); assertEquals(2, beans.getBeans().size()); - assertTrue(beans.getSpringBeans().isEmpty()); + assertTrue(beans.getSpringOrBlueprintBeans().isEmpty()); BeanFactoryDefinition b1 = beans.getBeans().get(0); BeanFactoryDefinition b2 = beans.getBeans().get(1); @@ -343,16 +343,17 @@ public class ModelParserTest { BeansDefinition beans = parser.parseBeansDefinition().orElse(null); assertNotNull(beans); assertTrue(beans.getBeans().isEmpty()); - assertEquals(2, beans.getSpringBeans().size()); - Document dom = beans.getSpringBeans().get(0).getOwnerDocument(); + assertEquals(2, beans.getSpringOrBlueprintBeans().size()); + Document dom = beans.getSpringOrBlueprintBeans().get(0).getOwnerDocument(); StringWriter sw = new StringWriter(); TransformerFactory.newInstance().newTransformer().transform(new DOMSource(dom), new StreamResult(sw)); String document = sw.toString(); assertTrue(document.contains("class=\"java.lang.String\"")); - assertSame(beans.getSpringBeans().get(0).getOwnerDocument(), beans.getSpringBeans().get(1).getOwnerDocument()); - assertEquals("s1", beans.getSpringBeans().get(0).getAttribute("id")); - assertEquals("s2", beans.getSpringBeans().get(1).getAttribute("id")); + assertSame(beans.getSpringOrBlueprintBeans().get(0).getOwnerDocument(), + beans.getSpringOrBlueprintBeans().get(1).getOwnerDocument()); + assertEquals("s1", beans.getSpringOrBlueprintBeans().get(0).getAttribute("id")); + assertEquals("s2", beans.getSpringOrBlueprintBeans().get(1).getAttribute("id")); assertEquals(1, beans.getComponentScanning().size()); assertEquals("com.example", beans.getComponentScanning().get(0).getBasePackage()); diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java index a4aa07d8b4e..d9d911932fa 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java @@ -2038,11 +2038,10 @@ public class ModelWriter extends BaseWriter { } protected void doWriteBeansDefinitionElements(BeansDefinition def) throws IOException { doWriteList(null, "route", def.getRoutes(), this::doWriteRouteDefinition); - domElements(def.getSpringBeans()); + domElements(def.getSpringOrBlueprintBeans()); doWriteList("dataFormats", "dataFormat", def.getDataFormats(), this::doWriteDataFormatDefinition); - domElements(def.getBlueprintBeans()); - doWriteList(null, "bean", def.getBeans(), this::doWriteBeanFactoryDefinition); doWriteList(null, "component-scan", def.getComponentScanning(), this::doWriteComponentScanDefinition); + doWriteList(null, "bean", def.getBeans(), this::doWriteBeanFactoryDefinition); doWriteList(null, "restConfiguration", def.getRestConfigurations(), this::doWriteRestConfigurationDefinition); doWriteList(null, "rest", def.getRests(), this::doWriteRestDefinition); doWriteList(null, "routeConfiguration", def.getRouteConfigurations(), this::doWriteRouteConfigurationDefinition); diff --git a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java index 03b75a7b7c3..0e01cb758d0 100644 --- a/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java +++ b/dsl/camel-xml-io-dsl/src/main/java/org/apache/camel/dsl/xml/io/XmlRoutesBuilderLoader.java @@ -322,23 +322,19 @@ public class XmlRoutesBuilderLoader extends RouteBuilderLoaderSupport { // <s:bean>, <s:beans> and <s:alias> elements - all the elements in single BeansDefinition have // one parent org.w3c.dom.Document - and this is what we collect from each resource - if (!app.getSpringBeans().isEmpty()) { - Document doc = app.getSpringBeans().get(0).getOwnerDocument(); - // bind as Document, to be picked up later - bean id allows nice sorting - // (can also be single ID - documents will get collected in LinkedHashMap, so we'll be fine) - String id = String.format("camel-xml-io-dsl-spring-xml:%05d:%s", counter.incrementAndGet(), resource.getLocation()); - getCamelContext().getRegistry().bind(id, doc); - } - - // <s:bean> elements - all the elements in single BeansDefinition have - // one parent org.w3c.dom.Document - and this is what we collect from each resource - if (!app.getBlueprintBeans().isEmpty()) { - Document doc = app.getBlueprintBeans().get(0).getOwnerDocument(); - // bind as Document, to be picked up later - bean id allows nice sorting - // (can also be single ID - documents will get collected in LinkedHashMap, so we'll be fine) - String id = String.format("camel-xml-io-dsl-blueprint-xml:%05d:%s", counter.incrementAndGet(), - resource.getLocation()); - getCamelContext().getRegistry().bind(id, doc); + if (!app.getSpringOrBlueprintBeans().isEmpty()) { + Document doc = app.getSpringOrBlueprintBeans().get(0).getOwnerDocument(); + String ns = doc.getDocumentElement().getNamespaceURI(); + String id = null; + if ("http://www.springframework.org/schema/beans".equals(ns)) { + id = String.format("camel-xml-io-dsl-spring-xml:%05d:%s", counter.incrementAndGet(), resource.getLocation()); + } else if ("http://www.osgi.org/xmlns/blueprint/v1.0.0".equals(ns)) { + id = String.format("camel-xml-io-dsl-blueprint-xml:%05d:%s", counter.incrementAndGet(), + resource.getLocation()); + } + if (id != null) { + getCamelContext().getRegistry().bind(id, doc); + } } } diff --git a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml index f1ba047e17c..3c0639abc82 100644 --- a/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml +++ b/dsl/camel-xml-io-dsl/src/test/resources/org/apache/camel/dsl/xml/io/springBeans.xml @@ -23,11 +23,30 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> - <camelContext id="SampleCamel" xmlns="http://camel.apache.org/schema/spring"> - - <route id="hello"> - <from uri="direct:hello"/> - <to uri="mock:result"/> + <!-- spring beans --> + <bean id="orderService" class="com.foo.OrderService"> + <argument index="0" value="true"/> + <argument index="1" ref="office"/> + </bean> + <!-- uses property placeholder ${xxx} syntax --> + <bean id="office" class="com.foo.Address"> + <property name="zip" value="${zipCode}"/> + <property name="street" value="${streetName}"/> + </bean> + + <camelContext id="SpringCamel" xmlns="http://camel.apache.org/schema/spring"> + + <!-- anything inside here such as this should be skipped during parsing --> + <propertyPlaceholder id="placeholder" location="classpath:sql.properties"/> + + <!-- we only parse (currently) embedded routes etc. --> + <route> + <from uri="timer:xml?period={{time:1000}}"/> + <setBody> + <simple>${random(1000)}</simple> + </setBody> + <bean ref="orderService"/> + <log message="${body}"/> </route> </camelContext> diff --git a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm index 381e05b05b2..4a14c770268 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm +++ b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-parser.vm @@ -312,6 +312,14 @@ ${indent} doAddElement(el, def.${member.getter}(), def::${mem ${indent} return true; ${indent} } ${indent} return false; +${indent} } +${indent} if ("${external.namespace2()}".equals(parser.getNamespace())) { +${indent} Element el = doParseDOMElement("${external.documentElement2()}", "${external.namespace2()}", def.${member.getter}()); +${indent} if (el != null) { +${indent} doAddElement(el, def.${member.getter}(), def::${member.setter}); +${indent} return true; +${indent} } +${indent} return false; ${indent} } #end #if( $others.empty ) diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java index da87308e0e9..5b77eb68d6c 100644 --- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/ExternalSchemaElement.java @@ -33,25 +33,36 @@ public @interface ExternalSchemaElement { /** * Names of external XML element we expect - * - * @return */ String[] names() default {}; + /** + * Names of external XML element we expect + */ + String[] names2() default {}; + /** * XSD namespace of XML elements expected - * - * @return */ String namespace() default ""; + /** + * XSD namespace of XML elements expected + */ + String namespace2() default ""; + /** * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the actual objects used are of * {@link org.w3c.dom.Element} class. These elements should be part of wrapping {@link org.w3c.dom.Document} and * this parameter allows to specify this root element name (in {@link #namespace()}). - * - * @return */ String documentElement(); + /** + * In JAXB, when an element is annotated with {@code @XmlAnyElement}, the actual objects used are of + * {@link org.w3c.dom.Element} class. These elements should be part of wrapping {@link org.w3c.dom.Document} and + * this parameter allows to specify this root element name (in {@link #namespace2()}). + */ + String documentElement2(); + }
