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