001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.jaxb.property;
031:
032: import java.io.IOException;
033:
034: import java.lang.reflect.Field;
035:
036: import java.util.HashMap;
037: import java.util.LinkedHashMap;
038:
039: import javax.xml.bind.JAXBException;
040: import javax.xml.bind.MarshalException;
041: import javax.xml.bind.UnmarshalException;
042:
043: import javax.xml.bind.annotation.XmlEnum;
044: import javax.xml.bind.annotation.XmlEnumValue;
045:
046: import javax.xml.namespace.QName;
047:
048: import javax.xml.stream.XMLStreamException;
049: import javax.xml.stream.XMLStreamWriter;
050:
051: import com.caucho.jaxb.JAXBContextImpl;
052: import com.caucho.jaxb.JAXBUtil;
053:
054: import com.caucho.util.L10N;
055:
056: /**
057: * a property for an enum
058: */
059: public class EnumProperty<E extends Enum<E>> extends CDataProperty {
060: private static final L10N L = new L10N(EnumProperty.class);
061:
062: public static final String XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
063:
064: private final Class<E> _enum;
065: private final Class _base;
066: private final QName _baseName;
067: private final HashMap<String, E> _valueMap = new HashMap<String, E>();
068: private final LinkedHashMap<E, String> _nameMap = new LinkedHashMap<E, String>();
069: private final QName _typeName;
070:
071: public EnumProperty(Class<E> e, JAXBContextImpl context)
072: throws JAXBException {
073: _enum = e;
074: _typeName = JAXBUtil.getXmlSchemaDatatype(_enum, context);
075:
076: try {
077: XmlEnum xmlEnum = _enum.getAnnotation(XmlEnum.class);
078: _base = xmlEnum.value();
079: _baseName = JAXBUtil.getXmlSchemaDatatype(_base, context);
080:
081: // XXX check that base is an XML simple type
082:
083: Field[] fields = _enum.getFields();
084:
085: for (int i = 0; i < fields.length; i++) {
086: Field f = fields[i];
087:
088: // We only care about actual enum fields
089: if (!fields[i].isEnumConstant())
090: continue;
091:
092: XmlEnumValue xmlEnumValue = f
093: .getAnnotation(XmlEnumValue.class);
094: E value = Enum.valueOf(_enum, f.getName());
095:
096: if (xmlEnumValue != null) {
097: _valueMap.put(xmlEnumValue.value(), value);
098: _nameMap.put(value, xmlEnumValue.value());
099: } else {
100: _valueMap.put(f.getName(), value);
101: _nameMap.put(value, f.getName());
102: }
103: }
104: } catch (Exception ex) {
105: throw new JAXBException(L.l(
106: "Error while introspecting enum {0}", e.getName()),
107: ex);
108: }
109: }
110:
111: public String write(Object in) throws JAXBException {
112: String out = _nameMap.get(in);
113:
114: if (out == null)
115: throw new MarshalException(L.l("Unknown enum value: {0}",
116: in));
117:
118: return out;
119: }
120:
121: protected Object read(String in) throws JAXBException {
122: Object obj = _valueMap.get(in);
123:
124: if (obj == null)
125: throw new UnmarshalException(L.l(
126: "Invalid enum string: {0}", in));
127:
128: return obj;
129: }
130:
131: public QName getSchemaType() {
132: return _typeName;
133: }
134:
135: public void generateSchema(XMLStreamWriter out)
136: throws XMLStreamException {
137: out.writeStartElement("xsd", "simpleType", XML_SCHEMA_NS);
138: out.writeAttribute("name", JAXBUtil.qNameToString(_typeName));
139:
140: out.writeStartElement("xsd", "restriction", XML_SCHEMA_NS);
141: out.writeAttribute("base", JAXBUtil.qNameToString(_baseName));
142:
143: for (String name : _nameMap.values()) {
144: out.writeEmptyElement("xsd", "enumeration", XML_SCHEMA_NS);
145: out.writeAttribute("value", name);
146: }
147:
148: out.writeEndElement(); // restriction
149: out.writeEndElement(); // simpleType
150: }
151: }
|