Package org.mule.module.ibeans.config

Source Code of org.mule.module.ibeans.config.IBeanBinding

/*
* $Id: IBeanBinding.java 22162 2011-06-09 18:23:00Z dfeist $
* -------------------------------------------------------------------------------------
* Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
*
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.module.ibeans.config;

import org.mule.DefaultMuleEvent;
import org.mule.api.EndpointAnnotationParser;
import org.mule.api.MessagingException;
import org.mule.api.MuleContext;
import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.MuleRuntimeException;
import org.mule.api.component.InterfaceBinding;
import org.mule.api.endpoint.ImmutableEndpoint;
import org.mule.api.endpoint.InboundEndpoint;
import org.mule.api.endpoint.OutboundEndpoint;
import org.mule.config.i18n.CoreMessages;
import org.mule.module.ibeans.spi.MuleCallAnnotationHandler;
import org.mule.module.ibeans.spi.MuleIBeansPlugin;
import org.mule.module.ibeans.spi.support.DynamicRequestInterfaceBinding;
import org.mule.util.annotation.AnnotationMetaData;
import org.mule.util.annotation.AnnotationUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ibeans.annotation.Call;
import org.ibeans.annotation.Template;
import org.ibeans.annotation.param.Body;
import org.ibeans.annotation.param.BodyParam;
import org.ibeans.annotation.param.HeaderParam;
import org.ibeans.api.IBeanInvoker;
import org.ibeans.api.IBeansException;
import org.ibeans.impl.IntegrationBeanInvocationHandler;
import org.ibeans.impl.InvokeAnnotationHandler;
import org.ibeans.impl.TemplateAnnotationHandler;

/**
* TODO
*/
public class IBeanBinding implements InterfaceBinding
{

    private static final Log logger = LogFactory.getLog(IBeanBinding.class);

    private Class interfaceClass;

    // The endpoint used to actually dispatch the message
    protected OutboundEndpoint endpoint;

    protected IBeanFlowConstruct flow;

    protected MuleIBeansPlugin plugin;
   
    protected MuleContext muleContext;

    public IBeanBinding(IBeanFlowConstruct flow, MuleContext muleContext, MuleIBeansPlugin plugin)
    {
        this.flow = flow;
        this.muleContext = muleContext;
        this.plugin = plugin;
    }

    public String getMethod()
    {
        throw new UnsupportedOperationException();
    }

    public void setMethod(String method)
    {
        throw new UnsupportedOperationException();
    }

    public MuleEvent process(MuleEvent event) throws MessagingException
    {
        try
        {
            return endpoint.process(new DefaultMuleEvent(event.getMessage(), endpoint.getExchangePattern(),
                event.getSession()));
        }
        catch (MessagingException e)
        {
            throw e;
        }
        catch (MuleException e)
        {
            throw new MessagingException(e.getI18nMessage(), event, e);
        }
    }

    public void setInterface(Class interfaceClass)
    {
        this.interfaceClass = interfaceClass;
    }

    public Class getInterface()
    {
        return interfaceClass;
    }

    public Object createProxy(Object target)
    {
        Map<String, String> evals = new HashMap<String, String>();
        try
        {
            IBeanInvoker<MuleCallAnnotationHandler, TemplateAnnotationHandler, InvokeAnnotationHandler> invoker = plugin.getIBeanInvoker();
            invoker.getCallHandler().setFlow(flow);

            List<AnnotationMetaData> annos = AnnotationUtils.getAllMethodAnnotations(getInterface());
            for (AnnotationMetaData metaData : annos)
            {
                if (metaData.getAnnotation() instanceof Call)
                {
                    Collection c = muleContext.getRegistry().lookupObjects(EndpointAnnotationParser.class);
                    String scheme;
                    boolean http;
                    String uri = ((Call) metaData.getAnnotation()).uri();
                    int i = uri.indexOf(":/");
                    if (i == -1)
                    {
                        scheme = "dynamic";
                    }
                    else
                    {
                        scheme = uri.substring(0, i);
                    }
                    http = scheme.contains("http");

                    Map metaInfo = new HashMap();
                    //By setting the connectorName we ensure that only one connector is created for each iBean
                    metaInfo.put("connectorName", metaData.getClazz().getSimpleName() + "." + scheme); //RM*  THis affects the connector name generation + "#" + target.hashCode());

                    for (Iterator iterator = c.iterator(); iterator.hasNext();)
                    {
                        EndpointAnnotationParser parser = (EndpointAnnotationParser) iterator.next();
                        if (parser.supports(metaData.getAnnotation(), metaData.getClazz(), metaData.getMember()))
                        {
                            InterfaceBinding binding;
                            Method method = (Method) metaData.getMember();
                            boolean callChannel = false;
                            Annotation ann;
                            //This is a little messy, but we need to detect whether we are doing a Mule 'send' or Mule 'request' call.
                            //Request calls get data from a resource such as DB, email inbox or message queue. These types of request will
                            //not have any payload or headers defined.
                            //The other way to handle this is to introduce a new annotation to explicitly handle this (See the Get annotation).
                            //The issue is it may be difficult for the user to understand the difference between @Call and @Get. Instead we figure it out
                            //here.
                            for (int x = 0; x < method.getParameterAnnotations().length; x++)
                            {
                                ann = method.getParameterAnnotations()[x][0];
                                if (ann.annotationType().equals(Body.class) ||
                                        ann.annotationType().equals(BodyParam.class) ||
                                        ann.annotationType().equals(HeaderParam.class))
                                {

                                    callChannel = true;

                                    break;
                                }
                            }
                            //TODO remove the HTTP hack above. Its required becuase HTTP request on the dispatcher
                            //don't honour authenitcation for some reason.  Also even though there may not be any headers
                            //defined we still need to attach some headers to the HTTP method. This is very difficult when
                            //using request
                            if (callChannel || http)
                            {
                                OutboundEndpoint endpoint = parser.parseOutboundEndpoint(metaData.getAnnotation(), metaInfo);
                                binding = new CallInterfaceBinding(this.flow);
                                binding.setEndpoint(endpoint);
                            }
                            else
                            {
                                InboundEndpoint endpoint = parser.parseInboundEndpoint(metaData.getAnnotation(), Collections.EMPTY_MAP);
                                binding = new DynamicRequestInterfaceBinding();
                                binding.setEndpoint(endpoint);
                            }

                            binding.setInterface(getInterface());
                            binding.setMethod(metaData.getMember().toString());
                            invoker.getCallHandler().addRouterForInterface(binding);

                        }
                    }
                }
                else if (metaData.getAnnotation() instanceof Template)
                {
                    evals.put(metaData.getMember().toString(), ((Template) metaData.getAnnotation()).value());
                }
            }

            if (evals.size() > 0)
            {
                invoker.getTemplateHandler().setEvals(evals);
            }

            Object proxy = Proxy.newProxyInstance(getInterface().getClassLoader(), new Class[]{getInterface()}, createInvocationHandler());
            if (logger.isDebugEnabled())
            {
                logger.debug("Have proxy?: " + (null != proxy));
            }
            return proxy;

        }
        catch (Exception e)
        {
            throw new MuleRuntimeException(CoreMessages.failedToCreateProxyFor(target), e);
        }
    }

    public void setEndpoint(ImmutableEndpoint e)
    {
        endpoint = (OutboundEndpoint) e;
    }

    public String toString()
    {
        final StringBuffer sb = new StringBuffer();
        sb.append("IBeanBinding");
        sb.append(", interface=").append(interfaceClass);
        sb.append('}');
        return sb.toString();
    }

    public ImmutableEndpoint getEndpoint()
    {
        return endpoint;
    }

    protected InvocationHandler createInvocationHandler() throws IBeansException
    {
        return new IntegrationBeanInvocationHandler(interfaceClass, plugin);
    }
}
TOP

Related Classes of org.mule.module.ibeans.config.IBeanBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.