users@jaxb.java.net

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

From: Shashi Velur <vshashi_at_gmail.com>
Date: Fri, 2 Oct 2009 10:54:07 -0500

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