users@jaxb.java.net

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

From: Shashi Velur <vshashi_at_gmail.com>
Date: Mon, 5 Oct 2009 12:39:11 -0700 (PDT)

Thanks 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



John Leonard-6 wrote:
>
> 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.
>
>

-- 
View this message in context: http://www.nabble.com/Bad-enum-value-in-the-input-XML-does-not-throw-exception%2C-assigns-null-tp25716728p25756081.html
Sent from the java.net - jaxb users mailing list archive at Nabble.com.