aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.tools.internal.xjc.model; aoqi@0: aoqi@0: import java.util.Collection; aoqi@0: aoqi@0: import javax.activation.MimeType; aoqi@0: import javax.xml.namespace.QName; aoqi@0: aoqi@0: import com.sun.codemodel.internal.JClass; aoqi@0: import com.sun.codemodel.internal.JExpression; aoqi@0: import com.sun.tools.internal.xjc.model.nav.NClass; aoqi@0: import com.sun.tools.internal.xjc.model.nav.NType; aoqi@0: import com.sun.tools.internal.xjc.outline.Aspect; aoqi@0: import com.sun.tools.internal.xjc.outline.Outline; aoqi@0: import com.sun.xml.internal.bind.v2.model.annotation.Locatable; aoqi@0: import com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo; aoqi@0: import com.sun.xml.internal.bind.v2.model.core.ID; aoqi@0: import com.sun.xml.internal.bind.v2.model.core.NonElement; aoqi@0: import com.sun.xml.internal.bind.v2.model.core.Element; aoqi@0: import com.sun.xml.internal.bind.v2.runtime.Location; aoqi@0: import com.sun.xml.internal.xsom.XSComponent; aoqi@0: import com.sun.xml.internal.xsom.XmlString; aoqi@0: aoqi@0: import org.xml.sax.Locator; aoqi@0: aoqi@0: /** aoqi@0: * Transducer that converts a string into an "enumeration class." aoqi@0: * aoqi@0: * The structure of the generated class needs to precisely aoqi@0: * follow the JAXB spec. aoqi@0: * aoqi@0: * @author aoqi@0: * Kohsuke KAWAGUCHI aoqi@0: */ aoqi@0: public final class CEnumLeafInfo implements EnumLeafInfo, NClass, CNonElement aoqi@0: { aoqi@0: /** aoqi@0: * The {@link Model} object to which this bean belongs. aoqi@0: */ aoqi@0: public final Model model; aoqi@0: aoqi@0: /** aoqi@0: * The parent into which the enum class should be generated. aoqi@0: */ aoqi@0: public final CClassInfoParent parent; aoqi@0: aoqi@0: /** aoqi@0: * Short name of the generated type-safe enum. aoqi@0: */ aoqi@0: public final String shortName; aoqi@0: aoqi@0: private final QName typeName; aoqi@0: aoqi@0: private final XSComponent source; aoqi@0: aoqi@0: /** aoqi@0: * Represents the underlying type of this enumeration aoqi@0: * and its conversion. aoqi@0: * aoqi@0: *

aoqi@0: * To parse XML into a constant, we use the base type aoqi@0: * to do lexical -> value, then use a map to pick up the right one. aoqi@0: * aoqi@0: *

aoqi@0: * Hence this also represents the type of the Java value. aoqi@0: * For example, if this is an enumeration of xs:int, aoqi@0: * then this field will be Java int. aoqi@0: */ aoqi@0: public final CNonElement base; aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * List of enum members. aoqi@0: */ aoqi@0: public final Collection members; aoqi@0: aoqi@0: private final CCustomizations customizations; aoqi@0: aoqi@0: /** aoqi@0: * @see #getLocator() aoqi@0: */ aoqi@0: private final Locator sourceLocator; aoqi@0: aoqi@0: public String javadoc; aoqi@0: aoqi@0: public CEnumLeafInfo(Model model, aoqi@0: QName typeName, aoqi@0: CClassInfoParent container, aoqi@0: String shortName, aoqi@0: CNonElement base, aoqi@0: Collection _members, aoqi@0: XSComponent source, aoqi@0: CCustomizations customizations, aoqi@0: Locator _sourceLocator) { aoqi@0: this.model = model; aoqi@0: this.parent = container; aoqi@0: this.shortName = model.allocator.assignClassName(parent,shortName); aoqi@0: this.base = base; aoqi@0: this.members = _members; aoqi@0: this.source = source; aoqi@0: if(customizations==null) aoqi@0: customizations = CCustomizations.EMPTY; aoqi@0: this.customizations = customizations; aoqi@0: this.sourceLocator = _sourceLocator; aoqi@0: this.typeName = typeName; aoqi@0: aoqi@0: for( CEnumConstant mem : members ) aoqi@0: mem.setParent(this); aoqi@0: aoqi@0: model.add(this); aoqi@0: aoqi@0: // TODO: can we take advantage of the fact that enum can be XmlRootElement? aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Source line information that points to the place aoqi@0: * where this type-safe enum is defined. aoqi@0: * Used to report error messages. aoqi@0: */ aoqi@0: public Locator getLocator() { aoqi@0: return sourceLocator; aoqi@0: } aoqi@0: aoqi@0: public QName getTypeName() { aoqi@0: return typeName; aoqi@0: } aoqi@0: aoqi@0: public NType getType() { aoqi@0: return this; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * @deprecated aoqi@0: * why are you calling the method whose return value is known? aoqi@0: */ aoqi@0: public boolean canBeReferencedByIDREF() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public boolean isElement() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public QName getElementName() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: public Element asElement() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: public NClass getClazz() { aoqi@0: return this; aoqi@0: } aoqi@0: aoqi@0: public XSComponent getSchemaComponent() { aoqi@0: return source; aoqi@0: } aoqi@0: aoqi@0: public JClass toType(Outline o, Aspect aspect) { aoqi@0: return o.getEnum(this).clazz; aoqi@0: } aoqi@0: aoqi@0: public boolean isAbstract() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public boolean isBoxedType() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public String fullName() { aoqi@0: return parent.fullName()+'.'+shortName; aoqi@0: } aoqi@0: aoqi@0: public boolean isPrimitive() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public boolean isSimpleType() { aoqi@0: return true; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * The spec says the value field in the enum class will be generated aoqi@0: * only under certain circumstances. aoqi@0: * aoqi@0: * @return aoqi@0: * true if the generated enum class should have the value field. aoqi@0: */ aoqi@0: public boolean needsValueField() { aoqi@0: for (CEnumConstant cec : members) { aoqi@0: if(!cec.getName().equals(cec.getLexicalValue())) aoqi@0: return true; aoqi@0: } aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: public JExpression createConstant(Outline outline, XmlString literal) { aoqi@0: // correctly identifying which constant it maps to is hard, so aoqi@0: // here I'm cheating aoqi@0: JClass type = toType(outline,Aspect.EXPOSED); aoqi@0: for (CEnumConstant mem : members) { aoqi@0: if(mem.getLexicalValue().equals(literal.value)) aoqi@0: return type.staticRef(mem.getName()); aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: @Deprecated aoqi@0: public boolean isCollection() { aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: @Deprecated aoqi@0: public CAdapter getAdapterUse() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: @Deprecated aoqi@0: public CNonElement getInfo() { aoqi@0: return this; aoqi@0: } aoqi@0: aoqi@0: public ID idUse() { aoqi@0: return ID.NONE; aoqi@0: } aoqi@0: aoqi@0: public MimeType getExpectedMimeType() { aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: public Collection getConstants() { aoqi@0: return members; aoqi@0: } aoqi@0: aoqi@0: public NonElement getBaseType() { aoqi@0: return base; aoqi@0: } aoqi@0: aoqi@0: public CCustomizations getCustomizations() { aoqi@0: return customizations; aoqi@0: } aoqi@0: aoqi@0: public Locatable getUpstream() { aoqi@0: throw new UnsupportedOperationException(); aoqi@0: } aoqi@0: aoqi@0: public Location getLocation() { aoqi@0: throw new UnsupportedOperationException(); aoqi@0: } aoqi@0: }