1
2
3
4
5
6
7
8
9
10 package org.mule.model.resolvers;
11
12 import org.mule.VoidResult;
13 import org.mule.api.MuleEventContext;
14 import org.mule.api.model.EntryPointResolver;
15 import org.mule.api.model.InvocationResult;
16 import org.mule.api.transformer.TransformerException;
17 import org.mule.transport.NullPayload;
18 import org.mule.util.ClassUtils;
19 import org.mule.util.StringMessageUtils;
20
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28
29
30
31
32
33
34 public abstract class AbstractEntryPointResolver implements EntryPointResolver
35 {
36 private static final Log logger = LogFactory.getLog(AbstractEntryPointResolver.class);
37
38 private boolean acceptVoidMethods = false;
39
40 private boolean synchronizeCall = false;
41
42
43 private final ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, Method>> methodCache =
44 new ConcurrentHashMap<Class<?>, ConcurrentHashMap<String, Method>>(4);
45
46 public boolean isAcceptVoidMethods()
47 {
48 return acceptVoidMethods;
49 }
50
51 public void setAcceptVoidMethods(boolean acceptVoidMethods)
52 {
53 this.acceptVoidMethods = acceptVoidMethods;
54 }
55
56 protected ConcurrentHashMap<String, Method> getMethodCache(Object component)
57 {
58 Class<?> componentClass = component.getClass();
59 ConcurrentHashMap<String, Method> cache = methodCache.get(componentClass);
60 if (cache == null)
61 {
62 methodCache.putIfAbsent(componentClass, new ConcurrentHashMap<String, Method>(4));
63 }
64 return methodCache.get(componentClass);
65 }
66
67 protected Method getMethodByName(Object component, String methodName, MuleEventContext context)
68 {
69 return getMethodCache(component).get(methodName);
70 }
71
72 protected Method addMethodByName(Object component, Method method, MuleEventContext context)
73 {
74 Method previousMethod = getMethodCache(component).putIfAbsent(method.getName(), method);
75 return (previousMethod != null ? previousMethod : method);
76 }
77
78 protected Method addMethodByArguments(Object component, Method method, Object[] payload)
79 {
80 Method previousMethod = getMethodCache(component).putIfAbsent(getCacheKeyForPayload(component, payload), method);
81 return (previousMethod != null ? previousMethod : method);
82 }
83
84
85 protected Method getMethodByArguments(Object component, Object[] payload)
86 {
87 Method method = getMethodCache(component).get(getCacheKeyForPayload(component, payload));
88 return method;
89 }
90
91 protected String getCacheKeyForPayload(Object component, Object[] payload)
92 {
93 StringBuffer key = new StringBuffer(48);
94 for (int i = 0; i < payload.length; i++)
95 {
96 Object o = payload[i];
97 if (o != null)
98 {
99 key.append(o.getClass().getName());
100 }
101 else
102 {
103 key.append("null");
104 }
105 }
106 key.append(".").append(ClassUtils.getClassName(component.getClass()));
107 return key.toString();
108 }
109
110
111 protected Object[] getPayloadFromMessage(MuleEventContext context) throws TransformerException
112 {
113 Object temp = context.getMessage().getPayload();
114 if (temp instanceof Object[])
115 {
116 return (Object[]) temp;
117 }
118 else if (temp instanceof NullPayload)
119 {
120 return ClassUtils.NO_ARGS;
121 }
122 else
123 {
124 return new Object[]{temp};
125 }
126 }
127
128 protected InvocationResult invokeMethod(Object component, Method method, Object[] arguments)
129 throws InvocationTargetException, IllegalAccessException
130 {
131 String methodCall = null;
132
133 if (logger.isDebugEnabled())
134 {
135 methodCall = component.getClass().getName() + "." + method.getName() + "("
136 + StringMessageUtils.toString(ClassUtils.getClassTypes(arguments)) + ")";
137 logger.debug("Invoking " + methodCall);
138 }
139
140 Object result;
141
142 if(isSynchronizeCall())
143 {
144 synchronized (component)
145 {
146 result = method.invoke(component, arguments);
147 }
148 }
149 else
150 {
151 result = method.invoke(component, arguments);
152 }
153
154 if (method.getReturnType().equals(Void.TYPE))
155 {
156 result = VoidResult.getInstance();
157 }
158
159 if (logger.isDebugEnabled())
160 {
161 logger.debug("Result of call " + methodCall + " is " + (result == null ? "null" : "not null"));
162 }
163
164 return new InvocationResult(this, result, method);
165 }
166
167 public boolean isSynchronizeCall()
168 {
169 return synchronizeCall;
170 }
171
172 public void setSynchronizeCall(boolean synchronizeCall)
173 {
174 this.synchronizeCall = synchronizeCall;
175 }
176
177 @Override
178 public String toString()
179 {
180 final StringBuffer sb = new StringBuffer();
181 sb.append("AbstractEntryPointResolver");
182 sb.append(", acceptVoidMethods=").append(acceptVoidMethods);
183 sb.append('}');
184 return sb.toString();
185 }
186 }