001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.xjc.model;
027:
028: import java.util.Collection;
029:
030: import javax.activation.MimeType;
031: import javax.xml.namespace.QName;
032:
033: import com.sun.codemodel.internal.JClass;
034: import com.sun.codemodel.internal.JExpression;
035: import com.sun.tools.internal.xjc.model.nav.NClass;
036: import com.sun.tools.internal.xjc.model.nav.NType;
037: import com.sun.tools.internal.xjc.outline.Aspect;
038: import com.sun.tools.internal.xjc.outline.Outline;
039: import com.sun.xml.internal.bind.v2.model.annotation.Locatable;
040: import com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo;
041: import com.sun.xml.internal.bind.v2.model.core.ID;
042: import com.sun.xml.internal.bind.v2.model.core.NonElement;
043: import com.sun.xml.internal.bind.v2.model.core.Element;
044: import com.sun.xml.internal.bind.v2.runtime.Location;
045: import com.sun.xml.internal.xsom.XSComponent;
046: import com.sun.xml.internal.xsom.XmlString;
047:
048: import org.xml.sax.Locator;
049:
050: /**
051: * Transducer that converts a string into an "enumeration class."
052: *
053: * The structure of the generated class needs to precisely
054: * follow the JAXB spec.
055: *
056: * @author
057: * <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
058: */
059: public final class CEnumLeafInfo implements
060: EnumLeafInfo<NType, NClass>, NClass, CNonElement {
061: /**
062: * The {@link Model} object to which this bean belongs.
063: */
064: public final Model model;
065:
066: /**
067: * The parent into which the enum class should be generated.
068: */
069: public final CClassInfoParent parent;
070:
071: /**
072: * Short name of the generated type-safe enum.
073: */
074: public final String shortName;
075:
076: private final QName typeName;
077:
078: private final XSComponent source;
079:
080: /**
081: * Represents the underlying type of this enumeration
082: * and its conversion.
083: *
084: * <p>
085: * To parse XML into a constant, we use the base type
086: * to do lexical -> value, then use a map to pick up the right one.
087: *
088: * <p>
089: * Hence this also represents the type of the Java value.
090: * For example, if this is an enumeration of xs:int,
091: * then this field will be Java int.
092: */
093: public final CNonElement base;
094:
095: /**
096: * List of enum members.
097: */
098: public final Collection<CEnumConstant> members;
099:
100: private final CCustomizations customizations;
101:
102: /**
103: * @see #getLocator()
104: */
105: private final Locator sourceLocator;
106:
107: public String javadoc;
108:
109: public CEnumLeafInfo(Model model, QName typeName,
110: CClassInfoParent container, String shortName,
111: CNonElement base, Collection<CEnumConstant> _members,
112: XSComponent source, CCustomizations customizations,
113: Locator _sourceLocator) {
114: this .model = model;
115: this .parent = container;
116: this .shortName = shortName;
117: this .base = base;
118: this .members = _members;
119: this .source = source;
120: if (customizations == null)
121: customizations = CCustomizations.EMPTY;
122: this .customizations = customizations;
123: this .sourceLocator = _sourceLocator;
124: this .typeName = typeName;
125:
126: for (CEnumConstant mem : members)
127: mem.setParent(this );
128:
129: model.add(this );
130:
131: // TODO: can we take advantage of the fact that enum can be XmlRootElement?
132: }
133:
134: /**
135: * Source line information that points to the place
136: * where this type-safe enum is defined.
137: * Used to report error messages.
138: */
139: public Locator getLocator() {
140: return sourceLocator;
141: }
142:
143: public QName getTypeName() {
144: return typeName;
145: }
146:
147: public NType getType() {
148: return this ;
149: }
150:
151: /**
152: * @deprecated
153: * why are you calling the method whose return value is known?
154: */
155: public boolean canBeReferencedByIDREF() {
156: return false;
157: }
158:
159: public boolean isElement() {
160: return false;
161: }
162:
163: public QName getElementName() {
164: return null;
165: }
166:
167: public Element<NType, NClass> asElement() {
168: return null;
169: }
170:
171: public NClass getClazz() {
172: return this ;
173: }
174:
175: public XSComponent getSchemaComponent() {
176: return source;
177: }
178:
179: public JClass toType(Outline o, Aspect aspect) {
180: return o.getEnum(this ).clazz;
181: }
182:
183: public boolean isAbstract() {
184: return false;
185: }
186:
187: public boolean isBoxedType() {
188: return false;
189: }
190:
191: public String fullName() {
192: return parent.fullName() + '.' + shortName;
193: }
194:
195: public boolean isPrimitive() {
196: return false;
197: }
198:
199: public boolean isSimpleType() {
200: return true;
201: }
202:
203: /**
204: * The spec says the value field in the enum class will be generated
205: * only under certain circumstances.
206: *
207: * @return
208: * true if the generated enum class should have the value field.
209: */
210: public boolean needsValueField() {
211: for (CEnumConstant cec : members) {
212: if (!cec.getName().equals(cec.getLexicalValue()))
213: return true;
214: }
215: return false;
216: }
217:
218: public JExpression createConstant(Outline outline, XmlString literal) {
219: // correctly identifying which constant it maps to is hard, so
220: // here I'm cheating
221: JClass type = toType(outline, Aspect.EXPOSED);
222: for (CEnumConstant mem : members) {
223: if (mem.getLexicalValue().equals(literal.value))
224: return type.staticRef(mem.getName());
225: }
226: return null;
227: }
228:
229: public boolean isCollection() {
230: return false;
231: }
232:
233: public CAdapter getAdapterUse() {
234: return null;
235: }
236:
237: public CTypeInfo getInfo() {
238: return this ;
239: }
240:
241: public ID idUse() {
242: return ID.NONE;
243: }
244:
245: public MimeType getExpectedMimeType() {
246: return null;
247: }
248:
249: public Collection<CEnumConstant> getConstants() {
250: return members;
251: }
252:
253: public NonElement<NType, NClass> getBaseType() {
254: return base;
255: }
256:
257: public CCustomizations getCustomizations() {
258: return customizations;
259: }
260:
261: public Locatable getUpstream() {
262: throw new UnsupportedOperationException();
263: }
264:
265: public Location getLocation() {
266: throw new UnsupportedOperationException();
267: }
268: }
|