1
2
3
4
5
6
7
8
9
10 package org.mule.module.ibeans.config;
11
12 import org.mule.DefaultMuleEvent;
13 import org.mule.api.EndpointAnnotationParser;
14 import org.mule.api.MessagingException;
15 import org.mule.api.MuleContext;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.MuleException;
18 import org.mule.api.MuleRuntimeException;
19 import org.mule.api.component.InterfaceBinding;
20 import org.mule.api.endpoint.ImmutableEndpoint;
21 import org.mule.api.endpoint.InboundEndpoint;
22 import org.mule.api.endpoint.OutboundEndpoint;
23 import org.mule.config.i18n.CoreMessages;
24 import org.mule.module.ibeans.spi.MuleCallAnnotationHandler;
25 import org.mule.module.ibeans.spi.MuleIBeansPlugin;
26 import org.mule.module.ibeans.spi.support.DynamicRequestInterfaceBinding;
27 import org.mule.util.annotation.AnnotationMetaData;
28 import org.mule.util.annotation.AnnotationUtils;
29
30 import java.lang.annotation.Annotation;
31 import java.lang.reflect.InvocationHandler;
32 import java.lang.reflect.Method;
33 import java.lang.reflect.Proxy;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Map;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.ibeans.annotation.Call;
44 import org.ibeans.annotation.Template;
45 import org.ibeans.annotation.param.Body;
46 import org.ibeans.annotation.param.BodyParam;
47 import org.ibeans.annotation.param.HeaderParam;
48 import org.ibeans.api.IBeanInvoker;
49 import org.ibeans.api.IBeansException;
50 import org.ibeans.api.channel.HTTP;
51 import org.ibeans.impl.IntegrationBeanInvocationHandler;
52 import org.ibeans.impl.InvokeAnnotationHandler;
53 import org.ibeans.impl.TemplateAnnotationHandler;
54
55
56
57
58 public class IBeanBinding implements InterfaceBinding
59 {
60
61 private static final Log logger = LogFactory.getLog(IBeanBinding.class);
62
63 private Class interfaceClass;
64
65
66 protected OutboundEndpoint endpoint;
67
68 protected IBeanFlowConstruct flow;
69
70 protected MuleIBeansPlugin plugin;
71
72 protected MuleContext muleContext;
73
74 public IBeanBinding(IBeanFlowConstruct flow, MuleContext muleContext, MuleIBeansPlugin plugin)
75 {
76 this.flow = flow;
77 this.muleContext = muleContext;
78 this.plugin = plugin;
79 }
80
81 public String getMethod()
82 {
83 throw new UnsupportedOperationException();
84 }
85
86 public void setMethod(String method)
87 {
88 throw new UnsupportedOperationException();
89 }
90
91 public MuleEvent process(MuleEvent event) throws MessagingException
92 {
93 try
94 {
95 return endpoint.process(new DefaultMuleEvent(event.getMessage(), endpoint, event.getSession()));
96 }
97 catch (MessagingException e)
98 {
99 throw e;
100 }
101 catch (MuleException e)
102 {
103 throw new MessagingException(e.getI18nMessage(), event, e);
104 }
105 }
106
107 public void setInterface(Class interfaceClass)
108 {
109 this.interfaceClass = interfaceClass;
110 }
111
112 public Class getInterface()
113 {
114 return interfaceClass;
115 }
116
117 public Object createProxy(Object target)
118 {
119 Map<String, String> evals = new HashMap<String, String>();
120 try
121 {
122 IBeanInvoker<MuleCallAnnotationHandler, TemplateAnnotationHandler, InvokeAnnotationHandler> invoker = plugin.getIBeanInvoker();
123 invoker.getCallHandler().setFlow(flow);
124
125 List<AnnotationMetaData> annos = AnnotationUtils.getAllMethodAnnotations(getInterface());
126 for (AnnotationMetaData metaData : annos)
127 {
128 if (metaData.getAnnotation() instanceof Call)
129 {
130 Collection c = muleContext.getRegistry().lookupObjects(EndpointAnnotationParser.class);
131 String scheme;
132 boolean http;
133 String uri = ((Call) metaData.getAnnotation()).uri();
134 int i = uri.indexOf(":/");
135 if (i == -1)
136 {
137 scheme = "dynamic";
138 }
139 else
140 {
141 scheme = uri.substring(0, i);
142 }
143 http = scheme.contains("http");
144
145 Map metaInfo = new HashMap();
146
147 metaInfo.put("connectorName", metaData.getClazz().getSimpleName() + "." + scheme);
148
149 for (Iterator iterator = c.iterator(); iterator.hasNext();)
150 {
151 EndpointAnnotationParser parser = (EndpointAnnotationParser) iterator.next();
152 if (parser.supports(metaData.getAnnotation(), metaData.getClazz(), metaData.getMember()))
153 {
154 InterfaceBinding binding;
155 Method method = (Method) metaData.getMember();
156 boolean callChannel = false;
157 Annotation ann;
158
159
160
161
162
163
164 for (int x = 0; x < method.getParameterAnnotations().length; x++)
165 {
166 ann = method.getParameterAnnotations()[x][0];
167 if (ann.annotationType().equals(Body.class) ||
168 ann.annotationType().equals(BodyParam.class) ||
169 ann.annotationType().equals(HeaderParam.class))
170 {
171
172 callChannel = true;
173
174 break;
175 }
176 }
177
178
179
180
181 if (callChannel || http)
182 {
183 OutboundEndpoint endpoint = parser.parseOutboundEndpoint(metaData.getAnnotation(), metaInfo);
184 binding = new CallInterfaceBinding(this.flow);
185 binding.setEndpoint(endpoint);
186 }
187 else
188 {
189 InboundEndpoint endpoint = parser.parseInboundEndpoint(metaData.getAnnotation(), Collections.EMPTY_MAP);
190 binding = new DynamicRequestInterfaceBinding();
191 binding.setEndpoint(endpoint);
192 }
193
194
195 if (http)
196 {
197 List<AnnotationMetaData> temp = AnnotationUtils.getParamAnnotations(method);
198 boolean post = false;
199 for (AnnotationMetaData data : temp)
200 {
201 if (data.getAnnotation().annotationType().equals(Body.class) ||
202 data.getAnnotation().annotationType().equals(BodyParam.class))
203 {
204 post = true;
205 break;
206 }
207 }
208
209 if (!post && binding.getEndpoint().getProperties().get(HTTP.METHOD_KEY) == null)
210 {
211 binding.getEndpoint().getProperties().put(HTTP.METHOD_KEY, "GET");
212 }
213 }
214
215 binding.setInterface(getInterface());
216 binding.setMethod(metaData.getMember().toString());
217 invoker.getCallHandler().addRouterForInterface(binding);
218
219 }
220 }
221 }
222 else if (metaData.getAnnotation() instanceof Template)
223 {
224 evals.put(metaData.getMember().toString(), ((Template) metaData.getAnnotation()).value());
225 }
226 }
227
228 if (evals.size() > 0)
229 {
230 invoker.getTemplateHandler().setEvals(evals);
231 }
232
233 Object proxy = Proxy.newProxyInstance(getInterface().getClassLoader(), new Class[]{getInterface()}, createInvocationHandler());
234 if (logger.isDebugEnabled())
235 {
236 logger.debug("Have proxy?: " + (null != proxy));
237 }
238 return proxy;
239
240 }
241 catch (Exception e)
242 {
243 throw new MuleRuntimeException(CoreMessages.failedToCreateProxyFor(target), e);
244 }
245 }
246
247 public void setEndpoint(ImmutableEndpoint e)
248 {
249 endpoint = (OutboundEndpoint) e;
250 }
251
252 public String toString()
253 {
254 final StringBuffer sb = new StringBuffer();
255 sb.append("IBeanBinding");
256 sb.append(", interface=").append(interfaceClass);
257 sb.append('}');
258 return sb.toString();
259 }
260
261 public ImmutableEndpoint getEndpoint()
262 {
263 return endpoint;
264 }
265
266 protected InvocationHandler createInvocationHandler() throws IBeansException
267 {
268 return new IntegrationBeanInvocationHandler(interfaceClass, plugin);
269 }
270 }