1 package groovy.inspect; 2 3 import groovy.lang.GroovyObject; 4 import groovy.lang.MetaClass; 5 import groovy.lang.MetaMethod; 6 import groovy.lang.PropertyValue; 7 8 import java.lang.reflect.Modifier ; 9 import java.lang.reflect.Method ; 10 import java.lang.reflect.Field ; 11 import java.lang.reflect.Constructor ; 12 import java.util.*; 13 14 import org.codehaus.groovy.runtime.InvokerHelper; 15 import org.codehaus.groovy.runtime.DefaultGroovyMethods; 16 17 23 public class Inspector { 24 protected Object objectUnderInspection = null; 25 26 public static final int CLASS_PACKAGE_IDX = 0; 28 public static final int CLASS_CLASS_IDX = 1; 29 public static final int CLASS_INTERFACE_IDX = 2; 30 public static final int CLASS_SUPERCLASS_IDX = 3; 31 public static final int CLASS_OTHER_IDX = 4; 32 33 public static final int MEMBER_ORIGIN_IDX = 0; 35 public static final int MEMBER_MODIFIER_IDX = 1; 36 public static final int MEMBER_DECLARER_IDX = 2; 37 public static final int MEMBER_TYPE_IDX = 3; 38 public static final int MEMBER_NAME_IDX = 4; 39 public static final int MEMBER_PARAMS_IDX = 5; 40 public static final int MEMBER_VALUE_IDX = 5; 41 public static final int MEMBER_EXCEPTIONS_IDX = 6; 42 43 public static final String NOT_APPLICABLE = "n/a"; 44 public static final String GROOVY = "GROOVY"; 45 public static final String JAVA = "JAVA"; 46 47 50 public Inspector(Object objectUnderInspection) { 51 if (null == objectUnderInspection){ 52 throw new IllegalArgumentException ("argument must not be null"); 53 } 54 this.objectUnderInspection = objectUnderInspection; 55 } 56 57 61 public String [] getClassProps() { 62 String [] result = new String [CLASS_OTHER_IDX+1]; 63 result[CLASS_PACKAGE_IDX] = "package "+ getClassUnderInspection().getPackage().getName(); 64 String modifiers = Modifier.toString(getClassUnderInspection().getModifiers()); 65 String classOrInterface = "class"; 66 if (getClassUnderInspection().isInterface()){ 67 classOrInterface = "interface"; 68 } 69 result[CLASS_CLASS_IDX] = modifiers + " "+ classOrInterface+" "+ shortName(getClassUnderInspection()); 70 result[CLASS_INTERFACE_IDX] = "implements "; 71 Class [] interfaces = getClassUnderInspection().getInterfaces(); 72 for (int i = 0; i < interfaces.length; i++) { 73 result[CLASS_INTERFACE_IDX] += shortName(interfaces[i])+ " "; 74 } 75 result[CLASS_SUPERCLASS_IDX] = "extends " + shortName(getClassUnderInspection().getSuperclass()); 76 result[CLASS_OTHER_IDX] = "is Primitive: "+getClassUnderInspection().isPrimitive() 77 +", is Array: " +getClassUnderInspection().isArray() 78 +", is Groovy: " + isGroovy(); 79 return result; 80 } 81 82 public boolean isGroovy() { 83 return getClassUnderInspection().isAssignableFrom(GroovyObject.class); 84 } 85 86 90 public Object [] getMethods(){ 91 Method[] methods = getClassUnderInspection().getMethods(); 92 Constructor [] ctors = getClassUnderInspection().getConstructors(); 93 Object [] result = new Object [methods.length + ctors.length]; 94 int resultIndex = 0; 95 for (; resultIndex < methods.length; resultIndex++) { 96 Method method = methods[resultIndex]; 97 result[resultIndex] = methodInfo(method); 98 } 99 for (int i = 0; i < ctors.length; i++, resultIndex++) { 100 Constructor ctor = ctors[i]; 101 result[resultIndex] = methodInfo(ctor); 102 } 103 return result; 104 } 105 109 public Object [] getMetaMethods(){ 110 MetaClass metaClass = InvokerHelper.getMetaClass(objectUnderInspection); 111 List metaMethods = metaClass.getMetaMethods(); 112 Object [] result = new Object [metaMethods.size()]; 113 int i=0; 114 for (Iterator iter = metaMethods.iterator(); iter.hasNext(); i++) { 115 MetaMethod metaMethod = (MetaMethod) iter.next(); 116 result[i] = methodInfo(metaMethod); 117 } 118 return result; 119 } 120 124 public Object [] getPublicFields(){ 125 Field [] fields = getClassUnderInspection().getFields(); 126 Object [] result = new Object [fields.length]; 127 for (int i = 0; i < fields.length; i++) { 128 Field field = fields[i]; 129 result[i] = fieldInfo(field); 130 } 131 return result; 132 } 133 137 public Object [] getProperties(){ 138 List props = DefaultGroovyMethods.allProperties(objectUnderInspection); 139 Object [] result = new Object [props.size()]; 140 int i=0; 141 for (Iterator iter = props.iterator(); iter.hasNext(); i++) { 142 PropertyValue pv = (PropertyValue) iter.next(); 143 result[i] = fieldInfo(pv); 144 } 145 return result; 146 } 147 148 protected String [] fieldInfo(Field field) { 149 String [] result = new String [MEMBER_VALUE_IDX+1]; 150 result[MEMBER_ORIGIN_IDX] = JAVA; 151 result[MEMBER_MODIFIER_IDX] = Modifier.toString(field.getModifiers()); 152 result[MEMBER_DECLARER_IDX] = shortName(field.getDeclaringClass()); 153 result[MEMBER_TYPE_IDX] = shortName(field.getType()); 154 result[MEMBER_NAME_IDX] = field.getName(); 155 try { 156 result[MEMBER_VALUE_IDX] = field.get(objectUnderInspection).toString(); 157 } catch (IllegalAccessException e) { 158 result[MEMBER_VALUE_IDX] = NOT_APPLICABLE; 159 } 160 return withoutNulls(result); 161 } 162 protected String [] fieldInfo(PropertyValue pv) { 163 String [] result = new String [MEMBER_VALUE_IDX+1]; 164 result[MEMBER_ORIGIN_IDX] = GROOVY; 165 result[MEMBER_MODIFIER_IDX] = "public"; 166 result[MEMBER_DECLARER_IDX] = NOT_APPLICABLE; 167 result[MEMBER_TYPE_IDX] = shortName(pv.getType()); 168 result[MEMBER_NAME_IDX] = pv.getName(); 169 try { 170 result[MEMBER_VALUE_IDX] = pv.getValue().toString(); 171 } catch (Exception e) { 172 result[MEMBER_VALUE_IDX] = NOT_APPLICABLE; 173 } 174 return withoutNulls(result); 175 } 176 177 protected Class getClassUnderInspection() { 178 return objectUnderInspection.getClass(); 179 } 180 181 public static String shortName(Class clazz){ 182 if (null == clazz) return NOT_APPLICABLE; 183 String className = clazz.getName(); 184 if (null == clazz.getPackage()) return className; 185 String packageName = clazz.getPackage().getName(); 186 int offset = packageName.length(); 187 if (offset > 0) offset++; 188 className = className.substring(offset); 189 return className; 190 } 191 192 protected String [] methodInfo(Method method){ 193 String [] result = new String [MEMBER_EXCEPTIONS_IDX+1]; 194 int mod = method.getModifiers(); 195 result[MEMBER_ORIGIN_IDX] = JAVA; 196 result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod); 197 result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass()); 198 result[MEMBER_TYPE_IDX] = shortName(method.getReturnType()); 199 result[MEMBER_NAME_IDX] = method.getName(); 200 Class [] params = method.getParameterTypes(); 201 StringBuffer sb = new StringBuffer (); 202 for (int j = 0; j < params.length; j++) { 203 sb.append(shortName(params[j])); 204 if (j < (params.length - 1)) sb.append(", "); 205 } 206 result[MEMBER_PARAMS_IDX] = sb.toString(); 207 sb.setLength(0); 208 Class [] exceptions = method.getExceptionTypes(); 209 for (int k = 0; k < exceptions.length; k++) { 210 sb.append(shortName(exceptions[k])); 211 if (k < (exceptions.length - 1)) sb.append(", "); 212 } 213 result[MEMBER_EXCEPTIONS_IDX] = sb.toString(); 214 return withoutNulls(result); 215 } 216 protected String [] methodInfo(Constructor ctor){ 217 String [] result = new String [MEMBER_EXCEPTIONS_IDX+1]; 218 int mod = ctor.getModifiers(); 219 result[MEMBER_ORIGIN_IDX] = JAVA; 220 result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod); 221 result[MEMBER_DECLARER_IDX] = shortName(ctor.getDeclaringClass()); 222 result[MEMBER_TYPE_IDX] = shortName(ctor.getDeclaringClass()); 223 result[MEMBER_NAME_IDX] = ctor.getName(); 224 Class [] params = ctor.getParameterTypes(); 225 StringBuffer sb = new StringBuffer (); 226 for (int j = 0; j < params.length; j++) { 227 sb.append(shortName(params[j])); 228 if (j < (params.length - 1)) sb.append(", "); 229 } 230 result[MEMBER_PARAMS_IDX] = sb.toString(); 231 sb.setLength(0); 232 Class [] exceptions = ctor.getExceptionTypes(); 233 for (int k = 0; k < exceptions.length; k++) { 234 sb.append(shortName(exceptions[k])); 235 if (k < (exceptions.length - 1)) sb.append(", "); 236 } 237 result[MEMBER_EXCEPTIONS_IDX] = sb.toString(); 238 return withoutNulls(result); 239 } 240 protected String [] methodInfo(MetaMethod method){ 241 String [] result = new String [MEMBER_EXCEPTIONS_IDX+1]; 242 int mod = method.getModifiers(); 243 result[MEMBER_ORIGIN_IDX] = GROOVY; 244 result[MEMBER_MODIFIER_IDX] = Modifier.toString(mod); 245 result[MEMBER_DECLARER_IDX] = shortName(method.getDeclaringClass()); 246 result[MEMBER_TYPE_IDX] = shortName(method.getReturnType()); 247 result[MEMBER_NAME_IDX] = method.getName(); 248 Class [] params = method.getParameterTypes(); 249 StringBuffer sb = new StringBuffer (); 250 for (int j = 0; j < params.length; j++) { 251 sb.append(shortName(params[j])); 252 if (j < (params.length - 1)) sb.append(", "); 253 } 254 result[MEMBER_PARAMS_IDX] = sb.toString(); 255 result[MEMBER_EXCEPTIONS_IDX] = NOT_APPLICABLE; return withoutNulls(result); 257 } 258 259 protected String [] withoutNulls(String [] toNormalize){ 260 for (int i = 0; i < toNormalize.length; i++) { 261 String s = toNormalize[i]; 262 if (null == s) toNormalize[i] = NOT_APPLICABLE; 263 } 264 return toNormalize; 265 } 266 267 public static void print(Object [] memberInfo) { 268 for (int i = 0; i < memberInfo.length; i++) { 269 String [] metaMethod = (String []) memberInfo[i]; 270 System.out.print(i+":\t"); 271 for (int j = 0; j < metaMethod.length; j++) { 272 String s = metaMethod[j]; 273 System.out.print(s+" "); 274 } 275 System.out.println(""); 276 } 277 } 278 public static Object [] sort(Object [] memberInfo) { 279 Arrays.sort(memberInfo, new MemberComparator()); 280 return memberInfo; 281 } 282 283 public static class MemberComparator implements Comparator { 284 public int compare(Object a, Object b) { 285 String [] aStr = (String []) a; 286 String [] bStr = (String []) b; 287 int result = aStr[Inspector.MEMBER_NAME_IDX].compareTo(bStr[Inspector.MEMBER_NAME_IDX]); 288 if (0 != result) return result; 289 result = aStr[Inspector.MEMBER_TYPE_IDX].compareTo(bStr[Inspector.MEMBER_TYPE_IDX]); 290 if (0 != result) return result; 291 result = aStr[Inspector.MEMBER_PARAMS_IDX].compareTo(bStr[Inspector.MEMBER_PARAMS_IDX]); 292 if (0 != result) return result; 293 result = aStr[Inspector.MEMBER_DECLARER_IDX].compareTo(bStr[Inspector.MEMBER_DECLARER_IDX]); 294 if (0 != result) return result; 295 result = aStr[Inspector.MEMBER_MODIFIER_IDX].compareTo(bStr[Inspector.MEMBER_MODIFIER_IDX]); 296 if (0 != result) return result; 297 result = aStr[Inspector.MEMBER_ORIGIN_IDX].compareTo(bStr[Inspector.MEMBER_ORIGIN_IDX]); 298 return result; 299 } 300 } 301 } 302 | Popular Tags |