View Javadoc

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  //   	   			if (pvMethod.getParameterTypes().length > j) {
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     	   			// pvVector.size > pvMethod.getParameterTypes().length
77     	   			// ??? Critical Point ???
78     	   			else {
79     	   				lvArgs[j] = pvConverter.makeComplex (pvVector.get(j));
80     	   			}
81     	   		} 
82     	   		// Converter == null
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        		// Methoden-Parameter und pvParams muessen gleiche Anzahl haben
120        		if (lvParamTypes.length == lvParams.size()) {
121        			// wenn Name und Anzahl Parameter uebereinstimmen, dann Methode merken
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 						// Typen im Array stimmen NICHT ueberein
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            		// Methodenname und Parameter stimmen ueberein
142            		if (lvParamOk) {
143            			return lvMethods[i]; 
144            		}
145        		}
146         }
147         
148         if (lvMerkMethod != null) {
149         	return lvMerkMethod; 
150         } 
151         // ???  if the method has the right name, but the size of parameters is not correct ???
152         // ??? by overloading can the chois from this method false ???
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 }