users@jaxb.java.net

Re: Bad enum value in the input XML does not throw exception, assigns null

From: John Leonard <jleonard.20081_at_gmx.com>
Date: Fri, 02 Oct 2009 22:34:53 -0400

Shashi Velur wrote:
> Thanks 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
>
>
>
> Wolfgang Laun-2 wrote:
>
>> It 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_at_gmail.com> wrote:
>>
>>
>>> Hello:
>>>
>>> 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
>>> --
>>> View this message in context:
>>> http://www.nabble.com/Bad-enum-value-in-the-input-XML-does-not-throw-exception%2C-assigns-null-tp25716728p25716728.html
>>> Sent from the java.net - jaxb users mailing list archive at Nabble.com.
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>
>>>
>>>
>>
>
>

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.