package bluej.utility;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import bluej.debugger.gentype.ConstructorReflective;
import bluej.debugger.gentype.FieldReflective;
import bluej.debugger.gentype.GenTypeClass;
import bluej.debugger.gentype.GenTypeDeclTpar;
import bluej.debugger.gentype.JavaPrimitiveType;
import bluej.debugger.gentype.JavaType;
import bluej.debugger.gentype.MethodReflective;
import bluej.debugger.gentype.Reflective;


| A reflective for GenTypeClass which uses the standard java reflection API. | | @author Davin McCall | public class JavaReflective extends Reflective{ private Class<?> c; @Override public int hashCode() { return c.hashCode(); } @Override public boolean equals(Object other) { if (other instanceof JavaReflective) { JavaReflective jrOther = (JavaReflective) other; return jrOther.c == c; } return false; } public JavaReflective(Class<?> c) { if (c == null) throw new NullPointerException(); this.c = c; } @Override public String getName() { return c.getName(); } @Override public String getSimpleName() { if (c.isArray()) { return c.getComponentType().getName().replace('$', '.') + "[]"; } else { return c.getName().replace('$', '.'); } } @Override public boolean isInterface() { return c.isInterface(); } @Override public boolean isStatic() { return Modifier.isStatic(c.getModifiers()); } @Override public boolean isPublic() { return Modifier.isPublic(c.getModifiers()); } @Override public boolean isFinal() { return Modifier.isFinal(c.getModifiers()); } @Override public List getTypeParams() { return JavaUtils.getJavaUtils().getTypeParams(c); } @Override public Reflective getArrayOf() { String rname; if (c.isArray()) rname = "[" + c.getName(); else{ rname = "[L" + c.getName() + ";"; } try { ClassLoader cloader = c.getClassLoader(); Class<?> arrClass = Class.forName(rname, false, cloader); return new JavaReflective(arrClass); } catch (ClassNotFoundException cnfe) { } return null; } @Override public Reflective getRelativeClass(String name) { try { ClassLoader cloader = c.getClassLoader(); if (cloader == null) cloader = ClassLoader.getSystemClassLoader(); Class<?> cr = cloader.loadClass(name); return new JavaReflective(cr); } catch (ClassNotFoundException cnfe) { return null; } catch (LinkageError le) { return null; } } @Override public List getSuperTypesR() { List<Reflective> l = new ArrayList<Reflective>(); if (c.isArray()) { Class<?> ct = c.getComponentType(); JavaReflective ctR = new JavaReflective(ct); List<Reflective> componentSuperTypes = ctR.getSuperTypesR(); Iterator<Reflective> i = componentSuperTypes.iterator(); while (i.hasNext()){ JavaReflective componentSuperType = (JavaReflective) i.next(); l.add(componentSuperType.getArrayOf()); } } Class<?> superclass = c.getSuperclass(); if ( superclass != null ) l.add(new JavaReflective(superclass)); Class<?> [] interfaces = c.getInterfaces(); for ( int i = 0; i < interfaces.length; i++ ) { l.add(new JavaReflective(interfaces[i])); } if (superclass == null && interfaces.length == 0 && c.isInterface()) l.add(new JavaReflective(Object.class)); return l; } @Override public List getSuperTypes() { List<GenTypeClass> l = new ArrayList<GenTypeClass>(); if (c.isArray()) { Class<?> ct = c.getComponentType(); JavaReflective ctR = new JavaReflective(ct); List<GenTypeClass> componentSuperTypes = ctR.getSuperTypes(); Iterator<GenTypeClass> i = componentSuperTypes.iterator(); while (i.hasNext()){ GenTypeClass componentSuperType = i.next(); l.add(componentSuperType.getArray()); } } GenTypeClass superclass = null; try { superclass = JavaUtils.getJavaUtils().getSuperclass(c); if ( superclass != null ) { l.add(superclass); } } catch (ClassNotFoundException cnfe) { } GenTypeClass[] interfaces; try { interfaces = JavaUtils.getJavaUtils().getInterfaces(c); for ( int i = 0; i < interfaces.length; i++ ) { l.add(interfaces[i]); } } catch (ClassNotFoundException cnfe) { interfaces = new GenTypeClass[0]; } if (superclass == null && interfaces.length == 0 && c.isInterface()) { l.add(new GenTypeClass(new JavaReflective(Object.class))); } return l; }
| Get the underlying class (as a java.lang.Class object) that this | reflective represents. | public Class getUnderlyingClass() { return c; } @Override public boolean isAssignableFrom(Reflective r) { if (r instanceof JavaReflective) { return c.isAssignableFrom(((JavaReflective)r).getUnderlyingClass()); } else { return false; } } @Override public Map getDeclaredFields() { try { Field [] fields = c.getDeclaredFields(); Map<String,FieldReflective> rmap = new HashMap<String,FieldReflective>(); for (int i = 0; i < fields.length; i++) { try { JavaType fieldType = JavaUtils.getJavaUtils().getFieldType(fields[i]); FieldReflective fref = new FieldReflective(fields[i].getName(), fieldType, fields[i].getModifiers(), this); rmap.put(fields[i].getName(), fref); } catch (ClassNotFoundException cnfe) { } } if (c.isArray()) { rmap.put("length", new FieldReflective("length", JavaPrimitiveType.getInt(), Modifier.PUBLIC | Modifier.FINAL, this)); } return rmap; } catch (LinkageError le) { return Collections.emptyMap(); } } @Override public Map> getDeclaredMethods() { try { Method [] methods = c.getDeclaredMethods(); Map<String,Set<MethodReflective>> rmap = new HashMap<String,Set<MethodReflective>>(); for (Method method : methods) { if (method.isSynthetic()) { continue; } JavaType rtype; try { rtype = JavaUtils.getJavaUtils().getReturnType(method); } catch (ClassNotFoundException cnfe) { rtype = JavaUtils.getJavaUtils().getRawReturnType(method); } List<GenTypeDeclTpar> tpars = JavaUtils.getJavaUtils().getTypeParams(method); Map<String,GenTypeDeclTpar> tparMap = new HashMap<String,GenTypeDeclTpar>(); storeTparMappings(tpars, tparMap); if (! Modifier.isStatic(method.getModifiers())) { getTparMapping(method.getDeclaringClass(), tparMap); } try { JavaType [] paramTypes = JavaUtils.getJavaUtils().getParamGenTypes(method, false); List<JavaType> paramTypesList = new ArrayList<JavaType>(paramTypes.length); for (JavaType paramType : paramTypes) { paramTypesList.add(paramType.mapTparsToTypes(tparMap).getUpperBound()); } rtype = rtype.mapTparsToTypes(tparMap).getUpperBound(); String name = method.getName(); MethodReflective mr = new MethodReflective(name, rtype, tpars, paramTypesList, this, JavaUtils.getJavaUtils().isVarArgs(method), method.getModifiers()); Set<MethodReflective> rset = rmap.get(method.getName()); if (rset == null) { rset = new HashSet<MethodReflective>(); rmap.put(method.getName(), rset); } rset.add(mr); } catch (ClassNotFoundException cnfe) { continue; } } if (c.isArray()) { rmap.put("clone", Collections.singleton(new MethodReflective("clone", new GenTypeClass(new JavaReflective(Object.class)), new ArrayList<GenTypeDeclTpar>(), new ArrayList<JavaType>(), this, false, Modifier.PUBLIC))); } return rmap; } catch (LinkageError le) { return Collections.emptyMap(); } } @Override public List getDeclaredConstructors() { List<ConstructorReflective> r = new ArrayList<>(); try { for (Constructor<?> con : c.getDeclaredConstructors()) { List<GenTypeDeclTpar> tpars = JavaUtils.getJavaUtils().getTypeParams(con); Map<String, GenTypeDeclTpar> tparMap = new HashMap<String, GenTypeDeclTpar>(); storeTparMappings(tpars, tparMap); try { JavaType [] paramTypes = JavaUtils.getJavaUtils().getParamGenTypes(con); List<JavaType> paramTypesList = new ArrayList<JavaType>(paramTypes.length); for (JavaType paramType : paramTypes) { paramTypesList.add(paramType.mapTparsToTypes(tparMap).getUpperBound()); } r.add(new ConstructorReflective(tpars, paramTypesList, this, JavaUtils.getJavaUtils().isVarArgs(con), con.getModifiers())); } catch (ClassNotFoundException exc) { } } } catch (LinkageError | SecurityException exc) { } return r; }
| Store, into the specified map, a mapping from the enclosing method/class/constructor | type parameter names to the corresponding type parameters. Existing entries in the | map are not overwritten. | | @param c The type, whose enclosing entities type parameters are required | @param tparMap The map, into which the mappings from name to type parameter are to be stored | private void getTparMapping(Class<?> c, Map<String,GenTypeDeclTpar> tparMap) { JavaUtils ju = JavaUtils.getJavaUtils(); List<GenTypeDeclTpar> tpars = ju.getTypeParams(c); storeTparMappings(tpars, tparMap); Method m = c.getEnclosingMethod(); Constructor<?> cc = c.getEnclosingConstructor(); c = c.getEnclosingClass(); while (c != null){ if (m != null) { tpars = ju.getTypeParams(m); storeTparMappings(tpars, tparMap); if (! Modifier.isStatic(m.getModifiers())) { c = m.getDeclaringClass(); } m = null; } else if (cc != null) { tpars = ju.getTypeParams(cc); storeTparMappings(tpars, tparMap); c = cc.getDeclaringClass(); cc = null; } if (c != null) { tpars = ju.getTypeParams(c); storeTparMappings(tpars, tparMap); c = c.getEnclosingClass(); if (c != null) { m = c.getEnclosingMethod(); cc = c.getEnclosingConstructor(); } } } }
| Store a set of mappings from type parameter names to the type parameter (GenTypeDeclTpar). | Existing mappings are not overwritten. | | @param tpars The set of type parameters to create mappings for | @param map The map of name to type parameter | private void storeTparMappings(List<GenTypeDeclTpar> tpars, Map<String, ? super GenTypeDeclTpar> map) { for (GenTypeDeclTpar tpar : tpars) { if (! map.containsKey(tpar.getTparName())) { map.put(tpar.getTparName(), tpar); } } } @Override public Reflective getOuterClass() { Class<?> declaring = c.getDeclaringClass(); if (declaring != null) { return new JavaReflective(declaring); } return null; } @Override public Reflective getInnerClass(String name) { try { Class<?> [] declared = c.getDeclaredClasses(); for (Class<?> inner : declared) { String innerName = inner.getName(); int lastDollar = innerName.lastIndexOf('$'); if (lastDollar != -1) { String baseName = innerName.substring(lastDollar + 1); if (baseName.equals(name)) { return new JavaReflective(inner); } } } } catch (LinkageError le) { } return null; } @Override public String getModuleName() { return c.getModule() != null ? c.getModule().getName() : null; } }
top, use, map, class JavaReflective

.   hashCode
.   equals
.   JavaReflective
.   getName
.   getSimpleName
.   isInterface
.   isStatic
.   isPublic
.   isFinal
.   getTypeParams
.   getArrayOf
.   getRelativeClass
.   getSuperTypesR
.   getSuperTypes
.   getUnderlyingClass
.   isAssignableFrom
.   getDeclaredFields
.   getDeclaredMethods
.   getDeclaredConstructors
.   getTparMapping
.   storeTparMappings
.   getOuterClass
.   getInnerClass
.   getModuleName




644 neLoCode + 13 LoComm