src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/EnumLeafInfoImpl.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.bind.v2.model.impl;
    28 import java.util.Iterator;
    30 import javax.xml.bind.annotation.XmlEnum;
    31 import javax.xml.bind.annotation.XmlEnumValue;
    32 import javax.xml.bind.annotation.XmlRootElement;
    33 import javax.xml.namespace.QName;
    35 import com.sun.xml.internal.bind.v2.model.annotation.Locatable;
    36 import com.sun.xml.internal.bind.v2.model.core.EnumConstant;
    37 import com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo;
    38 import com.sun.xml.internal.bind.v2.model.core.NonElement;
    39 import com.sun.xml.internal.bind.v2.model.core.Element;
    40 import com.sun.xml.internal.bind.v2.model.core.ClassInfo;
    41 import com.sun.xml.internal.bind.v2.runtime.Location;
    42 import java.util.Collection;
    43 import javax.xml.bind.annotation.XmlSchemaType;
    45 /**
    46  * {@link EnumLeafInfo} implementation.
    47  *
    48  * @author Kohsuke Kawaguchi
    49  */
    50 class EnumLeafInfoImpl<T,C,F,M> extends TypeInfoImpl<T,C,F,M>
    51         implements EnumLeafInfo<T,C>, Element<T,C>, Iterable<EnumConstantImpl<T,C,F,M>> {
    53     /**
    54      * The enum class whose information this object represents.
    55      */
    56     /*package*/ final C clazz;
    58     NonElement<T,C> baseType;
    60     private final T type;
    62     /**
    63      * Can be null for anonymous types.
    64      */
    65     private final QName typeName;
    67     /**
    68      * All the {@link EnumConstantImpl}s are linked in this list.
    69      */
    70     private EnumConstantImpl<T,C,F,M> firstConstant;
    72     /**
    73      * If this enum is also bound to an element, that tag name.
    74      * Or else null.
    75      */
    76     private QName elementName;
    78     /**
    79      * Used to recognize token vs string.
    80      */
    81     protected boolean tokenStringType;
    83     /**
    84      * @param clazz
    85      * @param type
    86      *      clazz and type should both point to the enum class
    87      *      that this {@link EnumLeafInfo} represents.
    88      *      Because of the type parameterization we have to take them separately.
    89      */
    90     public EnumLeafInfoImpl(ModelBuilder<T,C,F,M> builder,
    91                             Locatable upstream, C clazz, T type ) {
    92         super(builder,upstream);
    93         this.clazz = clazz;
    94         this.type = type;
    96         elementName = parseElementName(clazz);
    98         // compute the type name
    99         // TODO: I guess it must be allowed for enums to have @XmlElement
   100         typeName = parseTypeName(clazz);
   102         // locate the base type.
   103         // this can be done eagerly because there shouldn't be no cycle.
   104         XmlEnum xe = builder.reader.getClassAnnotation(XmlEnum.class, clazz, this);
   105         if(xe!=null) {
   106             T base = builder.reader.getClassValue(xe, "value");
   107             baseType = builder.getTypeInfo(base,this);
   108         } else {
   109             baseType = builder.getTypeInfo(builder.nav.ref(String.class),this);
   110         }
   111     }
   113     /**
   114      * Build {@link EnumConstant}s and discover/report any error in it.
   115      */
   116     protected void calcConstants() {
   117         EnumConstantImpl<T,C,F,M> last = null;
   119         // first check if we represent xs:token derived type
   120         Collection<? extends F> fields = nav().getDeclaredFields(clazz);
   121         for (F f : fields) {
   122             if (nav().isSameType(nav().getFieldType(f), nav().ref(String.class))) {
   123                 XmlSchemaType schemaTypeAnnotation = builder.reader.getFieldAnnotation(XmlSchemaType.class, f, this);
   124                 if (schemaTypeAnnotation != null) {
   125                     if ("token".equals(schemaTypeAnnotation.name())) {
   126                         tokenStringType = true;
   127                         break;
   128                     }
   129                 };
   130             }
   131         }
   132         F[] constants = nav().getEnumConstants(clazz);
   133         for( int i=constants.length-1; i>=0; i-- ) {
   134             F constant = constants[i];
   135             String name = nav().getFieldName(constant);
   136             XmlEnumValue xev = builder.reader.getFieldAnnotation(XmlEnumValue.class, constant, this);
   138             String literal;
   139             if(xev==null)   literal = name;
   140             else            literal = xev.value();
   142             last = createEnumConstant(name,literal,constant,last);
   143         }
   144         this.firstConstant = last;
   145     }
   147     protected EnumConstantImpl<T,C,F,M> createEnumConstant(String name, String literal, F constant, EnumConstantImpl<T,C,F,M> last) {
   148         return new EnumConstantImpl<T,C,F,M>(this, name, literal, last);
   149     }
   152     public T getType() {
   153         return type;
   154     }
   156     /**
   157      *
   158      * @return true if enum is restriction/extension from xs:token type, otherwise false
   159      */
   160     public boolean isToken() {
   161         return tokenStringType;
   162     }
   164     /**
   165      * Leaf-type cannot be referenced from IDREF.
   166      *
   167      * @deprecated
   168      *      why are you calling a method whose return value is always known?
   169      */
   170     public final boolean canBeReferencedByIDREF() {
   171         return false;
   172     }
   174     public QName getTypeName() {
   175         return typeName;
   176     }
   178     public C getClazz() {
   179         return clazz;
   180     }
   182     public NonElement<T,C> getBaseType() {
   183         return baseType;
   184     }
   186     public boolean isSimpleType() {
   187         return true;
   188     }
   190     public Location getLocation() {
   191         return nav().getClassLocation(clazz);
   192     }
   194     public Iterable<? extends EnumConstantImpl<T,C,F,M>> getConstants() {
   195         if(firstConstant==null)
   196             calcConstants();
   197         return this;
   198     }
   200     @Override
   201     public void link() {
   202         // make sure we've computed constants
   203         getConstants();
   204         super.link();
   205     }
   207     /**
   208      * No substitution.
   209      *
   210      * @deprecated if you are invoking this method directly, there's something wrong.
   211      */
   212     public Element<T, C> getSubstitutionHead() {
   213         return null;
   214     }
   216     public QName getElementName() {
   217         return elementName;
   218     }
   220     public boolean isElement() {
   221         return elementName!=null;
   222     }
   224     public Element<T,C> asElement() {
   225         if(isElement())
   226             return this;
   227         else
   228             return null;
   229     }
   231     /**
   232      * When a bean binds to an element, it's always through {@link XmlRootElement},
   233      * so this method always return null.
   234      *
   235      * @deprecated
   236      *      you shouldn't be invoking this method on {@link ClassInfoImpl}.
   237      */
   238     public ClassInfo<T,C> getScope() {
   239         return null;
   240     }
   242     public Iterator<EnumConstantImpl<T,C,F,M>> iterator() {
   243         return new Iterator<EnumConstantImpl<T,C,F,M>>() {
   244             private EnumConstantImpl<T,C,F,M> next = firstConstant;
   245             public boolean hasNext() {
   246                 return next!=null;
   247             }
   249             public EnumConstantImpl<T,C,F,M> next() {
   250                 EnumConstantImpl<T,C,F,M> r = next;
   251                 next = next.next;
   252                 return r;
   253             }
   255             public void remove() {
   256                 throw new UnsupportedOperationException();
   257             }
   258         };
   259     }
   260 }

mercurial