tiger-types-1.4/0000755000175000017500000000000011575451470014315 5ustar jamespagejamespagetiger-types-1.4/pom.xml0000644000175000017500000000442111573143475015634 0ustar jamespagejamespage net.java jvnet-parent 1 4.0.0 org.jvnet tiger-types 1.4 Type arithmetic library for Java5 scm:svn:https://svn.java.net/svn/tiger-types~svn/tags/tiger-types-1.4 scm:svn:https://svn.java.net/svn/tiger-types~svn/tags/tiger-types-1.4 http://java.net/projects/tiger-types/sources/svn/show/tags/tiger-types-1.4 maven-compiler-plugin 1.5 1.5 org.apache.maven.plugins maven-idea-plugin 2.2 JDK1.5 true org.apache.maven.plugins maven-release-plugin forked-path false ${release.arguments} junit junit 3.8.1 test maven-javadoc-plugin tiger-types-1.4/src/0000755000175000017500000000000011575451470015104 5ustar jamespagejamespagetiger-types-1.4/src/site/0000755000175000017500000000000011575451470016050 5ustar jamespagejamespagetiger-types-1.4/src/site/apt/0000755000175000017500000000000011575451470016634 5ustar jamespagejamespagetiger-types-1.4/src/site/apt/index.apt0000644000175000017500000000131711102434134020433 0ustar jamespagejamespageWhat is this? This library provides functions that perform type arithemtic over the type system of Java5. For example, you can compute that <<>>> is a sub-type of <<>>> but not <<>>>, you can compute the erasure of <<>>, or you can determine the array component type <<>> from <<>> How to use? If you are using Maven, put the following dependency in your POM: -------------------- org.jvnet tiger-types RELEASE -------------------- Otherwise just download the jar and put that in your classpath. tiger-types-1.4/src/site/site.xml0000644000175000017500000000153210714373636017540 0ustar jamespagejamespage org.jvnet.maven-javanet-skin maven-javanet-skin 1.0 tiger-types-1.4/src/test/0000755000175000017500000000000011575451470016063 5ustar jamespagejamespagetiger-types-1.4/src/test/java/0000755000175000017500000000000011575451470017004 5ustar jamespagejamespagetiger-types-1.4/src/test/java/org/0000755000175000017500000000000011575451470017573 5ustar jamespagejamespagetiger-types-1.4/src/test/java/org/jvnet/0000755000175000017500000000000011575451470020721 5ustar jamespagejamespagetiger-types-1.4/src/test/java/org/jvnet/tiger_types/0000755000175000017500000000000011575451470023257 5ustar jamespagejamespagetiger-types-1.4/src/test/java/org/jvnet/tiger_types/ListerTest.java0000644000175000017500000000110611306261502026205 0ustar jamespagejamespagepackage org.jvnet.tiger_types; import junit.framework.TestCase; import java.net.Proxy.Type; import java.util.EnumSet; import java.util.Set; /** * @author Kohsuke Kawaguchi */ public class ListerTest extends TestCase { public EnumSet set; public void testEnumSet() throws Exception { Lister l = Lister.create(getClass().getDeclaredField("set").getGenericType()); l.add(Type.HTTP); l.add(Type.SOCKS); Set col = (Set)l.toCollection(); assertTrue(col instanceof EnumSet); assertTrue(col.contains(Type.HTTP)); } } tiger-types-1.4/src/main/0000755000175000017500000000000011575451470016030 5ustar jamespagejamespagetiger-types-1.4/src/main/java/0000755000175000017500000000000011575451470016751 5ustar jamespagejamespagetiger-types-1.4/src/main/java/org/0000755000175000017500000000000011575451470017540 5ustar jamespagejamespagetiger-types-1.4/src/main/java/org/jvnet/0000755000175000017500000000000011575451470020666 5ustar jamespagejamespagetiger-types-1.4/src/main/java/org/jvnet/tiger_types/0000755000175000017500000000000011575451470023224 5ustar jamespagejamespagetiger-types-1.4/src/main/java/org/jvnet/tiger_types/WildcardTypeImpl.java0000644000175000017500000000550111455654743027312 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.WildcardType; import java.lang.reflect.Type; import java.util.Arrays; /** * @author Kohsuke Kawaguchi */ final class WildcardTypeImpl implements WildcardType { private final Type[] ub; private final Type[] lb; public WildcardTypeImpl(Type[] ub, Type[] lb) { this.ub = ub; this.lb = lb; } public Type[] getUpperBounds() { return ub; } public Type[] getLowerBounds() { return lb; } public int hashCode() { return Arrays.hashCode(lb) ^ Arrays.hashCode(ub); } public boolean equals(Object obj) { if (obj instanceof WildcardType) { WildcardType that = (WildcardType) obj; return Arrays.equals(that.getLowerBounds(),lb) && Arrays.equals(that.getUpperBounds(),ub); } return false; } } tiger-types-1.4/src/main/java/org/jvnet/tiger_types/TypeVisitor.java0000644000175000017500000000630011455654743026374 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.Type; import java.lang.reflect.ParameterizedType; import java.lang.reflect.GenericArrayType; import java.lang.reflect.WildcardType; import java.lang.reflect.TypeVariable; /** * @author Kohsuke Kawaguchi */ abstract class TypeVisitor { public final T visit( Type t, P param ) { assert t!=null; if (t instanceof Class) return onClass((Class)t,param); if (t instanceof ParameterizedType) return onParameterizdType( (ParameterizedType)t,param); if(t instanceof GenericArrayType) return onGenericArray((GenericArrayType)t,param); if(t instanceof WildcardType) return onWildcard((WildcardType)t,param); if(t instanceof TypeVariable) return onVariable((TypeVariable)t,param); // covered all the cases assert false; throw new IllegalArgumentException(); } protected abstract T onClass(Class c, P param); protected abstract T onParameterizdType(ParameterizedType p, P param); protected abstract T onGenericArray(GenericArrayType g, P param); protected abstract T onVariable(TypeVariable v, P param); protected abstract T onWildcard(WildcardType w, P param); } tiger-types-1.4/src/main/java/org/jvnet/tiger_types/Types.java0000644000175000017500000003472011455654743025206 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; /** * Type arithmetic functions. * * @author Kohsuke Kawaguchi */ public class Types { private static final TypeVisitor baseClassFinder = new TypeVisitor() { public Type onClass(Class c, Class sup) { // t is a raw type if(sup==c) return sup; Type r; Type sc = c.getGenericSuperclass(); if(sc!=null) { r = visit(sc,sup); if(r!=null) return r; } for( Type i : c.getGenericInterfaces() ) { r = visit(i,sup); if(r!=null) return r; } return null; } public Type onParameterizdType(ParameterizedType p, Class sup) { Class raw = (Class) p.getRawType(); if(raw==sup) { // p is of the form sup<...> return p; } else { // recursively visit super class/interfaces Type r = raw.getGenericSuperclass(); if(r!=null) r = visit(bind(r,raw,p),sup); if(r!=null) return r; for( Type i : raw.getGenericInterfaces() ) { r = visit(bind(i,raw,p),sup); if(r!=null) return r; } return null; } } public Type onGenericArray(GenericArrayType g, Class sup) { // not clear what I should do here return null; } public Type onVariable(TypeVariable v, Class sup) { return visit(v.getBounds()[0],sup); } public Type onWildcard(WildcardType w, Class sup) { // not clear what I should do here return null; } /** * Replaces the type variables in {@code t} by its actual arguments. * * @param decl * provides a list of type variables. See {@link GenericDeclaration#getTypeParameters()} * @param args * actual arguments. See {@link ParameterizedType#getActualTypeArguments()} */ private Type bind( Type t, GenericDeclaration decl, ParameterizedType args ) { return binder.visit(t,new BinderArg(decl,args.getActualTypeArguments())); } }; private static class BinderArg { final TypeVariable[] params; final Type[] args; BinderArg(TypeVariable[] params, Type[] args) { this.params = params; this.args = args; assert params.length==args.length; } public BinderArg( GenericDeclaration decl, Type[] args ) { this(decl.getTypeParameters(),args); } Type replace( TypeVariable v ) { for(int i=0; i binder = new TypeVisitor() { public Type onClass(Class c, BinderArg args) { return c; } public Type onParameterizdType(ParameterizedType p, BinderArg args) { Type[] params = p.getActualTypeArguments(); boolean different = false; for( int i=0; i)p.getRawType(), params, newOwner ); } public Type onGenericArray(GenericArrayType g, BinderArg types) { Type c = visit(g.getGenericComponentType(),types); if(c==g.getGenericComponentType()) return g; return new GenericArrayTypeImpl(c); } public Type onVariable(TypeVariable v, BinderArg types) { return types.replace(v); } public Type onWildcard(WildcardType w, BinderArg types) { // TODO: this is probably still incorrect // bind( "? extends T" ) with T= "? extends Foo" should be "? extends Foo", // not "? extends (? extends Foo)" Type[] lb = w.getLowerBounds(); Type[] ub = w.getUpperBounds(); boolean diff = false; for( int i=0; i * For example, given the following *

     * interface Foo<T> extends List<List<T>> {}
     * interface Bar extends Foo<String> {}
     * 
* This method works like this: *

     * getBaseClass( Bar, List ) = List<List<String>
     * getBaseClass( Bar, Foo  ) = Foo<String>
     * getBaseClass( Foo<? extends Number>, Collection ) = Collection<List<? extends Number>>
     * getBaseClass( ArrayList<? extends BigInteger>, List ) = List<? extends BigInteger>
     * 
* * @param type * The type that derives from {@code baseType} * @param baseType * The class whose parameterization we are interested in. * @return * The use of {@code baseType} in {@code type}. * or null if the type is not assignable to the base type. */ public static Type getBaseClass(Type type, Class baseType) { return baseClassFinder.visit(type,baseType); } /** * Gets the display name of the type object * * @return * a human-readable name that the type represents. */ public static String getTypeName(Type type) { if (type instanceof Class) { Class c = (Class) type; if(c.isArray()) return getTypeName(c.getComponentType())+"[]"; return c.getName(); } return type.toString(); } /** * Checks if {@code sub} is a sub-type of {@code sup}. */ public static boolean isSubClassOf(Type sub, Type sup) { return erasure(sup).isAssignableFrom(erasure(sub)); } /** * Implements the logic for {@link #erasure(Type)}. */ private static final TypeVisitor eraser = new TypeVisitor() { public Class onClass(Class c,Void _) { return c; } public Class onParameterizdType(ParameterizedType p,Void _) { // TODO: why getRawType returns Type? not Class? return visit(p.getRawType(),null); } public Class onGenericArray(GenericArrayType g,Void _) { return Array.newInstance( visit(g.getGenericComponentType(),null), 0 ).getClass(); } public Class onVariable(TypeVariable v,Void _) { return visit(v.getBounds()[0],null); } public Class onWildcard(WildcardType w,Void _) { return visit(w.getUpperBounds()[0],null); } }; /** * Returns the {@link Class} representation of the given type. * * This corresponds to the notion of the erasure in JSR-14. * *

* It made me realize how difficult it is to define the common navigation * layer for two different underlying reflection library. The other way * is to throw away the entire parameterization and go to the wrapper approach. */ public static Class erasure(Type t) { return eraser.visit(t,null); } /** * Returns the {@link Type} object that represents {@code clazz<T1,T2,T3>}. */ public static ParameterizedType createParameterizedType( Class rawType, Type... arguments ) { return new ParameterizedTypeImpl(rawType,arguments,null); } /** * Checks if the type is an array type. */ public static boolean isArray(Type t) { if (t instanceof Class) { Class c = (Class) t; return c.isArray(); } if(t instanceof GenericArrayType) return true; return false; } /** * Checks if the type is an array type but not byte[]. */ public static boolean isArrayButNotByteArray(Type t) { if (t instanceof Class) { Class c = (Class) t; return c.isArray() && c!=byte[].class; } if(t instanceof GenericArrayType) { t = ((GenericArrayType)t).getGenericComponentType(); return t!=Byte.TYPE; } return false; } /** * Gets the component type of the array. * * @param t * must be an array. */ public static Type getComponentType(Type t) { if (t instanceof Class) { Class c = (Class) t; return c.getComponentType(); } if(t instanceof GenericArrayType) return ((GenericArrayType)t).getGenericComponentType(); throw new IllegalArgumentException(); } /** * Gets the i-th type argument from a parameterized type. * *

* Unlike {@link #getTypeArgument(Type, int, Type)}, this method * throws {@link IllegalArgumentException} if the given type is * not parameterized. */ public static Type getTypeArgument(Type type, int i) { Type r = getTypeArgument(type, i, null); if(r==null) throw new IllegalArgumentException(); return r; } /** * Gets the i-th type argument from a parameterized type. * *

* For example, {@code getTypeArgument([Map],0)=Integer} * If the given type is not a parameterized type, returns the specified * default value. * *

* This is convenient for handling raw types and parameterized types uniformly. * * @throws IndexOutOfBoundsException * If i is out of range. */ public static Type getTypeArgument(Type type, int i, Type defaultValue) { if (type instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType) type; return fix(p.getActualTypeArguments()[i]); } else return defaultValue; } /** * Checks if the given type is a primitive type. */ public static boolean isPrimitive(Type type) { if (type instanceof Class) { Class c = (Class) type; return c.isPrimitive(); } return false; } public static boolean isOverriding(Method method, Class base) { // this isn't actually correct, // as the JLS considers // class Derived extends Base { // Integer getX() { ... } // } // class Base { // T getX() { ... } // } // to be overrided. Handling this correctly needs a careful implementation String name = method.getName(); Class[] params = method.getParameterTypes(); while(base!=null) { try { if(base.getDeclaredMethod(name,params)!=null) return true; } catch (NoSuchMethodException e) { // recursively go into the base class } base = base.getSuperclass(); } return false; } /** * JDK 5.0 has a bug of createing {@link GenericArrayType} where it shouldn't. * fix that manually to work around the problem. * * See bug 6202725. */ private static Type fix(Type t) { if(!(t instanceof GenericArrayType)) return t; GenericArrayType gat = (GenericArrayType) t; if(gat.getGenericComponentType() instanceof Class) { Class c = (Class) gat.getGenericComponentType(); return Array.newInstance(c,0).getClass(); } return t; } } tiger-types-1.4/src/main/java/org/jvnet/tiger_types/Lister.java0000644000175000017500000001407411455654743025344 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.Array; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.EnumSet; /** * Abstracts away the process of creating a collection (array, {@link List}, etc) * of items. * * @author Kohsuke Kawaguchi */ public abstract class Lister { /** * Type of the individual item */ public final Class itemType; public final Type itemGenericType; protected final Collection r; protected Lister(Class itemType, Type itemGenericType) { this(itemType,itemGenericType,new ArrayList()); } protected Lister(Class itemType, Type itemGenericType, Collection r) { this.itemType = itemType; this.itemGenericType = itemGenericType; this.r = r; } public void add(Object o) { r.add(o); } public abstract T toCollection(); /** * Creates a {@link Lister} instance that produces the given type. */ public static Lister create(Type t) { return create(Types.erasure(t),t); } /** * Creates a {@link Lister} instance that produces the given type. * * @param c * The erasure version of 't'. This is taken * as a parameter as a performance optimizaiton. * * @return * null if the given type doesn't look like a collection. * @throws IllegalArgumentException * if the given type does look like a collection yet this implementation * is not capable of how to handle it. */ public static Lister create(Class c, Type t) { if(c.isArray()) { // array Class ct = c.getComponentType(); return new Lister(ct,ct) { public Object toCollection() { return r.toArray((Object[])Array.newInstance(itemType,r.size())); } }; } if(Collection.class.isAssignableFrom(c)) { final Type col = Types.getBaseClass(t, Collection.class); final Type itemType; if (col instanceof ParameterizedType) itemType = Types.getTypeArgument(col, 0); else itemType = Object.class; Collection items=null; try { items = (Collection)c.newInstance(); } catch (InstantiationException e) { // this is not instanciable. Try known instanciable versions. for (Class ct : CONCRETE_TYPES) { if(c.isAssignableFrom(ct)) { try { items = (Collection)ct.newInstance(); break; } catch (InstantiationException x) { throw toError(x); } catch (IllegalAccessException x) { throw toError(x); } } } // EnumSet if(items==null && c==EnumSet.class) { items = EnumSet.noneOf(Types.erasure(itemType).asSubclass(Enum.class)); } if(items==null) throw new IllegalArgumentException("Don't know how to instanciate "+c); } catch (IllegalAccessException e) { throw toError(e); } return new Lister(Types.erasure(itemType),itemType,items) { public Object toCollection() { return r; } }; } return null; } private static IllegalAccessError toError(IllegalAccessException e) { IllegalAccessError x = new IllegalAccessError(); x.initCause(e); return x; } private static InstantiationError toError(InstantiationException e) { InstantiationError x = new InstantiationError(); x.initCause(e); return x; } private static final Class[] CONCRETE_TYPES = new Class[] { ArrayList.class, HashSet.class }; } tiger-types-1.4/src/main/java/org/jvnet/tiger_types/GenericArrayTypeImpl.java0000644000175000017500000000670311455654743030141 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Type; /** * Implementation of GenericArrayType interface for core reflection. */ final class GenericArrayTypeImpl implements GenericArrayType { private Type genericComponentType; GenericArrayTypeImpl(Type ct) { assert ct!=null; genericComponentType = ct; } /** * Returns a Type object representing the component type * of this array. * * @return a Type object representing the component type * of this array * @since 1.5 */ public Type getGenericComponentType() { return genericComponentType; // return cached component type } public String toString() { Type componentType = getGenericComponentType(); StringBuilder sb = new StringBuilder(); if (componentType instanceof Class) sb.append(((Class) componentType).getName()); else sb.append(componentType.toString()); sb.append("[]"); return sb.toString(); } @Override public boolean equals(Object o) { if (o instanceof GenericArrayType) { GenericArrayType that = (GenericArrayType) o; Type thatComponentType = that.getGenericComponentType(); return genericComponentType.equals(thatComponentType); } else return false; } @Override public int hashCode() { return genericComponentType.hashCode(); } } tiger-types-1.4/src/main/java/org/jvnet/tiger_types/ParameterizedTypeImpl.java0000644000175000017500000001566311455654743030367 0ustar jamespagejamespage/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.jvnet.tiger_types; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.MalformedParameterizedTypeException; import java.util.Arrays; /** * {@link ParameterizedType} implementation. */ final 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(); } }