/* | 
|
 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. 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.  Oracle designates this | 
|
 * particular file as subject to the "Classpath" exception as provided | 
|
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|
 * or visit www.oracle.com if you need additional information or have any | 
|
 * questions. | 
|
*/  | 
|
package com.sun.beans;  | 
|
import java.lang.reflect.Type;  | 
|
import java.lang.reflect.WildcardType;  | 
|
import java.util.Arrays;  | 
|
/** | 
|
 * This class implements {@link WildcardType WildcardType} compatibly with the JDK's | 
|
 * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | 
|
 * Unfortunately we can't use the JDK's | 
|
 * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl} here as we do for | 
|
 * {@link sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl ParameterizedTypeImpl} and | 
|
 * {@link sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl GenericArrayTypeImpl}, | 
|
 * because {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}'s | 
|
 * constructor takes parameters representing intermediate structures obtained during class-file parsing. | 
|
 * We could reconstruct versions of those structures but it would be more trouble than it's worth. | 
|
 * | 
|
 * @since 1.7 | 
|
 * | 
|
 * @author Eamonn McManus | 
|
 * @author Sergey Malenkov | 
|
*/  | 
|
final class WildcardTypeImpl implements WildcardType {  | 
|
private final Type[] upperBounds;  | 
|
private final Type[] lowerBounds;  | 
|
    /** | 
|
     * Creates a wildcard type with the requested bounds. | 
|
     * Note that the array arguments are not cloned | 
|
     * because instances of this class are never constructed | 
|
     * from outside the containing package. | 
|
     * | 
|
     * @param upperBounds  the array of types representing | 
|
     *                     the upper bound(s) of this type variable | 
|
     * @param lowerBounds  the array of types representing | 
|
     *                     the lower bound(s) of this type variable | 
|
*/  | 
|
WildcardTypeImpl(Type[] upperBounds, Type[] lowerBounds) {  | 
|
this.upperBounds = upperBounds;  | 
|
this.lowerBounds = lowerBounds;  | 
|
}  | 
|
    /** | 
|
     * Returns an array of {@link Type Type} objects | 
|
     * representing the upper bound(s) of this type variable. | 
|
     * Note that if no upper bound is explicitly declared, | 
|
     * the upper bound is {@link Object Object}. | 
|
     * | 
|
     * @return an array of types representing | 
|
     *         the upper bound(s) of this type variable | 
|
*/  | 
|
public Type[] getUpperBounds() {  | 
|
return this.upperBounds.clone();  | 
|
}  | 
|
    /** | 
|
     * Returns an array of {@link Type Type} objects | 
|
     * representing the lower bound(s) of this type variable. | 
|
     * Note that if no lower bound is explicitly declared, | 
|
     * the lower bound is the type of {@code null}. | 
|
     * In this case, a zero length array is returned. | 
|
     * | 
|
     * @return an array of types representing | 
|
     *         the lower bound(s) of this type variable | 
|
*/  | 
|
public Type[] getLowerBounds() {  | 
|
return this.lowerBounds.clone();  | 
|
}  | 
|
    /** | 
|
     * Indicates whether some other object is "equal to" this one. | 
|
     * It is implemented compatibly with the JDK's | 
|
     * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | 
|
     * | 
|
     * @param object  the reference object with which to compare | 
|
     * @return {@code true} if this object is the same as the object argument; | 
|
     *         {@code false} otherwise | 
|
     * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#equals | 
|
*/  | 
|
@Override  | 
|
public boolean equals(Object object) {  | 
|
if (object instanceof WildcardType) {  | 
|
WildcardType type = (WildcardType) object;  | 
|
return Arrays.equals(this.upperBounds, type.getUpperBounds())  | 
|
&& Arrays.equals(this.lowerBounds, type.getLowerBounds());  | 
|
}  | 
|
return false;  | 
|
}  | 
|
    /** | 
|
     * Returns a hash code value for the object. | 
|
     * It is implemented compatibly with the JDK's | 
|
     * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | 
|
     * | 
|
     * @return a hash code value for this object | 
|
     * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#hashCode | 
|
*/  | 
|
@Override  | 
|
    public int hashCode() { | 
|
return Arrays.hashCode(this.upperBounds)  | 
|
^ Arrays.hashCode(this.lowerBounds);  | 
|
}  | 
|
    /** | 
|
     * Returns a string representation of the object. | 
|
     * It is implemented compatibly with the JDK's | 
|
     * {@link sun.reflect.generics.reflectiveObjects.WildcardTypeImpl WildcardTypeImpl}. | 
|
     * | 
|
     * @return a string representation of the object | 
|
     * @see sun.reflect.generics.reflectiveObjects.WildcardTypeImpl#toString | 
|
*/  | 
|
@Override  | 
|
public String toString() {  | 
|
StringBuilder sb;  | 
|
Type[] bounds;  | 
|
        if (this.lowerBounds.length == 0) { | 
|
if (this.upperBounds.length == 0 || Object.class == this.upperBounds[0]) {  | 
|
                return "?"; | 
|
}  | 
|
bounds = this.upperBounds;  | 
|
sb = new StringBuilder("? extends ");  | 
|
}  | 
|
        else { | 
|
bounds = this.lowerBounds;  | 
|
sb = new StringBuilder("? super ");  | 
|
}  | 
|
for (int i = 0; i < bounds.length; i++) {  | 
|
if (i > 0) {  | 
|
sb.append(" & ");  | 
|
}  | 
|
sb.append((bounds[i] instanceof Class)  | 
|
? ((Class) bounds[i]).getName()  | 
|
: bounds[i].toString());  | 
|
}  | 
|
return sb.toString();  | 
|
}  | 
|
}  |