|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
Bad enum value in the input XML does not throw exception, assigns nullHello:
I am looking for some help on enforcing the type-safety of the enumeration values passed-in from the XML. The current behavior I am seeing with JAXB RI ver. 2.1.9 is that the invalid enumerations in XML are mapped to null values in the generated Java classes. I expected to see an exception thrown whenever Unmarshaller.unmarshal(xmlStreamReader, clazz) method is invoked with an XML that has an invalid enum value. I looked through the JAXB RI source while debugging and found that the following method in com.sun.xml.bind.v2.model.impl.RuntimeEnumLeafInfoImpl.java is returning a null whenever the map (with all valid enum Strings) is looked-up using the given enum value (in my case an invalid enum value): <snip> public T parse(CharSequence lexical) throws AccessorException, SAXException { // TODO: error handling B b = baseXducer.parse(lexical); if(b==null) { return null; } return parseMap.get(b); } </snip> This seems to be called from com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.CompositeTransducedAccessorImpl class. The following code snippet simply sets null to the Java Object (of the generated JAXB Java class) whenever the previous method call is made with an invalid enumeration. <snip> public void parse(BeanT bean, CharSequence lexical) throws AccessorException, SAXException { acc.set(bean,xducer.parse(lexical)); } </snip> Is this the expected behavior? I expect the above method to check for the null return value of xducer.parse(lexical) and throw an exception as the passed-in value does not match any of the given enum values. I have used the following XML annotation for type-safety: <snip> <xs:simpleType name="terminationType"> <xs:annotation> <xs:appinfo> <jaxb:typesafeEnumClass /> </xs:appinfo> </xs:annotation> <xs:restriction base="xs:string"> <xs:enumeration value="NONE"> <xs:annotation> <xs:appinfo> <jaxb:typesafeEnumMember name="NONE" /> </xs:appinfo> </xs:annotation> </xs:enumeration> <xs:enumeration value="REQUEST"> <xs:annotation> <xs:appinfo> <jaxb:typesafeEnumMember name="REQUEST" /> </xs:appinfo> </xs:annotation> </xs:enumeration> <xs:enumeration value="RESPONSE"> <xs:annotation> <xs:appinfo> <jaxb:typesafeEnumMember name="RESPONSE" /> </xs:appinfo> </xs:annotation> </xs:enumeration> <xs:enumeration value="EXCEPTION"> <xs:annotation> <xs:appinfo> <jaxb:typesafeEnumMember name="EXCEPTION" /> </xs:appinfo> </xs:annotation> </xs:enumeration> </xs:restriction> </xs:simpleType> </snip> Any help is much appreciated. Thank you. Cheers, Shashi Twitter: @shashivelur Blog: http://www.shashivelur.com.blog LinkedIn: http://www.linkedin.com/in/shashivelur |
|
|
Re: Bad enum value in the input XML does not throw exception, assigns nullIt seems that you have misinterpreted the meaning of the typesafeEnumMemberName customization: This is an element to be used as a child of <jaxb:globalBindings>, and the value of its 'name' attribute should be "generateError" to get what you expect.
-W On Fri, Oct 2, 2009 at 6:16 PM, Shashi Velur <vshashi@...> wrote:
|
|
|
Re: Bad enum value in the input XML does not throw exception, assigns nullThanks for the quick reply. I tried reading the JAXB spec. Perhaps, I do not understand this very well.
I tried what I think you suggested as pasted below (with the relevant portions of my WSDL) - But, got an error ("Unable to generate code using jaxbri") when running the maven target for generating source. <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ..... xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"> .... .... <xs:schema ..... > <xs:annotation> <xs:appinfo> <jaxb:globalBindings typesafeEnumMemberName="generateError" > <jaxb:typesafeEnumClass name="TerminationType"> <jaxb:typesafeEnumMember name="NONE" value="NONE" /> <jaxb:typesafeEnumMember name="REQUEST" value="REQUEST" /> <jaxb:typesafeEnumMember name="RESPONSE" value="RESPONSE" /> <jaxb:typesafeEnumMember name="EXCEPTION" value="EXCEPTION" /> </jaxb:typesafeEnumClass> </jaxb:globalBindings> </xs:appinfo> </xs:annotation> .... .... <xs:simpleType name="terminationType"> <xs:restriction base="xs:string"> <xs:enumeration value="NONE" /> <xs:enumeration value="REQUEST" /> <xs:enumeration value="RESPONSE" /> <xs:enumeration value="EXCEPTION" /> </xs:restriction> </xs:simpleType> .... .... </xs:schema> .... .... </wsdl:definitions> I also tried several variations (inline, etc.) as suggested in the JAXB spec. But, I either get code-generation errors or the code just ignores the invalid enumerations passed-in from my XML instead of throwing exceptions. Will you look at this XML and point me in the right direction? I would appreciate if you can correct the above XML, if you can. Thanks again. Cheers, Shashi
|
|
|
Re: Bad enum value in the input XML does not throw exception, assigns null
If you want to unmarshall-validate, don't you need something like the following (from jaxb-ri code samples) : ********************************************************** ********************************************************** try { JAXBContext jc = JAXBContext.newInstance( "primer.po" ); Unmarshaller u = jc.createUnmarshaller(); SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); try { Schema schema = sf.newSchema(new File("po.xsd")); u.setSchema(schema); u.setEventHandler( new ValidationEventHandler() { public boolean handleEvent(ValidationEvent ve) { if (ve.getSeverity() != ValidationEvent.WARNING) { ValidationEventLocator vel = ve.getLocator(); System.out.println("Line:Col[" + vel.getLineNumber() + ":" + vel.getColumnNumber() + "]:" + ve.getMessage()); } return true; } } ); } catch (org.xml.sax.SAXException se) { System.out.println("Unable to validate due to following error."); se.printStackTrace(); } ********************************************************** ********************************************************** i.e., it isn't sufficient to just unmarshall the code, you also need to attach the schema to the unmarshaller. John L. |
|
|
Re: Bad enum value in the input XML does not throw exception, assigns nullHello Shashi,
the correct form for the customization would be: <xs:annotation> <xs:appinfo> <jaxb:globalBindings typesafeEnumMemberName="generateError"/> </xs:appinfo> </xs:annotation> However, I failed to realize that your problem results from XML data being incorrect. For this, setting the schema - as posted by John - is the way to go. The typesafeEnumMemberName just affects the way the restricted xs:string is compiled into an enum; so this setting would cause an error when you call xjc with a type definition that cannot be made into an enum, e.g.: <xs:simpleType name="terminationType"> <xs:restriction base="xs:string"> <xs:enumeration value="NONE" /> <xs:enumeration value="none" /> ... -W On Sat, Oct 3, 2009 at 12:11 AM, Shashi Velur <vshashi@...> wrote:
|
|
|
Re: Bad enum value in the input XML does not throw exception, assigns nullThanks again for the info.
I had a ValidationEventHandler, but was missing the unmarshaller.setSchema(schema) call. After adding this, it worked. I just realized that the JavaDocs for the Unmarshaller.setSchema() method clearly says that by default the schema is set to null. Another interesting observation I made is that for my example, the jaxb annotations were not necessary. So, after taking off all of the jaxb annotations in my XSD, I still got an error when an invalid enum value was passed in the XML. Cheers, Shashi
|
| Free embeddable forum powered by Nabble | Forum Help |