package gw.lang.ir.builder; import gw.lang.ir.IRType; import gw.lang.GosuShop; import gw.lang.UnstableAPI; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.java.IJavaClassInfo; import java.util.List; import java.util.ArrayList; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.Constructor; /** * NOTE: This class is currently not a fixed part of the API and may change in future releases. * * Copyright 2010 Guidewire Software, Inc. */ @UnstableAPI public abstract class IRElementBuilder { // ------------------------ Protected Helper Methods protected static IRType getIRType( Class cls ) { return GosuShop.getIRTypeResolver().getDescriptor( cls ); } protected static IRType getIRType( IType type ) { return GosuShop.getIRTypeResolver().getDescriptor( type ); } protected static IRType getIRType( IJavaClassInfo cls ) { return GosuShop.getIRTypeResolver().getDescriptor( cls ); } protected static List<IRType> getIRTypes( Class[] classes ) { List<IRType> results = new ArrayList<IRType>(); for (Class cls : classes) { results.add( getIRType( cls ) ); } return results; } // ------------------------ Constructor Resolution protected static Constructor findConstructor( Class cls, int numArgs ) { Constructor match = null; for (Constructor cons : cls.getDeclaredConstructors()) { if (cons.getParameterTypes().length == numArgs) { if (match != null) { throw new IllegalArgumentException("The call to create a new " + cls + " with " + numArgs + " arguments is ambiguous"); } else { match = cons; } } } if (match == null) { throw new IllegalArgumentException("No constructor with " + numArgs + " arguments found on class " + cls); } return match; } // ------------------------ Method Resolution protected static Method findMethod( Class cls, String name, int numArgs ) { Method match = findUniqueMethodInList( cls.getMethods(), cls, name, numArgs ); if (match != null) { return match; } match = findDeclaredMethod( cls, name, numArgs ); if (match != null) { return match; } if ( name.equals("toString") || name.equals("equals") || name.equals("hashCode")) { return findMethod( Object.class, name, numArgs ); } throw new IllegalArgumentException("No method named " + name + " with " + numArgs + " arguments found starting from class " + cls); } private static Method findDeclaredMethod( Class cls, String name, int numArgs ) { Method match = findUniqueMethodInList( TypeSystem.getDeclaredMethods( cls ), cls, name, numArgs ); if (match != null) { return match; } if ( cls.getSuperclass() != null ) { return findDeclaredMethod( cls.getSuperclass(), name, numArgs ); } return null; } private static Method findUniqueMethodInList( Method[] methods, Class cls, String name, int numArgs ) { Method match = null; for (Method m : methods) { if (m.getName().equals(name) && m.getParameterTypes().length == numArgs) { if (match != null) { throw new IllegalArgumentException("The call to method " + name + " on class " + cls.getName() + " with " + numArgs + " arguments is ambiguous"); } match = m; } } return match; } // ------------------------- Field Resolution protected static Field findField( Class cls, String name ) { Field[] allFields = cls.getFields(); for (Field f : allFields) { if (f.getName().equals(name)) { return f; } } Field match = findDeclaredField( cls, name ); if ( match != null ) { return match; } throw new IllegalArgumentException("No field named " + name + " found starting from class " + cls); } private static Field findDeclaredField( Class cls, String name ) { Field[] declaredFields = cls.getDeclaredFields(); for (Field f : declaredFields) { if (f.getName().equals(name)) { return f; } } if ( cls.getSuperclass() != null ) { return findDeclaredField( cls.getSuperclass(), name ); } return null; } }