1 package net.sf.crispy.util;
2
3 import java.lang.reflect.Method;
4 import java.security.AccessController;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Vector;
10
11
12 /**
13 * Work with reflection API.
14 *
15 * @author Linke
16 *
17 */
18 public final class Invoker {
19
20 private Invoker() { super(); }
21
22 private static Map compatibleTypes = new HashMap();
23
24 /**
25 * Invoke method from pvObject with the method-name (pvMethodName) and parameter (pvPrams) via reflection.
26 * @param pvObject object for the method call
27 * @param pvMethodName name of method
28 * @param pvParams parameter for method
29 * @return the return value from the method call
30 * @throws Exception
31 */
32 public static Object invokeWithConverter (Object pvObject, String pvMethodName, Vector pvParams, Converter pvConverter) throws Exception {
33 return invoke (pvObject, pvMethodName, pvParams, true, pvConverter);
34 }
35
36 public static Object invoke (String pvClassName, String pvMethodName, Vector pvParams, boolean pvWithConverter, Converter pvConverter) throws Exception {
37 Class lvClass = Class.forName(pvClassName);
38 Object lvObject = lvClass.newInstance();
39 return invoke (lvObject, pvMethodName, pvParams, pvWithConverter, pvConverter);
40 }
41
42 public static Object invoke (Object pvObject, String pvMethodName, Vector pvParams, boolean pvWithConverter, Converter pvConverter) throws Exception {
43 Class clazz = pvObject.getClass();
44 Method lvMethod = findMethod(clazz, pvMethodName, pvParams);
45 Converter lvConverter = (pvWithConverter == true ? pvConverter : null);
46 Object[] lvArgs = vector2Array(pvParams, lvMethod, lvConverter);
47 AccessController.doPrivileged(new MethodAccessiblePrivilegedAction(lvMethod));
48 Object lvMethodResult = null;
49 try {
50 lvMethodResult = lvMethod.invoke(pvObject, lvArgs);
51 } catch (IllegalArgumentException e) {
52 throw new IllegalArgumentException("Illegal argument by method: " + lvMethod + " and args: " + pvParams + " with object: " + pvObject);
53 }
54 if (pvWithConverter == true) {
55 lvMethodResult = lvConverter.makeSimple (lvMethodResult);
56 }
57 return lvMethodResult;
58 }
59
60 public static Object[] vector2Array(Vector pvVector, Method pvMethod, Converter pvConverter) throws Exception {
61 Object[] lvArgs = new Object[pvVector.size()];
62 int lvMethodParamsLength = pvMethod.getParameterTypes().length;
63 int lvVectorSize = pvVector.size();
64 for (int j = 0; j < lvArgs.length; j++) {
65 if (pvConverter != null) {
66 if (lvMethodParamsLength == lvVectorSize) {
67
68 Class lvParamType = pvMethod.getParameterTypes()[j];
69 if (lvParamType.isArray()) {
70 Class lvType = lvParamType.getComponentType();
71 lvArgs[j] = pvConverter.makeComplex (pvVector.get(j), lvParamType, lvType);
72 } else {
73 lvArgs[j] = pvConverter.makeComplex (pvVector.get(j), lvParamType);
74 }
75 }
76
77
78 else {
79 lvArgs[j] = pvConverter.makeComplex (pvVector.get(j));
80 }
81 }
82
83 else {
84 lvArgs[j] = pvVector.get(j);
85 }
86 }
87 return lvArgs;
88 }
89
90 public static boolean isCompatibleType (Class pvType1, Class pvType2) {
91 if (compatibleTypes.size() == 0) {
92 compatibleTypes.put(byte.class, Byte.class);
93 compatibleTypes.put(short.class, Short.class);
94 compatibleTypes.put(int.class, Integer.class);
95 compatibleTypes.put(long.class, Long.class);
96 compatibleTypes.put(float.class, Float.class);
97 compatibleTypes.put(double.class, Double.class);
98 compatibleTypes.put(char.class, Character.class);
99 compatibleTypes.put(boolean.class, Boolean.class);
100
101 compatibleTypes.put(Long.class, long.class);
102 }
103 Class lvType = (Class) compatibleTypes.get(pvType1);
104 boolean lvReturn = false;
105 if (lvType != null) {
106 lvReturn = (compatibleTypes.get(pvType1).equals(pvType2));
107 }
108 return lvReturn;
109 }
110
111 public static Method findMethod(Class pvClass, String pvMethodName, List pvParams) throws Exception {
112 List lvParams = pvParams;
113 if (lvParams == null) { lvParams = new ArrayList(0); }
114 Method[] lvMethods = findAllMethods(pvClass, pvMethodName);
115 Method lvMerkMethod = null;
116 for (int i = 0; i < lvMethods.length; i++) {
117 Class lvParamTypes[] = lvMethods[i].getParameterTypes();
118
119
120 if (lvParamTypes.length == lvParams.size()) {
121
122 lvMerkMethod = lvMethods[i];
123
124 boolean lvParamOk = true;
125 for (int j = 0; j < lvParamTypes.length; j++) {
126 if (lvParamTypes[j].isArray()) {
127 Class lvParamArrayType = Converter.getArrayType(lvParams.get(j));
128
129 if (!lvParamTypes[j].getComponentType().equals(lvParamArrayType)) {
130 lvParamOk = false;
131 break;
132 }
133 } else {
134 Class lvParamClass = (lvParams.get(j) == null ? null : lvParams.get(j).getClass());
135 if ((!lvParamTypes[j].equals(lvParamClass)) && (!isCompatibleType(lvParamTypes[j], lvParamClass))) {
136 lvParamOk = false;
137 break;
138 }
139 }
140 }
141
142 if (lvParamOk) {
143 return lvMethods[i];
144 }
145 }
146 }
147
148 if (lvMerkMethod != null) {
149 return lvMerkMethod;
150 }
151
152
153 else if (lvMethods.length > 0) {
154 return lvMethods[0];
155 }
156 throw new NoSuchMethodException("For class: " + pvClass
157 + " with method: " + pvMethodName + " with parameter: " + lvParams);
158 }
159
160 public static Method[] findAllMethods(Class pvClass, String pvMethodName) throws Exception {
161 Method[] lvMethods = pvClass.getMethods();
162 ArrayList lvFindedMethods = new ArrayList();
163 for (int i = 0; i < lvMethods.length; i++) {
164 if (lvMethods[i].getName().equals(pvMethodName)){
165 lvFindedMethods.add(lvMethods[i]);
166 }
167 }
168 return (Method[]) lvFindedMethods.toArray(new Method [lvFindedMethods.size()]);
169 }
170
171 public static Vector array2Vector (Object [] pvArray) throws Exception {
172 Vector param = new Vector();
173 if (pvArray != null){
174 for (int i = 0; i < pvArray.length; i++) {
175 param.add(pvArray[i]);
176 }
177 }
178 return param;
179 }
180
181 public static Vector array2SimpleVector (Object [] pvArray) throws Exception {
182 Vector param = new Vector();
183 if (pvArray != null){
184 Converter lvConverter = new Converter();
185 for (int i = 0; i < pvArray.length; i++) {
186 param.add(lvConverter.makeSimple(pvArray[i]));
187 }
188 }
189 return param;
190 }
191
192 public static Object[] array2SimpleArray (Object [] pvArray, Converter pvConverter) throws Exception {
193 Object ret[] = null;
194 if (pvArray != null){
195 ret = new Object[pvArray.length];
196 for (int i = 0; i < pvArray.length; i++) {
197 ret[i] = pvConverter.makeSimple(pvArray[i]);
198 }
199 }
200 return ret;
201 }
202
203 }