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