/* * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package com.sun.xml.internal.bind.v2.model.nav; import java.lang.reflect.MalformedParameterizedTypeException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Arrays; /** * {@link ParameterizedType} implementation. */ class ParameterizedTypeImpl implements ParameterizedType { private Type[] actualTypeArguments; private Class<?> rawType; private Type ownerType; ParameterizedTypeImpl(Class<?> rawType, Type[] actualTypeArguments, Type ownerType) { this.actualTypeArguments = actualTypeArguments; this.rawType = rawType; if (ownerType != null) { this.ownerType = ownerType; } else { this.ownerType = rawType.getDeclaringClass(); } validateConstructorArguments(); } private void validateConstructorArguments() { TypeVariable/*<?>*/[] formals = rawType.getTypeParameters(); // check correct arity of actual type args if (formals.length != actualTypeArguments.length) { throw new MalformedParameterizedTypeException(); } for (int i = 0; i < actualTypeArguments.length; i++) { // check actuals against formals' bounds } } public Type[] getActualTypeArguments() { return actualTypeArguments.clone(); } public Class<?> getRawType() { return rawType; } public Type getOwnerType() { return ownerType; } /* * From the JavaDoc for java.lang.reflect.ParameterizedType * "Instances of classes that implement this interface must * implement an equals() method that equates any two instances * that share the same generic type declaration and have equal * type parameters." */ @Override public boolean equals(Object o) { if (o instanceof ParameterizedType) { // Check that information is equivalent ParameterizedType that = (ParameterizedType) o; if (this == that) return true; Type thatOwner = that.getOwnerType(); Type thatRawType = that.getRawType(); if (false) { // Debugging boolean ownerEquality = (ownerType == null ? thatOwner == null : ownerType.equals(thatOwner)); boolean rawEquality = (rawType == null ? thatRawType == null : rawType.equals(thatRawType)); boolean typeArgEquality = Arrays.equals(actualTypeArguments, // avoid clone that.getActualTypeArguments()); for (Type t : actualTypeArguments) { System.out.printf("\t\t%s%s%n", t, t.getClass()); } System.out.printf("\towner %s\traw %s\ttypeArg %s%n", ownerEquality, rawEquality, typeArgEquality); return ownerEquality && rawEquality && typeArgEquality; } return (ownerType == null ? thatOwner == null : ownerType.equals(thatOwner)) && (rawType == null ? thatRawType == null : rawType.equals(thatRawType)) && Arrays.equals(actualTypeArguments, // avoid clone that.getActualTypeArguments()); } else return false; } @Override public int hashCode() { return Arrays.hashCode(actualTypeArguments) ^ (ownerType == null ? 0 : ownerType.hashCode()) ^ (rawType == null ? 0 : rawType.hashCode()); } public String toString() { StringBuilder sb = new StringBuilder(); if (ownerType != null) { if (ownerType instanceof Class) sb.append(((Class) ownerType).getName()); else sb.append(ownerType.toString()); sb.append("."); if (ownerType instanceof ParameterizedTypeImpl) { // Find simple name of nested type by removing the // shared prefix with owner. sb.append(rawType.getName().replace(((ParameterizedTypeImpl) ownerType).rawType.getName() + "$", "")); } else sb.append(rawType.getName()); } else sb.append(rawType.getName()); if (actualTypeArguments != null && actualTypeArguments.length > 0) { sb.append("<"); boolean first = true; for (Type t : actualTypeArguments) { if (!first) sb.append(", "); if (t instanceof Class) sb.append(((Class) t).getName()); else sb.append(t.toString()); first = false; } sb.append(">"); } return sb.toString(); } }