1 package net.sf.crispy;
2
3 import java.lang.reflect.Method;
4 import java.util.Collection;
5
6 import net.sf.crispy.proxy.Proxy;
7 import net.sf.crispy.util.Converter;
8 import net.sf.crispy.util.Invoker;
9
10 /**
11 * Decorator for all Executor implemantations. Before execute the method <code>execute</code>, test the
12 * method for the remoting (for internal use).
13 *
14 * @author Linke
15 *
16 */
17 public class ExecutorDecorator extends Executor {
18
19 private transient final Executor executor;
20
21 public ExecutorDecorator(Executor pvExecutor) {
22 super();
23 executor = pvExecutor;
24 this.setProperties(executor.getProperties());
25 }
26
27 public Executor getExecutor() { return executor; }
28
29 public static Object notRemoteMethod (final Method pvMethod, final Class pvProxyClass) {
30 final String lvMethodName = pvMethod.getName();
31 Object lvReturn = null;
32 if ("toString".equals(lvMethodName)) {
33 lvReturn = "toString: " + pvProxyClass.getName();
34 }
35 else if ("getClass".equals(lvMethodName)) {
36 lvReturn = pvProxyClass;
37 }
38 else if ("equals".equals(lvMethodName)) {
39 lvReturn = Boolean.FALSE;
40 }
41 else if ("hashCode".equals(lvMethodName)) {
42 lvReturn = Integer.valueOf("0");
43 }
44
45 return lvReturn;
46 }
47
48
49 public Object createInvocationStrategy (final Class pvProxyClass, final Method pvMethod) throws Exception {
50
51 executor.setInvocationStrategy(null);
52 return Proxy.createInvocationStrategy(executor.getDefaultInvocationStrategy(),
53 getProperties(), executor.getDefaultUrlAndPort(),
54 pvProxyClass, pvMethod);
55 }
56
57 public String getDefaultUrlAndPort() { return executor.getDefaultUrlAndPort(); }
58 public InvocationStrategy getDefaultInvocationStrategy() { return executor.getDefaultInvocationStrategy(); }
59
60 public Object execute(final Class pvProxyClass, final Object pvProxy, final Method pvMethod, final Object[] pvArgs) throws Exception {
61 final Object isPermittedMethod = notRemoteMethod(pvMethod, pvProxyClass);
62 if (isPermittedMethod == null) {
63 if ((executor.getProperties() != null) && (executor.getUrlAndPort() == null)) {
64 executor.setUrlAndPort(getProperties().getProperty(Property.REMOTE_URL_AND_PORT, getDefaultUrlAndPort()));
65 }
66 } else {
67 if (log.isDebugEnabled()) { log.debug("PermittedMethod: " + pvMethod); }
68 return isPermittedMethod;
69 }
70
71
72 final Object lvInvocationStrategy = createInvocationStrategy(pvProxyClass, pvMethod);
73 executor.setInvocationStrategy(lvInvocationStrategy);
74
75
76 boolean lvWithConverter = executor.withConverter();
77 String lvStrWithConverter = getProperties().getProperty(Property.WITH_CONVERTER, Boolean.valueOf(lvWithConverter).toString());
78 lvWithConverter = Boolean.valueOf(lvStrWithConverter).booleanValue();
79
80
81 Object lvParams[] = pvArgs;
82 Converter lvConverter = null;
83 if (lvWithConverter == true) {
84 String lvPropertyNullValue = getProperties().getProperty(Property.NULL_VALUE, null);
85 lvConverter = new Converter(lvPropertyNullValue);
86 lvConverter.setWithSimpleKeyMapper(true);
87 lvParams = Invoker.array2SimpleArray(pvArgs, lvConverter);
88 }
89
90 Object lvResult = executor.execute(pvProxyClass, pvProxy, pvMethod, lvParams);
91
92
93 if (lvWithConverter == true) {
94 if ((lvResult instanceof Collection) && (pvMethod.getReturnType().isArray())) {
95 Class lvTypeInArray = pvMethod.getReturnType().getComponentType();
96 lvResult = lvConverter.makeComplex(lvResult, pvMethod.getReturnType(), lvTypeInArray);
97 } else {
98 lvResult = lvConverter.makeComplex(lvResult, pvMethod.getReturnType());
99 }
100 }
101
102 return lvResult;
103 }
104
105 }