aoqi@0: /*
aoqi@0: * Copyright (c) 1997, 2012, 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.xml.internal.ws.spi.db;
aoqi@0:
aoqi@0: import java.lang.annotation.Annotation;
aoqi@0: import java.lang.reflect.GenericArrayType;
aoqi@0: import java.lang.reflect.Type;
aoqi@0: import java.util.Collection;
aoqi@0: import java.util.HashMap;
aoqi@0: import java.util.Map;
aoqi@0:
aoqi@0: import javax.xml.namespace.QName;
aoqi@0:
aoqi@0: import com.sun.xml.internal.bind.v2.model.nav.Navigator;
aoqi@0:
aoqi@0: /**
aoqi@0: * A reference to a JAXB-bound type.
aoqi@0: *
aoqi@0: *
aoqi@0: * Subject to change without notice.
aoqi@0: *
aoqi@0: * @since 2.0 EA1
aoqi@0: * @author Kohsuke Kawaguchi
aoqi@0: * @author shih-chang.chen@oracle.com
aoqi@0: */
aoqi@0: public final class TypeInfo {
aoqi@0:
aoqi@0: /**
aoqi@0: * The associated XML element name that the JAX-RPC uses with this type reference.
aoqi@0: *
aoqi@0: * Always non-null. Strings are interned.
aoqi@0: */
aoqi@0: public final QName tagName;
aoqi@0:
aoqi@0: /**
aoqi@0: * The Java type that's being referenced.
aoqi@0: *
aoqi@0: * Always non-null.
aoqi@0: */
aoqi@0: public Type type;
aoqi@0:
aoqi@0: /**
aoqi@0: * The annotations associated with the reference of this type.
aoqi@0: *
aoqi@0: * Always non-null.
aoqi@0: */
aoqi@0: public final Annotation[] annotations;
aoqi@0:
aoqi@0: private Map properties = new HashMap();
aoqi@0:
aoqi@0: private boolean isGlobalElement = true;
aoqi@0:
aoqi@0: private TypeInfo parentCollectionType;
aoqi@0:
aoqi@0: private Type genericType;
aoqi@0:
aoqi@0: private boolean nillable = true;
aoqi@0:
aoqi@0: public TypeInfo(QName tagName, Type type, Annotation... annotations) {
aoqi@0: if(tagName==null || type==null || annotations==null) {
aoqi@0: String nullArgs = "";
aoqi@0:
aoqi@0: if(tagName == null) nullArgs = "tagName";
aoqi@0: if(type == null) nullArgs += (nullArgs.length() > 0 ? ", type" : "type");
aoqi@0: if(annotations == null) nullArgs += (nullArgs.length() > 0 ? ", annotations" : "annotations");
aoqi@0:
aoqi@0: // Messages.ARGUMENT_CANT_BE_NULL.format(nullArgs);
aoqi@0:
aoqi@0: throw new IllegalArgumentException( "Argument(s) \"" + nullArgs + "\" can''t be null.)");
aoqi@0: }
aoqi@0:
aoqi@0: this.tagName = new QName(tagName.getNamespaceURI().intern(), tagName.getLocalPart().intern(), tagName.getPrefix());
aoqi@0: this.type = type;
aoqi@0: if (type instanceof Class && ((Class>)type).isPrimitive()) nillable = false;
aoqi@0: this.annotations = annotations;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Finds the specified annotation from the array and returns it.
aoqi@0: * Null if not found.
aoqi@0: */
aoqi@0: public A get( Class annotationType ) {
aoqi@0: for (Annotation a : annotations) {
aoqi@0: if(a.annotationType()==annotationType)
aoqi@0: return annotationType.cast(a);
aoqi@0: }
aoqi@0: return null;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Creates a {@link TypeInfo} for the item type,
aoqi@0: * if this {@link TypeInfo} represents a collection type.
aoqi@0: * Otherwise returns an identical type.
aoqi@0: */
aoqi@0: public TypeInfo toItemType() {
aoqi@0: // if we are to reinstitute this check, check JAXB annotations only
aoqi@0: // assert annotations.length==0; // not designed to work with adapters.
aoqi@0: Type t = (genericType != null)? genericType : type;
aoqi@0: Type base = Utils.REFLECTION_NAVIGATOR.getBaseClass(t, Collection.class);
aoqi@0: if(base==null)
aoqi@0: return this; // not a collection
aoqi@0:
aoqi@0: return new TypeInfo(tagName, Utils.REFLECTION_NAVIGATOR.getTypeArgument(base,0));
aoqi@0: }
aoqi@0:
aoqi@0: public Map properties() {
aoqi@0: return properties;
aoqi@0: }
aoqi@0:
aoqi@0: public boolean isGlobalElement() {
aoqi@0: return isGlobalElement;
aoqi@0: }
aoqi@0:
aoqi@0: public void setGlobalElement(boolean isGlobalElement) {
aoqi@0: this.isGlobalElement = isGlobalElement;
aoqi@0: }
aoqi@0:
aoqi@0: public TypeInfo getParentCollectionType() {
aoqi@0: return parentCollectionType;
aoqi@0: }
aoqi@0:
aoqi@0: public void setParentCollectionType(TypeInfo parentCollectionType) {
aoqi@0: this.parentCollectionType = parentCollectionType;
aoqi@0: }
aoqi@0:
aoqi@0: public boolean isRepeatedElement() {
aoqi@0: return (parentCollectionType != null);
aoqi@0: }
aoqi@0:
aoqi@0: public Type getGenericType() {
aoqi@0: return genericType;
aoqi@0: }
aoqi@0:
aoqi@0: public void setGenericType(Type genericType) {
aoqi@0: this.genericType = genericType;
aoqi@0: }
aoqi@0:
aoqi@0: public boolean isNillable() {
aoqi@0: return nillable;
aoqi@0: }
aoqi@0:
aoqi@0: public void setNillable(boolean nillable) {
aoqi@0: this.nillable = nillable;
aoqi@0: }
aoqi@0:
aoqi@0: public String toString() {
aoqi@0: return new StringBuilder("TypeInfo: Type = ").append(type)
aoqi@0: .append(", tag = ").append(tagName).toString();
aoqi@0: }
aoqi@0:
aoqi@0: public TypeInfo getItemType() {
aoqi@0: // System.out.println("????? TypeInfo " + type);
aoqi@0: if (type instanceof Class && ((Class)type).isArray() && !byte[].class.equals(type)) {
aoqi@0: Type componentType = ((Class)type).getComponentType();
aoqi@0: Type genericComponentType = null;
aoqi@0: if (genericType!= null && genericType instanceof GenericArrayType) {
aoqi@0: GenericArrayType arrayType = (GenericArrayType) type;
aoqi@0: genericComponentType = arrayType.getGenericComponentType();
aoqi@0: componentType = arrayType.getGenericComponentType();
aoqi@0: }
aoqi@0: TypeInfo ti =new TypeInfo(tagName, componentType, annotations);
aoqi@0: if (genericComponentType != null) ti.setGenericType(genericComponentType);
aoqi@0: return ti;
aoqi@0: }
aoqi@0: // if (type instanceof Class && java.util.Collection.class.isAssignableFrom((Class)type)) {
aoqi@0: Type t = (genericType != null)? genericType : type;
aoqi@0: Type base = Utils.REFLECTION_NAVIGATOR.getBaseClass(t, Collection.class);
aoqi@0: if ( base != null) {
aoqi@0: return new TypeInfo(tagName, Utils.REFLECTION_NAVIGATOR.getTypeArgument(base,0), annotations);
aoqi@0: }
aoqi@0: return null;
aoqi@0: }
aoqi@0: }