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