001 /* 002 Galois, a framework to exploit amorphous data-parallelism in irregular 003 programs. 004 005 Copyright (C) 2010, The University of Texas at Austin. All rights reserved. 006 UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS SOFTWARE 007 AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR ANY 008 PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF PERFORMANCE, AND ANY 009 WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF TRADE. 010 NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO THE USE OF THE 011 SOFTWARE OR DOCUMENTATION. Under no circumstances shall University be liable 012 for incidental, special, indirect, direct or consequential damages or loss of 013 profits, interruption of business, or related expenses which may arise from use 014 of Software or Documentation, including but not limited to those resulting from 015 defects in Software and/or Documentation, or loss or inaccuracy of data of any 016 kind. 017 018 File: Reflection.java 019 020 */ 021 022 023 024 package util; 025 026 import java.lang.annotation.Annotation; 027 import java.lang.reflect.InvocationTargetException; 028 import java.lang.reflect.Method; 029 import java.util.ArrayList; 030 import java.util.Arrays; 031 import java.util.List; 032 033 /** 034 * Helper methods for the package java.lang.reflect 035 */ 036 public class Reflection { 037 /** 038 * Tests whether the package a class belongs to contains a given annotation. 039 * Annotations in packages are not automatically added by the compiler to the classes 040 * belonging to the package. 041 * 042 * @param className the fully qualified name of the class 043 * @param annotationClass annotation in question 044 * @return true if the package to which the class belongs has been marked with 045 * the given annotation. 046 */ 047 public static boolean packageContainsAnnotation(String className, Class<? extends Annotation> annotationClass) { 048 return getPackageAnnotation(className, annotationClass) != null; 049 } 050 051 public static <A extends Annotation> A getPackageAnnotation(String className, Class<A> annotationClass) { 052 Class<?> classClass = null; 053 try { 054 classClass = Class.forName(className); 055 } catch (ClassNotFoundException e) { 056 throw new RuntimeException(e); 057 } 058 Package classPackage = Package.getPackage(classClass.getPackage().getName()); 059 return classPackage.getAnnotation(annotationClass); 060 } 061 062 public static boolean containsAnnotation(String className, Class<? extends Annotation> annotationClass) { 063 return getAnnotation(className, annotationClass) != null; 064 } 065 066 public static <A extends Annotation> A getAnnotation(String className, Class<A> annotationClass) { 067 Class<?> classClass = null; 068 try { 069 classClass = Class.forName(className); 070 } catch (ClassNotFoundException e) { 071 throw new RuntimeException(e); 072 } 073 return (A) classClass.getAnnotation(annotationClass); 074 } 075 076 /** 077 * Creates an object of the given class, using the default constructor 078 * 079 * @param className the fully qualified name of the class 080 * @return an instance of the class 081 */ 082 public static Object createObject(String className) { 083 Object object = null; 084 try { 085 Class<?> classDefinition = Class.forName(className); 086 object = classDefinition.newInstance(); 087 } catch (Exception ex) { 088 throw new RuntimeException(ex); 089 } 090 return object; 091 } 092 093 /** 094 * Invokes a instance method (of any visibility) of a given object. 095 * If there is more than one method with the given name in the class 096 * the instance belongs to, we invoke any of them in a non-deterministic 097 * fashion. 098 * 099 * @param o object in which to invoke the given method 100 * @param methodName the name of the method to invoke 101 * @param params actual parameters 102 * @return Object return value of callee 103 */ 104 public static Object invokeMethod(Object o, String methodName, Object[] params) { 105 String className = o.getClass().getName(); 106 List<Object> actualParams = new ArrayList<Object>(Arrays.asList(params)); 107 actualParams.add(0, o); 108 return invokeStaticMethod(className, methodName, actualParams.toArray()); 109 } 110 111 /** 112 * Invokes a static method (of any visibility) of a given class. 113 * If there is more than one static method with the given name in the class, 114 * we invoke one of them in non-deterministic fashion. 115 * 116 * @param className the fully qualified name of the class 117 * @param methodName the name of the method to invoke 118 * @param params actual parameters 119 * @return Object return value of callee 120 */ 121 public static Object invokeStaticMethod(String className, String methodName, Object[] params) { 122 Class<?> c = null; 123 try { 124 c = Class.forName(className); 125 } catch (ClassNotFoundException e) { 126 throw new RuntimeException(e); 127 } 128 final Method methods[] = c.getDeclaredMethods(); 129 for (Method method : methods) { 130 if (methodName.equals(method.getName())) { 131 try { 132 method.setAccessible(true); 133 return method.invoke(null, params); 134 } catch (IllegalAccessException ex) { 135 throw new RuntimeException(ex); 136 } catch (InvocationTargetException ite) { 137 throw new RuntimeException(ite); 138 } 139 } 140 } 141 throw new RuntimeException("Method '" + methodName + "' not found"); 142 } 143 }