Package org.apache.tuscany.binding.axis2

Source Code of org.apache.tuscany.binding.axis2.Axis2Service$InvocationContext

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.   
*/
package org.apache.tuscany.binding.axis2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.PortType;
import javax.xml.namespace.QName;

import org.apache.axiom.soap.SOAPFactory;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
import org.apache.axis2.description.WSDLToAxisServiceBuilder;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004Constants;
import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData;
import org.apache.tuscany.spi.builder.BuilderConfigException;
import org.apache.tuscany.spi.component.CompositeComponent;
import org.apache.tuscany.spi.component.WorkContext;
import org.apache.tuscany.spi.extension.ServiceExtension;
import org.apache.tuscany.spi.host.ServletHost;
import org.apache.tuscany.spi.model.ServiceContract;
import org.apache.tuscany.spi.wire.Interceptor;
import org.apache.tuscany.spi.wire.InvocationChain;
import org.apache.tuscany.spi.wire.Message;
import org.apache.tuscany.spi.wire.MessageId;
import org.apache.tuscany.spi.wire.MessageImpl;
import org.apache.tuscany.spi.wire.TargetInvoker;
import org.apache.tuscany.spi.wire.WireService;
import org.osoa.sca.annotations.Destroy;

/**
* An implementation of a {@link ServiceExtension} configured with the Axis2
* binding
*
* @version $Rev: 462960 $ $Date: 2006-10-11 14:28:18 -0700 (Wed, 11 Oct 2006) $
*/
public class Axis2Service extends ServiceExtension {
    private ServiceContract<?> serviceContract;

    private ServletHost servletHost;

    private ConfigurationContext configContext;

    private WebServiceBinding binding;

    private WorkContext workContext;

    private Map<MessageId, InvocationContext> invCtxMap = new HashMap<MessageId, InvocationContext>();

    private String serviceName;

    public Axis2Service(String theName,
                        ServiceContract<?> serviceContract,
                        CompositeComponent parent,
                        WireService wireService,
                        WebServiceBinding binding,
                        ServletHost servletHost,
                        ConfigurationContext configContext,
                        WorkContext workContext) {

        super(theName, serviceContract.getInterfaceClass(), parent, wireService);

        this.serviceContract = serviceContract;
        this.binding = binding;
        this.servletHost = servletHost;
        this.configContext = configContext;
        this.workContext = workContext;
        this.serviceName = theName;
    }

    public void start() {
        super.start();

        try {
            configContext.getAxisConfiguration().addService(createAxisService(binding));
        } catch (AxisFault e) {
            throw new Axis2BindingRunTimeException(e);
        }

        Axis2ServiceServlet servlet = new Axis2ServiceServlet();
        servlet.init(configContext);
        configContext.setContextRoot(getName());
        servletHost.registerMapping("/" + getName(), servlet);
    }

    @Destroy
    public void stop() {
        servletHost.unregisterMapping("/" + getName());
        try {
            configContext.getAxisConfiguration().removeService(getName());
        } catch (AxisFault e) {
            throw new Axis2BindingRunTimeException(e);
        }
        super.stop();
    }

    private AxisService createAxisService(WebServiceBinding wsBinding) throws AxisFault {
        Definition definition = wsBinding.getWSDLDefinition();
        WebServicePortMetaData wsdlPortInfo =
            new WebServicePortMetaData(definition, wsBinding.getWSDLPort(), null, false);

        // TODO investigate if this is 20 wsdl what todo?
        WSDLToAxisServiceBuilder builder =
            new WSDL11ToAxisServiceBuilder(definition, wsdlPortInfo.getServiceName(), wsdlPortInfo.getPort()
                .getName());
        builder.setServerSide(true);
        AxisService axisService = builder.populateService();

        axisService.setName(this.getName());
        axisService.setServiceDescription("Tuscany configured AxisService for service: '" + this.getName()
            + "'");

        // Use the existing WSDL
        Parameter wsdlParam = new Parameter(WSDLConstants.WSDL_4_J_DEFINITION, null);
        wsdlParam.setValue(definition);
        axisService.addParameter(wsdlParam);
        Parameter userWSDL = new Parameter("useOriginalwsdl", "true");
        axisService.addParameter(userWSDL);

        PortType wsdlPortType = wsdlPortInfo.getPortType();
        for (Object o : wsdlPortType.getOperations()) {
            Operation wsdlOperation = (Operation)o;
            String operationName = wsdlOperation.getName();
            QName operationQN = new QName(definition.getTargetNamespace(), operationName);

            org.apache.tuscany.spi.model.Operation<?> op = serviceContract.getOperations().get(operationName);

            MessageReceiver msgrec = null;
            boolean opIsNonBlocking = op.isNonBlocking();
            if (serviceContract.getCallbackName() != null) {
                msgrec = new Axis2ServiceInOutAsyncMessageReceiver(this, op, workContext);
            } else if (opIsNonBlocking) {
                msgrec = new Axis2ServiceInMessageReceiver(this, op);
            } else {
                msgrec = new Axis2ServiceInOutSyncMessageReceiver(this, op);
            }

            AxisOperation axisOp = axisService.getOperation(operationQN);
            if (opIsNonBlocking) {
                axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_ONLY);
            } else {
                axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_OUT);
            }
            axisOp.setMessageReceiver(msgrec);
        }

        return axisService;
    }

    public Object invokeTarget(org.apache.tuscany.spi.model.Operation<?> op, Object[] args)
        throws InvocationTargetException {
        InvocationChain chain = inboundWire.getInvocationChains().get(op);
        Interceptor headInterceptor = chain.getHeadInterceptor();
        if (headInterceptor == null) {
            try {
                // short-circuit the dispatch and invoke the target directly
                if (chain.getTargetInvoker() == null) {
                    throw new AssertionError("No target invoker [" + chain.getOperation().getName() + "]");
                }
                return chain.getTargetInvoker().invokeTarget(args);
            } catch (InvocationTargetException e) {
                // the cause was thrown by the target so throw it
                throw e;
            }
        } else {
            Object messageId = workContext.getCurrentMessageId();
            workContext.setCurrentMessageId(null);
            Object correlationId = workContext.getCurrentCorrelationId();
            workContext.setCurrentCorrelationId(null);

            Message msg = new MessageImpl();
            msg.setTargetInvoker(chain.getTargetInvoker());
            msg.setFromAddress(getFromAddress());
            if (messageId == null) {
                messageId = new MessageId();
            }
            msg.setMessageId(messageId);
            msg.setCorrelationId(correlationId);
            msg.setBody(args);
            Message resp;
            // dispatch the wire down the chain and get the response
            // TODO http://issues.apache.org/jira/browse/TUSCANY-777
            ClassLoader oldtccl = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
                resp = headInterceptor.invoke(msg);
            } finally {
                Thread.currentThread().setContextClassLoader(oldtccl);
            }
            Object body = resp.getBody();
            if (resp.isFault()) {
                throw new InvocationTargetException((Throwable)body);
            }
            return body;
        }
    }

    protected Object getFromAddress() {
        return this.serviceName;
    }

    /**
     * Get the Method from an interface matching the WSDL operation name
     */
    protected Method getMethod(Class<?> serviceInterface, String operationName) {
        // Note: this doesn't support overloaded operations
        Method[] methods = serviceInterface.getMethods();
        for (Method m : methods) {
            if (m.getName().equals(operationName)) {
                return m;
            }
            // tolerate WSDL with capatalized operation name
            StringBuilder sb = new StringBuilder(operationName);
            sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
            if (m.getName().equals(sb.toString())) {
                return m;
            }
        }
        throw new BuilderConfigException("no operation named " + operationName
            + " found on service interface: "
            + serviceInterface.getName());
    }

    public TargetInvoker createCallbackTargetInvoker(ServiceContract contract,
                                                     org.apache.tuscany.spi.model.Operation operation) {

        return new Axis2ServiceCallbackTargetInvoker(workContext, this);
    }

    public void addMapping(MessageId msgId, InvocationContext invCtx) {
        this.invCtxMap.put(msgId, invCtx);
    }

    public InvocationContext retrieveMapping(MessageId msgId) {
        return this.invCtxMap.get(msgId);
    }

    public void removeMapping(MessageId msgId) {
        this.invCtxMap.remove(msgId);
    }

    protected class InvocationContext {
        public MessageContext inMessageContext;

        public org.apache.tuscany.spi.model.Operation<?> operation;

        public SOAPFactory soapFactory;

        public CountDownLatch doneSignal;

        public InvocationContext(MessageContext messageCtx,
                                 org.apache.tuscany.spi.model.Operation<?> operation,
                                 SOAPFactory soapFactory,
                                 CountDownLatch doneSignal) {
            this.inMessageContext = messageCtx;
            this.operation = operation;
            this.soapFactory = soapFactory;
            this.doneSignal = doneSignal;
        }
    }
}
TOP

Related Classes of org.apache.tuscany.binding.axis2.Axis2Service$InvocationContext

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.