JAXB Root Class Rename using binding.xml - java

I use the Dali plugin in Eclipse to generate Java classes using an xsd file, which essentially just invokes xjc on the schema file. I used the advice here to resolve naming conflicts by applying an XML binding file to the class generation. This worked well, but I tried to take it a step further by renaming the root element, and the result was that I lost the XmlRootElement annotation. I tried using annox to add the root element annotation back in, but I get this error: Unsupported binding namespace "http://annox.dev.java.net". Perhaps you meant "http://java.sun.com/xml/ns/jaxb/xjc"?
Here is my initial binding.xml file (without annox):
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<!-- Force all classes to be generated at the top level, this will potentially cause name conflicts -->
<jaxb:globalBindings localScoping="toplevel"/>
<jaxb:bindings schemaLocation="mySchema-1.0.0.xsd">
<!-- Rename the root element -->
<jaxb:bindings node="//xs:element[#name='MyRootClassNameIsReallyLong']/xs:complexType">
<jaxb:class name="ShorterName"/>
</jaxb:bindings>
<!-- Rename the Bar class to resolve a naming conflict -->
<jaxb:bindings node="//xs:element[#name='Foo']/xs:complexType/xs:sequence/xs:element[#name='Bar']/xs:complexType">
<jaxb:class name="FooBar"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
By the way, it's worth noting that the schema file came from a third party, so I have no interest in modifying it. Likewise, I'd rather not tamper with the generated Java files, so that's why I am interested in the binding xml approach.
Edit (9/11/2013) - Here is the binding XML with annox:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
xmlns:annox="http://annox.dev.java.net"
version="2.1">
<!-- Force all classes to be generated at the top level, this will potentially cause name conflicts -->
<jaxb:globalBindings localScoping="toplevel"/>
<jaxb:bindings schemaLocation="mySchema-1.0.0.xsd">
<!-- Rename the root element -->
<jaxb:bindings node="//xs:element[#name='MyRootClassNameIsReallyLong']/xs:complexType">
<jaxb:class name="ShorterName"/>
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="MyRootClassNameIsReallyLong" />
</annox:annotate>
</jaxb:bindings>
<!-- Rename the Bar class to resolve a naming conflict -->
<jaxb:bindings node="//xs:element[#name='Foo']/xs:complexType/xs:sequence/xs:element[#name='Bar']/xs:complexType">
<jaxb:class name="FooBar"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>

Annox is an XJC add on, so you in addition to declaring the namespace prefx (xmlns:annox="http://annox.dev.java.net), you also need to declare it as an extensionBindingPrefix.
Your openning tag should then look like this:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb
http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
jaxb:extensionBindingPrefix="annox"
version="2.1">

Related

JAXB different datatypes parsing per namespace

I have got the JAXB bindings config file like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<jaxb:globalBindings generateElementProperty="false">
<jaxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="com.utils.EmptyDateTimeAdapter.parseDateTime"
printMethod="com.utils.EmptyDateTimeAdapter.printDateTimeWithZone"/>
<xjc:serializable uid="-1"/>
</jaxb:globalBindings>
</jaxb:bindings>
In xml above I declared that every wsdl dateTime element will be parsed by these methods.
My question is:
How can I change this JAXB config file to specify multiple parse methods for element type per package name or per wsdl?
<jaxws:bindings wsdlLocation="SampleService.wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxws:bindings node="wsdl:definitions/wsdl:types/xs:schema[#targetNamespace='http://example.com/service/SampleService/']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:javaType name="java.util.Date" xmlType="xs:date"
parseMethod="org.apache.cxf.tools.common.DataTypeAdapter.parseDateTime"
printMethod="org.apache.cxf.tools.common.DataTypeAdapter.printDateTime"/>
</jxb:globalBindings>
</jaxws:bindings>
</jaxws:bindings>
references :
JBoss Community Archive (Read Only)
JAXB bindings and xs:date to java.util.Date
Custom Jax-b bindings for xs:date to JAVA 8 java.time.LocalDate using Adapter

Import JAXB binding snippet into other binding file

For a certain xsd file, I have created a corresponding binding file that does some actions. In my case, annotating ComplexTypes with annotations. Finding the type is done with an XPath expression. The following example demonstrates this:
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
version="2.1"
xmlns:annox="http://annox.dev.java.net" jaxb:extensionBindingPrefixes="annox">
<jaxb:bindings schemaLocation="FirstSchema.xsd" node="/xsd:schema">
<jaxb:bindings node="//xsd:complexType//xsd:element[contains(#type, 'SomeType')]" required="false">
<annox:annotate target="field">#com.example.Type(type = "SomeType")</annox:annotate>
</jaxb:bindings>
//About 100 lines of bindings
</jaxb:bindings>
</jaxb:bindings>
There are more bindings defined than just the single I've shown, but my problem is that the bindings are now executed on the FirstSchema.xsd. I have a lot of other xsd files that require the exact same bindings. If I have over 10 more xsd files, I'd have to copy-paste these bindings every time for every schema.
Is it possible to "extract" the bindings and re-use them for every other xsd file like an import? It's kind of related to this comment/question. The advised solution there is using jaxb:schemaBindings/jaxb:package, but if I understand correctly the following snippet just generates the classes into another package and doesn't really solve the problem?
<jaxb:schemaBindings>
<jaxb:package name="com.example.package"/>
</jaxb:schemaBindings>
You'll be surprized, but old-school XML inclusion works with XJB files.
binding.xjb:
<!DOCTYPE jaxb:bindings [
<!ENTITY gh24type SYSTEM "gh24type.xml">
]>
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="annox"
jaxb:version="2.1">
<jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
<!-- ... -->
&gh24type;
</jaxb:bindings>
</jaxb:bindings>
gh24type.xml:
<jaxb:bindings node="xsd:complexType[#name='gh24Type']">
<annox:annotate>#javax.annotation.Generated({"jaxb2-annotate-plugin"})</annox:annotate>
</jaxb:bindings>
So basically nothing spectacular, just entity-based XML inclusion. If you have exactly the same fragments, just include your entity several times for each of the schemas in question.
Alternatives would be writing a special plugin to simplify customization. Which might be a good idea anyway.

How to rename a xsd element during xjc java class generation?

I'm generating java classes from xsd with cxf-xjc-plugin.
<?xml version="1.0" encoding="utf-16"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="result">
...
</xsd>
I'm trying to rename the root element using a jaxb-binding.xml file:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc"
jaxb:version="2.1">
<jaxb:bindings schemaLocation="xsd/myxsd.xsd" node="//xsd:element[#name='result']">
<jaxb:class name="MyNewName" />
</jaxb:bindings>
</jaxb:bindings>
But it does not work. The generated java class is named Result. What might be wrong here?

Property is already defined error in wsdl2java

I am trying to generate proxy classes from wsdl2java using cxf, but whenever I try I keep on getting below error:
WSDLToJava Error: http://webservices.sabre.com/wsdl/sabreXML1.0.00/shopping/Grou
pedItineraryResponse_v1-0-2.xsd [0,0]: Property "ValidatingCarrier" is already d
efined. Use <jaxb:property> to resolve this conflict.
http://webservices.sabre.com/wsdl/sabreXML1.0.00/shopping/GroupedItineraryRespon
se_v1-0-2.xsd [0,0]: The following location is relevant to the above error
I tried to add binding file to wsdl2java.bat as I got info from one of the url like this:
<jaxws:bindings wsdlLocation="http://webservices.sabre.com/wsdl/sabreXML1.0.00/shopping/BargainFinderMaxRQ_v1-8-2.wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:extensionBindingPrefixes="xjc"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema">
<jaxb:globalBindings
jaxb:version="2.0">
<xjc:simple />
</jaxb:globalBindings>
</jaxws:bindings>
I am using third party wsdl url, so I don't have any control to change on the server side, I need to make changes only on command to successfuly generate proxy classes. Can someone kindly help me in this issue?
The problem is that FareType has both child element named ValidatingCarrier and attribute with the same name.
To work around this you should add field binding as suggested by error message. Example binding:
<jaxb:bindings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
jaxb:version="2.1"
schemaLocation="http://webservices.sabre.com/wsdl/sabreXML1.0.00/shopping/GroupedItineraryResponse_v1-0-2.xsd">
<jaxb:bindings node="//xs:complexType[#name='FareType']/xs:sequence/xs:element[#name='ValidatingCarrier']">
<jaxb:property name="validatingCarrierInfo"></jaxb:property>
</jaxb:bindings>
</jaxb:bindings>
With this binding I renamed ValidatingCarrier to ValidatingCarrierInfo.

How to set #XmlType.namespace via JAXB External Bindings Customization file

I am using JAXB to process multiple XML documents.
My issue is that I cannot change the related xsd's and I don't want to amend the generated classes.
What I want to do is employ JAXB Binding customization files to achieve the desired result.
All I need to do is perform the equivalent of using the #XmlType.namespace annotation.
Is it possible to set the #XmlType.namespace annotation via JAXB Binding Customization files?
Disclaimer: I am the author of the jaxb2-annotate-plugin.
You can use the jaxb2-annotate-plugin to add arbitrary annotations to your schema-derived classes. #XmlType will be something like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:annox="http://annox.dev.java.net"
jaxb:extensionBindingPrefixes="xjc annox"
version="2.1">
<jaxb:bindings schemaLocation="schema.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='someType']">
<annox:annotateClass>#javax.xml.bind.annotation.XmlType(namespace="urn:test")</annox:annotateClass>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
If you already have an #XmlType there, the customized annotation will be "merged" into it.

Categories

Resources