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.xml.internal.bind.v2.model.nav;
027:
028: import java.lang.reflect.MalformedParameterizedTypeException;
029: import java.lang.reflect.ParameterizedType;
030: import java.lang.reflect.Type;
031: import java.lang.reflect.TypeVariable;
032: import java.util.Arrays;
033:
034: /**
035: * {@link ParameterizedType} implementation.
036: */
037: class ParameterizedTypeImpl implements ParameterizedType {
038: private Type[] actualTypeArguments;
039: private Class<?> rawType;
040: private Type ownerType;
041:
042: ParameterizedTypeImpl(Class<?> rawType, Type[] actualTypeArguments,
043: Type ownerType) {
044: this .actualTypeArguments = actualTypeArguments;
045: this .rawType = rawType;
046: if (ownerType != null) {
047: this .ownerType = ownerType;
048: } else {
049: this .ownerType = rawType.getDeclaringClass();
050: }
051: validateConstructorArguments();
052: }
053:
054: private void validateConstructorArguments() {
055: TypeVariable/*<?>*/[] formals = rawType.getTypeParameters();
056: // check correct arity of actual type args
057: if (formals.length != actualTypeArguments.length) {
058: throw new MalformedParameterizedTypeException();
059: }
060: for (int i = 0; i < actualTypeArguments.length; i++) {
061: // check actuals against formals' bounds
062: }
063:
064: }
065:
066: public Type[] getActualTypeArguments() {
067: return actualTypeArguments.clone();
068: }
069:
070: public Class<?> getRawType() {
071: return rawType;
072: }
073:
074: public Type getOwnerType() {
075: return ownerType;
076: }
077:
078: /*
079: * From the JavaDoc for java.lang.reflect.ParameterizedType
080: * "Instances of classes that implement this interface must
081: * implement an equals() method that equates any two instances
082: * that share the same generic type declaration and have equal
083: * type parameters."
084: */
085: @Override
086: public boolean equals(Object o) {
087: if (o instanceof ParameterizedType) {
088: // Check that information is equivalent
089: ParameterizedType that = (ParameterizedType) o;
090:
091: if (this == that)
092: return true;
093:
094: Type thatOwner = that.getOwnerType();
095: Type thatRawType = that.getRawType();
096:
097: if (false) { // Debugging
098: boolean ownerEquality = (ownerType == null ? thatOwner == null
099: : ownerType.equals(thatOwner));
100: boolean rawEquality = (rawType == null ? thatRawType == null
101: : rawType.equals(thatRawType));
102:
103: boolean typeArgEquality = Arrays.equals(
104: actualTypeArguments, // avoid clone
105: that.getActualTypeArguments());
106: for (Type t : actualTypeArguments) {
107: System.out.printf("\t\t%s%s%n", t, t.getClass());
108: }
109:
110: System.out.printf("\towner %s\traw %s\ttypeArg %s%n",
111: ownerEquality, rawEquality, typeArgEquality);
112: return ownerEquality && rawEquality && typeArgEquality;
113: }
114:
115: return (ownerType == null ? thatOwner == null : ownerType
116: .equals(thatOwner))
117: && (rawType == null ? thatRawType == null : rawType
118: .equals(thatRawType))
119: && Arrays.equals(actualTypeArguments, // avoid clone
120: that.getActualTypeArguments());
121: } else
122: return false;
123: }
124:
125: @Override
126: public int hashCode() {
127: return Arrays.hashCode(actualTypeArguments)
128: ^ (ownerType == null ? 0 : ownerType.hashCode())
129: ^ (rawType == null ? 0 : rawType.hashCode());
130: }
131:
132: public String toString() {
133: StringBuilder sb = new StringBuilder();
134:
135: if (ownerType != null) {
136: if (ownerType instanceof Class)
137: sb.append(((Class) ownerType).getName());
138: else
139: sb.append(ownerType.toString());
140:
141: sb.append(".");
142:
143: if (ownerType instanceof ParameterizedTypeImpl) {
144: // Find simple name of nested type by removing the
145: // shared prefix with owner.
146: sb.append(rawType.getName().replace(
147: ((ParameterizedTypeImpl) ownerType).rawType
148: .getName()
149: + "$", ""));
150: } else
151: sb.append(rawType.getName());
152: } else
153: sb.append(rawType.getName());
154:
155: if (actualTypeArguments != null
156: && actualTypeArguments.length > 0) {
157: sb.append("<");
158: boolean first = true;
159: for (Type t : actualTypeArguments) {
160: if (!first)
161: sb.append(", ");
162: if (t instanceof Class)
163: sb.append(((Class) t).getName());
164: else
165: sb.append(t.toString());
166: first = false;
167: }
168: sb.append(">");
169: }
170:
171: return sb.toString();
172: }
173: }
|