1
2
3
4
5
6
7
8
9
10
11 package org.mule.component;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.RequestContext;
16 import org.mule.api.MuleContext;
17 import org.mule.api.MuleEvent;
18 import org.mule.api.MuleMessage;
19 import org.mule.api.component.InterfaceBinding;
20 import org.mule.api.config.MuleProperties;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.transport.NullPayload;
23 import org.mule.util.StringMessageUtils;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.Method;
27 import java.util.Map;
28
29 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34 public class BindingInvocationHandler implements InvocationHandler
35 {
36
37 public static final String DEFAULT_METHOD_NAME_TOKEN = "default";
38
39 protected static Log logger = LogFactory.getLog(BindingInvocationHandler.class);
40
41 protected Map<String, InterfaceBinding> routers = null;
42
43 protected MuleContext muleContext;
44
45 @SuppressWarnings("unchecked")
46 public BindingInvocationHandler(InterfaceBinding router)
47 {
48 routers = new ConcurrentHashMap();
49 addRouterForInterface(router);
50 }
51
52 public void addRouterForInterface(InterfaceBinding router)
53 {
54 if (router.getMethod() == null)
55 {
56 if (routers.size() == 0)
57 {
58 routers.put(DEFAULT_METHOD_NAME_TOKEN, router);
59 }
60 else
61 {
62 throw new IllegalArgumentException(CoreMessages.mustSetMethodNamesOnBinding().getMessage());
63 }
64 }
65 else
66 {
67 routers.put(router.getMethod(), router);
68 }
69 muleContext = router.getEndpoint().getConnector().getMuleContext();
70 }
71
72 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
73 {
74 if (method.getName().equals("toString"))
75 {
76 return toString();
77 }
78
79 MuleMessage message = createMuleMessage(args);
80
81
82 message.setInvocationProperty(MuleProperties.MULE_METHOD_PROPERTY, method.getName());
83
84 InterfaceBinding router = routers.get(method.getName());
85 if (router == null)
86 {
87 router = routers.get(DEFAULT_METHOD_NAME_TOKEN);
88 }
89
90 if (router == null)
91 {
92 throw new IllegalArgumentException(CoreMessages.cannotFindBindingForMethod(method.getName()).toString());
93 }
94
95 MuleEvent currentEvent = RequestContext.getEvent();
96 MuleEvent replyEvent = router.process(new DefaultMuleEvent(message,currentEvent));
97
98 if (replyEvent != null && replyEvent.getMessage()!=null)
99 {
100 MuleMessage reply = replyEvent.getMessage();
101 if (reply.getExceptionPayload() != null)
102 {
103 throw findDeclaredMethodException(method, reply.getExceptionPayload().getException());
104 }
105 else
106 {
107 return determineReply(reply, method);
108 }
109 }
110 else
111 {
112 return null;
113 }
114 }
115
116 private MuleMessage createMuleMessage(Object[] args)
117 {
118 if (args == null)
119 {
120 return new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
121 }
122 else if (args.length == 1)
123 {
124 return new DefaultMuleMessage(args[0], muleContext);
125 }
126 else
127 {
128 return new DefaultMuleMessage(args, muleContext);
129 }
130 }
131
132
133
134
135
136
137 private Throwable findDeclaredMethodException(Method method, Throwable throwable) throws Throwable
138 {
139 Throwable cause = throwable.getCause();
140 if (cause != null)
141 {
142
143
144 Class[] exceptions = method.getExceptionTypes();
145 for (int i = 0; i < exceptions.length; i++)
146 {
147 if (cause.getClass().equals(exceptions[i]))
148 {
149 return cause;
150 }
151 }
152 }
153
154 return throwable;
155 }
156
157 private Object determineReply(MuleMessage reply, Method bindingMethod)
158 {
159 if (MuleMessage.class.isAssignableFrom(bindingMethod.getReturnType()))
160 {
161 return reply;
162 }
163 else
164 {
165 return reply.getPayload();
166 }
167 }
168
169 @Override
170 public String toString()
171 {
172 final StringBuffer sb = new StringBuffer();
173 sb.append("BindingInvocation");
174 sb.append("{routers='").append(StringMessageUtils.toString(routers));
175 sb.append('}');
176 return sb.toString();
177 }
178
179 }