001: package net.sf.crispy.util;
002:
003: import java.lang.reflect.Method;
004: import java.security.AccessController;
005: import java.util.ArrayList;
006: import java.util.HashMap;
007: import java.util.List;
008: import java.util.Map;
009: import java.util.Vector;
010:
011: /**
012: * Work with reflection API.
013: *
014: * @author Linke
015: *
016: */
017: public final class Invoker {
018:
019: private Invoker() {
020: super ();
021: }
022:
023: private static Map compatibleTypes = new HashMap();
024:
025: /**
026: * Invoke method from pvObject with the method-name (pvMethodName) and parameter (pvPrams) via reflection.
027: * @param pvObject object for the method call
028: * @param pvMethodName name of method
029: * @param pvParams parameter for method
030: * @return the return value from the method call
031: * @throws Exception
032: */
033: public static Object invokeWithConverter(Object pvObject,
034: String pvMethodName, Vector pvParams, Converter pvConverter)
035: throws Exception {
036: return invoke(pvObject, pvMethodName, pvParams, true,
037: pvConverter);
038: }
039:
040: public static Object invoke(String pvClassName,
041: String pvMethodName, Vector pvParams,
042: boolean pvWithConverter, Converter pvConverter)
043: throws Exception {
044: Class lvClass = Class.forName(pvClassName);
045: Object lvObject = lvClass.newInstance();
046: return invoke(lvObject, pvMethodName, pvParams,
047: pvWithConverter, pvConverter);
048: }
049:
050: public static Object invoke(Object pvObject, String pvMethodName,
051: Vector pvParams, boolean pvWithConverter,
052: Converter pvConverter) throws Exception {
053: Class clazz = pvObject.getClass();
054: Method lvMethod = findMethod(clazz, pvMethodName, pvParams);
055: Converter lvConverter = (pvWithConverter == true ? pvConverter
056: : null);
057: Object[] lvArgs = vector2Array(pvParams, lvMethod, lvConverter);
058: AccessController
059: .doPrivileged(new MethodAccessiblePrivilegedAction(
060: lvMethod));
061: Object lvMethodResult = null;
062: try {
063: lvMethodResult = lvMethod.invoke(pvObject, lvArgs);
064: } catch (IllegalArgumentException e) {
065: throw new IllegalArgumentException(
066: "Illegal argument by method: " + lvMethod
067: + " and args: " + pvParams
068: + " with object: " + pvObject);
069: }
070: if (pvWithConverter == true) {
071: lvMethodResult = lvConverter.makeSimple(lvMethodResult);
072: }
073: return lvMethodResult;
074: }
075:
076: public static Object[] vector2Array(Vector pvVector,
077: Method pvMethod, Converter pvConverter) throws Exception {
078: Object[] lvArgs = new Object[pvVector.size()];
079: int lvMethodParamsLength = pvMethod.getParameterTypes().length;
080: int lvVectorSize = pvVector.size();
081: for (int j = 0; j < lvArgs.length; j++) {
082: if (pvConverter != null) {
083: if (lvMethodParamsLength == lvVectorSize) {
084: // if (pvMethod.getParameterTypes().length > j) {
085: Class lvParamType = pvMethod.getParameterTypes()[j];
086: if (lvParamType.isArray()) {
087: Class lvType = lvParamType.getComponentType();
088: lvArgs[j] = pvConverter.makeComplex(pvVector
089: .get(j), lvParamType, lvType);
090: } else {
091: lvArgs[j] = pvConverter.makeComplex(pvVector
092: .get(j), lvParamType);
093: }
094: }
095: // pvVector.size > pvMethod.getParameterTypes().length
096: // ??? Critical Point ???
097: else {
098: lvArgs[j] = pvConverter
099: .makeComplex(pvVector.get(j));
100: }
101: }
102: // Converter == null
103: else {
104: lvArgs[j] = pvVector.get(j);
105: }
106: }
107: return lvArgs;
108: }
109:
110: public static boolean isCompatibleType(Class pvType1, Class pvType2) {
111: if (compatibleTypes.size() == 0) {
112: compatibleTypes.put(byte.class, Byte.class);
113: compatibleTypes.put(short.class, Short.class);
114: compatibleTypes.put(int.class, Integer.class);
115: compatibleTypes.put(long.class, Long.class);
116: compatibleTypes.put(float.class, Float.class);
117: compatibleTypes.put(double.class, Double.class);
118: compatibleTypes.put(char.class, Character.class);
119: compatibleTypes.put(boolean.class, Boolean.class);
120:
121: compatibleTypes.put(Long.class, long.class);
122: }
123: Class lvType = (Class) compatibleTypes.get(pvType1);
124: boolean lvReturn = false;
125: if (lvType != null) {
126: lvReturn = (compatibleTypes.get(pvType1).equals(pvType2));
127: }
128: return lvReturn;
129: }
130:
131: public static Method findMethod(Class pvClass, String pvMethodName,
132: List pvParams) throws Exception {
133: List lvParams = pvParams;
134: if (lvParams == null) {
135: lvParams = new ArrayList(0);
136: }
137: Method[] lvMethods = findAllMethods(pvClass, pvMethodName);
138: Method lvMerkMethod = null;
139: for (int i = 0; i < lvMethods.length; i++) {
140: Class lvParamTypes[] = lvMethods[i].getParameterTypes();
141:
142: // Methoden-Parameter und pvParams muessen gleiche Anzahl haben
143: if (lvParamTypes.length == lvParams.size()) {
144: // wenn Name und Anzahl Parameter uebereinstimmen, dann Methode merken
145: lvMerkMethod = lvMethods[i];
146:
147: boolean lvParamOk = true;
148: for (int j = 0; j < lvParamTypes.length; j++) {
149: if (lvParamTypes[j].isArray()) {
150: Class lvParamArrayType = Converter
151: .getArrayType(lvParams.get(j));
152: // Typen im Array stimmen NICHT ueberein
153: if (!lvParamTypes[j].getComponentType().equals(
154: lvParamArrayType)) {
155: lvParamOk = false;
156: break;
157: }
158: } else {
159: Class lvParamClass = (lvParams.get(j) == null ? null
160: : lvParams.get(j).getClass());
161: if ((!lvParamTypes[j].equals(lvParamClass))
162: && (!isCompatibleType(lvParamTypes[j],
163: lvParamClass))) {
164: lvParamOk = false;
165: break;
166: }
167: }
168: }
169: // Methodenname und Parameter stimmen ueberein
170: if (lvParamOk) {
171: return lvMethods[i];
172: }
173: }
174: }
175:
176: if (lvMerkMethod != null) {
177: return lvMerkMethod;
178: }
179: // ??? if the method has the right name, but the size of parameters is not correct ???
180: // ??? by overloading can the chois from this method false ???
181: else if (lvMethods.length > 0) {
182: return lvMethods[0];
183: }
184: throw new NoSuchMethodException("For class: " + pvClass
185: + " with method: " + pvMethodName + " with parameter: "
186: + lvParams);
187: }
188:
189: public static Method[] findAllMethods(Class pvClass,
190: String pvMethodName) throws Exception {
191: Method[] lvMethods = pvClass.getMethods();
192: ArrayList lvFindedMethods = new ArrayList();
193: for (int i = 0; i < lvMethods.length; i++) {
194: if (lvMethods[i].getName().equals(pvMethodName)) {
195: lvFindedMethods.add(lvMethods[i]);
196: }
197: }
198: return (Method[]) lvFindedMethods
199: .toArray(new Method[lvFindedMethods.size()]);
200: }
201:
202: public static Vector array2Vector(Object[] pvArray)
203: throws Exception {
204: Vector param = new Vector();
205: if (pvArray != null) {
206: for (int i = 0; i < pvArray.length; i++) {
207: param.add(pvArray[i]);
208: }
209: }
210: return param;
211: }
212:
213: public static Vector array2SimpleVector(Object[] pvArray)
214: throws Exception {
215: Vector param = new Vector();
216: if (pvArray != null) {
217: Converter lvConverter = new Converter();
218: for (int i = 0; i < pvArray.length; i++) {
219: param.add(lvConverter.makeSimple(pvArray[i]));
220: }
221: }
222: return param;
223: }
224:
225: public static Object[] array2SimpleArray(Object[] pvArray,
226: Converter pvConverter) throws Exception {
227: Object ret[] = null;
228: if (pvArray != null) {
229: ret = new Object[pvArray.length];
230: for (int i = 0; i < pvArray.length; i++) {
231: ret[i] = pvConverter.makeSimple(pvArray[i]);
232: }
233: }
234: return ret;
235: }
236:
237: }
|