membersound
membersound

Reputation: 86885

CXF is not generating enum mapping?

I'm generating classes with CXF (wsdl2java) out of wsdl files, but one enum is instead mapped to a String only.

If I open the generated class, this is the wsdl snippet:

 <complexType>
    <complexContent>
      <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
        <attribute name="Type" use="required">
          <simpleType>
            <restriction base="{http://www.w3.org/2001/XMLSchema}string">
              <enumeration value="AAA"/>
              <enumeration value="VVV"/>
            </restriction>
          </simpleType>
        </attribute>
      </restriction>
    </complexContent>
  </complexType>

Why is the result a String, and not an Enum? This is the auto generated result:

private String type;

public String getType() {
    return type;
}

public void setType(String value) {
    this.type = value;
}

Update: custom binding file:

<jaxb:bindings    
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    jaxb:version="2.1">


         <jaxb:bindings>
                <jaxb:bindings node="//xs:attribute[@name='Type']/xs:simpleType">
                 <jaxb:typesafeEnumClass ref="TestEnum" />
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

Upvotes: 3

Views: 4396

Answers (2)

Gangnus
Gangnus

Reputation: 24484

The following information appeared as a result of my experiments. I couldn't find anything useful in the CXF manuals.

  • if you declare a type inside another type, and it is simpletype, you have NO type in the container java class, but only a field. If your restriction was based on string, you will have the field of the String type.
  • if that inner type is complextype (you must put a simplecontent element between complextype and restriction), you have an inner class with the correct name, but it is NOT a real enumeration. You can get a String value by getValue(). You can use any string data for it and get no error. (IMHO, absolutely useless variant)
  • if you declare your enumeration as a complextype without container type, you will have it as a public not-inner class. Otherwards, it is as the previous. Again, it is no enumeration, no check for correctness, no real restrictions. Useless.
  • if you declare your enumeration type outside of any container type, and it will be a simpletype, you have a public non-inner enumeration. Obviously, it is what you would like to see.

What is worse, even the fourth variant won't catch an error in an XML message for you. If:

enumeration StyleType {A,B,C}
...
StyleType Style 

And you have XML message with incorrect (not one of A,B,C) value for Style, you will simply get null when using getStyle(). So, instead of having nice message "in ... message on line ... position ... there are incorrect data", you have to add a check for not null after every gerStyle(). If you don't want the user to get NullPointerException's.

Upvotes: 5

Radek Postołowicz
Radek Postołowicz

Reputation: 4784

"... one enum is instead mapped to a String only."

"Why is the result a String, and not an Enum?"

This could happen when one of your enumeration value is not a valid Java identifier (for instance: starts with digit) - JAXB (which cxf's wsdl2java delegates work to) is de facto forced to use String field, otherwise generated code wouldn't compile.

Recommended reading: http://blog.bdoughan.com/2011/08/jaxb-and-enums.html

Upvotes: 4

Related Questions