users@jaxb.java.net

Re: retrieving enumerated values from schema at runtime (jaxb 1.0.5)

From: Aleksei Valikov <valikov_at_gmx.net>
Date: Thu, 18 May 2006 14:43:43 +0200

Hi.

> Please note that I am aware of the reflection mechanism
> however javax.xml.bind.annotation.XmlType is only available jaxb 1.0.5
>
> I am using jaxb 1.0.5 ( from JWSDP 1.6)
>
> I specified in my xml schema a restriction on values
> for attribute typeArea
>
> <xs:element name="Cameroun" type="town"/>
>
> <xs:simpleType name="town">
> <xs:restriction base="xsd:string">
> <xsd:enumeration value="BAFOUSSAM"/>
> </xsd:restriction>
> </xsd:simpleType>
>
> Is there a way from the generated java code (using jaxb) to have access
> to enumerated value.
> conatined in a given xml schema.
> Clearly jaxb xml validator is aware of the constant value 'BAFOUSSAM',
> because if my Xml constains
> a different value for Cameroun element, the jaxb validator rejects it.
> So I am interested in having
> access to the constant values recorded by the jaxb metadata. I cannot
> see any obvious getter
> in the jaxb generated java objects framework to cater for my needs.
> My current workaround, is to have a xml template, marshall it, record
> the constant values
> I want, and then use them while working with other xml, which are
> instances of the same base xml schema

I would recommend annotate the type so that it becomes an enum.

   <xsd:annotation>
     <xsd:appinfo>
       <jaxb:globalBindings typesafeEnumBase="xsd:string"/>
     </xsd:appinfo>
   </xsd:annotation>

In this case you'll have TownType enum class generated for you.
Here's an example of a enum class type:

/**
  * Java content class for SexType.
  * <p>The following schema fragment specifies the expected content contained
within this java content object.
  * <p>
  * <pre>
  * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
  * &lt;enumeration value="Male"/>
  * &lt;enumeration value="Female"/>
  * &lt;/restriction>
  * </pre>
  *
  */
public class SexType {

     private final static java.util.Map valueMap = new java.util.HashMap();
     public final static java.lang.String _MALE =
com.sun.xml.bind.DatatypeConverterImpl.installHook("Male");
     public final static test.SexType MALE = new test.SexType(_MALE);
     public final static java.lang.String _FEMALE =
com.sun.xml.bind.DatatypeConverterImpl.installHook("Female");
     public final static test.SexType FEMALE = new test.SexType(_FEMALE);
     private final java.lang.String lexicalValue;
     private final java.lang.String value;

     protected SexType(java.lang.String v) {
         value = v;
         lexicalValue = v;
         valueMap.put(v, this);
     }

     public java.lang.String toString() {
         return lexicalValue;
     }

     public java.lang.String getValue() {
         return value;
     }

     public final int hashCode() {
         return super.hashCode();
     }

     public final boolean equals(java.lang.Object o) {
         return super.equals(o);
     }

     public static test.SexType fromValue(java.lang.String value) {
         test.SexType t = ((test.SexType) valueMap.get(value));
         if (t == null) {
             throw new java.lang.IllegalArgumentException();
         } else {
             return t;
         }
     }

     public static test.SexType fromString(java.lang.String str) {
         return fromValue(str);
     }
}

You can then use reflection to inspect the class and gather information you need
like enum instances, codes, mapping and so on.
Alternatively, you can also try the enum add-on from jaxbcommons.dev.java.net.
This add-on will additionally generate nice methods like values(), codes(),
getEnumMap(), getCodeEnumMap().

Bye.
/lexi