Coverage Report - org.mule.module.ibeans.config.IBeanBinding
 
Classes in this File Line Coverage Branch Coverage Complexity
IBeanBinding
0%
0/73
0%
0/30
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 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  
  * TODO
 53  
  */
 54  
 public class IBeanBinding implements InterfaceBinding
 55  
 {
 56  
 
 57  0
     private static final Log logger = LogFactory.getLog(IBeanBinding.class);
 58  
 
 59  
     private Class interfaceClass;
 60  
 
 61  
     // The endpoint used to actually dispatch the message
 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  0
     {
 72  0
         this.flow = flow;
 73  0
         this.muleContext = muleContext;
 74  0
         this.plugin = plugin;
 75  0
     }
 76  
 
 77  
     public String getMethod()
 78  
     {
 79  0
         throw new UnsupportedOperationException();
 80  
     }
 81  
 
 82  
     public void setMethod(String method)
 83  
     {
 84  0
         throw new UnsupportedOperationException();
 85  
     }
 86  
 
 87  
     public MuleEvent process(MuleEvent event) throws MessagingException
 88  
     {
 89  
         try
 90  
         {
 91  0
             return endpoint.process(new DefaultMuleEvent(event.getMessage(), endpoint, event.getSession()));
 92  
         }
 93  0
         catch (MessagingException e)
 94  
         {
 95  0
             throw e;
 96  
         }
 97  0
         catch (MuleException e)
 98  
         {
 99  0
             throw new MessagingException(e.getI18nMessage(), event, e);
 100  
         }
 101  
     }
 102  
 
 103  
     public void setInterface(Class interfaceClass)
 104  
     {
 105  0
         this.interfaceClass = interfaceClass;
 106  0
     }
 107  
 
 108  
     public Class getInterface()
 109  
     {
 110  0
         return interfaceClass;
 111  
     }
 112  
 
 113  
     public Object createProxy(Object target)
 114  
     {
 115  0
         Map<String, String> evals = new HashMap<String, String>();
 116  
         try
 117  
         {
 118  0
             IBeanInvoker<MuleCallAnnotationHandler, TemplateAnnotationHandler, InvokeAnnotationHandler> invoker = plugin.getIBeanInvoker();
 119  0
             invoker.getCallHandler().setFlow(flow);
 120  
 
 121  0
             List<AnnotationMetaData> annos = AnnotationUtils.getAllMethodAnnotations(getInterface());
 122  0
             for (AnnotationMetaData metaData : annos)
 123  
             {
 124  0
                 if (metaData.getAnnotation() instanceof Call)
 125  
                 {
 126  0
                     Collection c = muleContext.getRegistry().lookupObjects(EndpointAnnotationParser.class);
 127  
                     String scheme;
 128  
                     boolean http;
 129  0
                     String uri = ((Call) metaData.getAnnotation()).uri();
 130  0
                     int i = uri.indexOf(":/");
 131  0
                     if (i == -1)
 132  
                     {
 133  0
                         scheme = "dynamic";
 134  
                     }
 135  
                     else
 136  
                     {
 137  0
                         scheme = uri.substring(0, i);
 138  
                     }
 139  0
                     http = scheme.contains("http");
 140  
 
 141  0
                     Map metaInfo = new HashMap();
 142  
                     //By setting the connectorName we ensure that only one connector is created for each iBean
 143  0
                     metaInfo.put("connectorName", metaData.getClazz().getSimpleName() + "." + scheme); //RM*  THis affects the connector name generation + "#" + target.hashCode());
 144  
 
 145  0
                     for (Iterator iterator = c.iterator(); iterator.hasNext();)
 146  
                     {
 147  0
                         EndpointAnnotationParser parser = (EndpointAnnotationParser) iterator.next();
 148  0
                         if (parser.supports(metaData.getAnnotation(), metaData.getClazz(), metaData.getMember()))
 149  
                         {
 150  
                             InterfaceBinding binding;
 151  0
                             Method method = (Method) metaData.getMember();
 152  0
                             boolean callChannel = false;
 153  
                             Annotation ann;
 154  
                             //This is a little messy, but we need to detect whether we are doing a Mule 'send' or Mule 'request' call.
 155  
                             //Request calls get data from a resource such as DB, email inbox or message queue. These types of request will
 156  
                             //not have any payload or headers defined.
 157  
                             //The other way to handle this is to introduce a new annotation to explicitly handle this (See the Get annotation).
 158  
                             //The issue is it may be difficult for the user to understand the difference between @Call and @Get. Instead we figure it out
 159  
                             //here.
 160  0
                             for (int x = 0; x < method.getParameterAnnotations().length; x++)
 161  
                             {
 162  0
                                 ann = method.getParameterAnnotations()[x][0];
 163  0
                                 if (ann.annotationType().equals(Body.class) ||
 164  
                                         ann.annotationType().equals(BodyParam.class) ||
 165  
                                         ann.annotationType().equals(HeaderParam.class))
 166  
                                 {
 167  
 
 168  0
                                     callChannel = true;
 169  
 
 170  0
                                     break;
 171  
                                 }
 172  
                             }
 173  
                             //TODO remove the HTTP hack above. Its required becuase HTTP request on the dispatcher
 174  
                             //don't honour authenitcation for some reason.  Also even though there may not be any headers
 175  
                             //defined we still need to attach some headers to the HTTP method. This is very difficult when
 176  
                             //using request
 177  0
                             if (callChannel || http)
 178  
                             {
 179  0
                                 OutboundEndpoint endpoint = parser.parseOutboundEndpoint(metaData.getAnnotation(), metaInfo);
 180  0
                                 binding = new CallInterfaceBinding(this.flow);
 181  0
                                 binding.setEndpoint(endpoint);
 182  0
                             }
 183  
                             else
 184  
                             {
 185  0
                                 InboundEndpoint endpoint = parser.parseInboundEndpoint(metaData.getAnnotation(), Collections.EMPTY_MAP);
 186  0
                                 binding = new DynamicRequestInterfaceBinding();
 187  0
                                 binding.setEndpoint(endpoint);
 188  
                             }
 189  
 
 190  0
                             binding.setInterface(getInterface());
 191  0
                             binding.setMethod(metaData.getMember().toString());
 192  0
                             invoker.getCallHandler().addRouterForInterface(binding);
 193  
 
 194  
                         }
 195  0
                     }
 196  0
                 }
 197  0
                 else if (metaData.getAnnotation() instanceof Template)
 198  
                 {
 199  0
                     evals.put(metaData.getMember().toString(), ((Template) metaData.getAnnotation()).value());
 200  
                 }
 201  
             }
 202  
 
 203  0
             if (evals.size() > 0)
 204  
             {
 205  0
                 invoker.getTemplateHandler().setEvals(evals);
 206  
             }
 207  
 
 208  0
             Object proxy = Proxy.newProxyInstance(getInterface().getClassLoader(), new Class[]{getInterface()}, createInvocationHandler());
 209  0
             if (logger.isDebugEnabled())
 210  
             {
 211  0
                 logger.debug("Have proxy?: " + (null != proxy));
 212  
             }
 213  0
             return proxy;
 214  
 
 215  
         }
 216  0
         catch (Exception e)
 217  
         {
 218  0
             throw new MuleRuntimeException(CoreMessages.failedToCreateProxyFor(target), e);
 219  
         }
 220  
     }
 221  
 
 222  
     public void setEndpoint(ImmutableEndpoint e)
 223  
     {
 224  0
         endpoint = (OutboundEndpoint) e;
 225  0
     }
 226  
 
 227  
     public String toString()
 228  
     {
 229  0
         final StringBuffer sb = new StringBuffer();
 230  0
         sb.append("IBeanBinding");
 231  0
         sb.append(", interface=").append(interfaceClass);
 232  0
         sb.append('}');
 233  0
         return sb.toString();
 234  
     }
 235  
 
 236  
     public ImmutableEndpoint getEndpoint()
 237  
     {
 238  0
         return endpoint;
 239  
     }
 240  
 
 241  
     protected InvocationHandler createInvocationHandler() throws IBeansException
 242  
     {
 243  0
         return new IntegrationBeanInvocationHandler(interfaceClass, plugin);
 244  
     }
 245  
 }