No enums generated by jax-ws ri 2.2.1 for amazon ecs wsdl file
Asked Answered
W

2

7

I'm attempting to generate artifacts for the following amazon wsdl:
http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

using the following ant task:

<taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
    <classpath>
        <pathelement location="${BUILD_LIBS}/jaxws-ri/lib/jaxws-tools.jar"/>
    </classpath>
</taskdef>

<target name="wsimport" depends="init">
    <delete dir="${generated.src}" />
    <mkdir dir="${generated.src}"/>
    <wsimport
        debug="true"
    keep="true"
    verbose="true"
    destdir="${generated.src}"
    package="com.amazon.webservices.ecs"
    wsdl="wsdl/AWSECommerceService.wsdl"/>
</target>

but no java artifacts are generated for the following element which look like this:

<xs:element name="Condition">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:enumeration value="All"/>
            <xs:enumeration value="New"/>
            <xs:enumeration value="Used"/>
            <xs:enumeration value="Collectible"/>
            <xs:enumeration value="Refurbished"/>
       </xs:restriction>
   </xs:simpleType>
</xs:element>

Basically no enums are generated even though all other elements are generated. Has anyone seen this problem before? I'm using jax-ws ri 2.2.1 http://jax-ws.java.net/2.2.1/
Thanks

Watusi answered 20/11, 2010 at 21:21 Comment(0)
M
5

as referenced by Puspendu, JAXB client customization of the binding is exactly/pretty close to what you need -- you need to use a JAX-WS client customization for your example. JAXB and JAX-WS customizations essentially allows you to augment the definition of schema elements for WSDL/schema's that you do not control. there are MANY different things you can accomplish such as mapping xml element names to custom java elements, altering the generated API, and to answer your question, generating type-safe enum classes for elements that are restricted with an enum.

There are two ways/parts to doing a client customization for JAX-WS.

1) if the WSDL imports an external schema file 2) if the WSDL contains the entire schema definition without any imports

if the wsdl imports an external schema file then,

basically you need to create a new file (typically with a jxb extension, but it really doesn't matter) that you will maintain along side the wsdl you are generating the client stub/api for. typically I name these files schema-file-name_clientcustomization.jxb

every time you get an updated wsdl, you should validate that your JXB file is still valid for that wsdl. The biggest things I've found to look for, especially with enum restrictions, is restricted value changes, namespace changes, type name changes, etc..

the content of this new file will look something similar to this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<jxb:bindings 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"     
  targetNamespace="http://java.sun.com/xml/ns/jaxb" 
   version="1.0">

    <jxb:bindings schemaLocation="NameOfYourSchemaFile.xsd" 
         node="/xsd:schema[@targetNamespace='SCHEMANAMESPACE']">
        <jxb:schemaBindings>
            <jxb:package name="com.amazon.webservices.ecs" />
        </jxb:schemaBindings>

        <jxb:bindings node="xsd:element[@name='Condition']/xsd:simpleType">
            <jxb:typesafeEnumClass name="ConditionEnum" >
                <jxb:typesafeEnumMember value="All" name="ALL" />
                <jxb:typesafeEnumMember value="New" name="NEW" />
                <jxb:typesafeEnumMember value="Used" name="USED" />
                <jxb:typesafeEnumMember value="Collectible" name="COLLECTIBLE" />
                <jxb:typesafeEnumMember value="Refurbished" name="REFURBISHED" />
            </jxb:typesafeEnumClass>
        </jxb:bindings>
         </jxb:bindings>
</jxb:bindings>

Essentially this file defines augmentation that should be done to the referenced xsd file. all bindings elements in this file have a node attribute which is an XPATH expression that selects the schema item that you want to augment. in the example, I don't have any namespace or other information so I specified the XPATH to select just the element's simple type declaration. within that binding, we define the typesafeenumclass, this causes the jaxb/wsimport to generate an enum class to represent the referenced simple type. since it's an anonymous simple type, this effectively defines a class just for the referenced element. The generated class will be an ENUM who's memebers are defined by the "name" attribute of the typesafeEnumMember element.

to use this JXB file, you need to reference it in your ant task, like so:

<wsimport
        debug="true"
    keep="true"
    verbose="true"
    destdir="${generated.src}"
    package="com.amazon.webservices.ecs"
    wsdl="wsdl/AWSECommerceService.wsdl">

    <binding dir="wsdl" includes="*.jxb"/>

</wsimport>

if the WSDL defines the entire schema internally, then you need to use a JAX-WS customization file. This case is what matches your question.

http://jax-ws.java.net/nonav/2.1.7/docs/customizations.html

JAX-WS client customization is very similar to the JAXB customization. The idea is identical, for the most part the JAX-WS portion of the customization file will alter generated artifacts that are specifically related to WSDL, whereas the embedded JAXB customization performs the same function as an external customization file: it alters the generated objects based on the schema.

The big difference is that rather than tell the JAXB parser where the schema file is, you provide a binding section that selects the schema definition (using XPATH) that you want to apply customization to.

This example I actually tested and verified to generate an Enum class for the element you are asking questions about, so you can copy this JAX-WS customization example verbatim.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<jaxws:bindings
        wsdlLocation="AWSECommerceService.wsdl" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    >

    <jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://webservices.amazon.com/AWSECommerceService/2010-11-01']">
        <jaxb:schemaBindings>
            <jaxb:package name="com.amazon.webservices.ecs"/>
        </jaxb:schemaBindings>


        <jaxb:bindings node="xsd:element[@name='Condition']/xsd:simpleType">
            <jaxb:typesafeEnumClass name="ConditionEnum" >
                <jaxb:typesafeEnumMember value="All" name="ALL" />
                <jaxb:typesafeEnumMember value="New" name="NEW" />
                <jaxb:typesafeEnumMember value="Used" name="USED" />
                <jaxb:typesafeEnumMember value="Collectible" name="COLLECTIBLE" />
                <jaxb:typesafeEnumMember value="Refurbished" name="REFURBISHED" />
            </jaxb:typesafeEnumClass>
        </jaxb:bindings>

    </jaxws:bindings>

</jaxws:bindings>

you would then reference this JAX-WS customization file the same way you would reference the JXB file.

I did not validate the standalone JAXB customization example, since I really only included it as an example and as a precursor explanation for the JAX-WS customization example.

The JAX-WS customization example I did actually test/validate against the WSDL you have linked, so you should be able to use it as a starting point. I noticed that there are numerous enumerated restrictions in the defined WSDL, so I would assume you'll want to generate enums for most/all of them.

I hope this helps.

Mitinger answered 3/12, 2010 at 17:34 Comment(0)
C
1

Use typesafeEnumMember in JAXB-Binding

Ref: http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp148439

Or

Something like this[ added name="ConditionType" ]:

<xs:simpleType name="ConditionType">
            <xs:restriction base="xs:string">
                <xs:enumeration value="All"/>
                <xs:enumeration value="New"/>
                <xs:enumeration value="Used"/>
                <xs:enumeration value="Collectible"/>
                <xs:enumeration value="Refurbished"/>
            </xs:restriction>
        </xs:simpleType>
Cautionary answered 30/11, 2010 at 20:2 Comment(7)
Hi thanks for your answer. Would you be able to elaborate on that? I don't control the wsdl file it comes from Amazon.Watusi
@leftbrainlogic if the way described by Helter looks tough to follow, just add a 'name' attribute to the simpleType node corrensponding xs:enumerationCautionary
if you don't own the WSDL, then editing it to suit your needs isn't a very scalable option. you would have to re-do the editing, every time you get a new version of the wsdl. this is exactly the case that Client side customization was built for. if you have no issues with editing and re-editing the wsdl, you can refactor the anonymous inner type of the Condition element into a proper named simple type, and it will generate an enum class, however that isn't practical to do every time you get a new WSDL, especially with the number of enums defined in the amazon wsdl.Mitinger
@Helter If you get a new version of WSDL, you need to check/modify JAXB/JAX-WS binding too. Just for example, if they provide a new wsdlonly with a single ConditionType added, you need to find-out and map that. I am not saying binding is useless, rather my point is if there is easier way, we should follow that first.Cautionary
That is true. you would need to update the binding customization when things are updated in the wsdl. however, there are TONS of anonymous enums defined in the amazon wsdl. converting all of those anonymous types to named types would be way too much work. especially if you have to do it over and over every time you get a wsdl. you would have to know how you re-factored the wsdl and then figure out how the new wsdl differs from the old wsdl. the binding file can simply be compared to the new wsdl and updated. it's a lot of boiler plate, but I think it gives the best option long-term.Mitinger
@Helter we should take care of the practical and result-oriented approach too. Binding customization with XPath based node mapping is very buggy in different versions of sun/oracle jdk. see this bug: bugs.sun.com/bugdatabase/view_bug.do?bug_id=4769801Cautionary
@Helter Your solution is good enough and I appreciate your effort to write the sample, so .. upvoting :)Cautionary

© 2022 - 2024 — McMap. All rights reserved.