Package org.apache.tuscany.binding.celtix

Source Code of org.apache.tuscany.binding.celtix.CeltixService

/*
* 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.celtix;

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import javax.jws.soap.SOAPBinding;
import javax.wsdl.Binding;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceProvider;

import org.osoa.sca.annotations.Destroy;

import org.apache.tuscany.spi.CoreRuntimeException;
import org.apache.tuscany.spi.builder.BuilderConfigException;
import org.apache.tuscany.spi.component.CompositeComponent;
import org.apache.tuscany.spi.extension.ServiceExtension;
import org.apache.tuscany.spi.wire.WireService;

import commonj.sdo.helper.TypeHelper;
import org.apache.tuscany.binding.celtix.io.SCAServerDataBindingCallback;
import org.objectweb.celtix.Bus;
import org.objectweb.celtix.bindings.BindingFactory;
import org.objectweb.celtix.bindings.DataBindingCallback;
import org.objectweb.celtix.bindings.ServerBinding;
import org.objectweb.celtix.bindings.ServerBindingEndpointCallback;
import org.objectweb.celtix.bindings.ServerDataBindingCallback;
import org.objectweb.celtix.bus.bindings.WSDLMetaDataCache;
import org.objectweb.celtix.bus.bindings.WSDLOperationInfo;
import org.objectweb.celtix.context.ObjectMessageContext;
import org.objectweb.celtix.ws.addressing.AttributedURIType;
import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
import org.xmlsoap.schemas.wsdl.http.AddressType;


/**
* An implementation of a {@link Service} configured with the Celtix binding
*
* @version $Rev: 441893 $ $Date: 2006-09-09 20:41:09 -0700 (Sat, 09 Sep 2006) $
*/
public class CeltixService extends ServiceExtension implements ServerBindingEndpointCallback {

    private Bus bus;
    private Port port;
    private Definition wsdlDef;
    private Service wsdlService;
    private WSDLMetaDataCache wsdlCache;
    private TypeHelper typeHelper;

    private Map<QName, ServerDataBindingCallback> opMap =
        new ConcurrentHashMap<QName, ServerDataBindingCallback>();


    public CeltixService(String theName,
                         Class<?> interfaze,
                         CompositeComponent parent,
                         WireService wireService,
                         WebServiceBinding binding,
                         Bus bus,
                         TypeHelper theTypeHelper) {
        super(theName, interfaze, parent, wireService);
        this.wsdlDef = binding.getWSDLDefinition();
        this.port = binding.getWSDLPort();
        this.wsdlService = binding.getWSDLService();
        this.bus = bus;
        this.wsdlCache = new WSDLMetaDataCache(wsdlDef, port);
        this.typeHelper = theTypeHelper;
    }

    public void start() {
        super.start();
        initOperationMap();
        startServerBinding();
    }

    private void startServerBinding() {
        String key = wsdlDef.getDocumentBaseURI();
        URL url;
        try {
            url = new URL(key);
        } catch (MalformedURLException e) {
            throw new CeltixServiceInitException(e);
        }

        QName qName = wsdlService.getQName();
        String portName = port.getName();
        EndpointReferenceType reference = EndpointReferenceUtils.getEndpointReference(url,qName,portName);

        AttributedURIType address = new AttributedURIType();

        String bindingId = null;
        Binding binding = port.getBinding();
        if (null != binding) {
            List list = binding.getExtensibilityElements();
            if (!list.isEmpty()) {
                bindingId = ((ExtensibilityElement) list.get(0)).getElementType().getNamespaceURI();
            }
        }
        List<?> list = port.getExtensibilityElements();
        for (Object ep : list) {
            ExtensibilityElement ext = (ExtensibilityElement) ep;
            if (ext instanceof SOAPAddress) {
                if (bindingId == null) {
                    bindingId = ((SOAPAddress) ext).getLocationURI();
                }
                address.setValue(((SOAPAddress) ext).getLocationURI());
            }
            if (ext instanceof AddressType) {
                if (bindingId == null) {
                    bindingId = ((AddressType) ext).getLocation();
                }
                address.setValue(((AddressType) ext).getLocation());
            }
        }
        if (reference.getAddress() == null) {
            //REVIST - bug in Celtix that the HTTP transport won't find the address correctly
            reference.setAddress(address);
        }
        ClassLoader previousLoader = null;
        try {
            //FIXME: This hack is because SAAJImpl uses Thread.currentThread().getContextClassLoader(),
            //this classloader is different from current classLoader.
            previousLoader = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
            BindingFactory bindingFactory = bus.getBindingManager().getBindingFactory(bindingId);
            ServerBinding serverBinding = bindingFactory.createServerBinding(reference, this);
            serverBinding.activate();
        } catch (Exception e) {
            throw new CeltixServiceInitException(e);
        } finally {
            if (previousLoader != null) {
                Thread.currentThread().setContextClassLoader(previousLoader);
            }
        }
    }

    private void initOperationMap() {
        List ops = port.getBinding().getBindingOperations();
        for (Object op1 : ops) {
            BindingOperation op = (BindingOperation) op1;
            BindingInput bindingInput = op.getBindingInput();
            List elements = bindingInput.getExtensibilityElements();
            QName qn = new QName(wsdlDef.getTargetNamespace(), op.getName());

            //In case soap:body namespace is different from targetNamespace
            for (Object element : elements) {
                if (SOAPBody.class.isInstance(element)) {
                    SOAPBody body = (SOAPBody) element;
                    if (body.getNamespaceURI() != null) {
                        qn = new QName(body.getNamespaceURI(), op.getName());
                    }
                }
            }

            ServerDataBindingCallback cb = getDataBindingCallback(qn, null, DataBindingCallback.Mode.PARTS);
            opMap.put(qn, cb);
            if (!"".equals(cb.getRequestWrapperQName().getLocalPart())) {
                opMap.put(cb.getRequestWrapperQName(), cb);
            }
        }
    }

    @Destroy
    public void stop() throws CoreRuntimeException {
        super.stop();
    }

    public ServerDataBindingCallback getDataBindingCallback(QName operationName,
                                                            ObjectMessageContext objContext,
                                                            DataBindingCallback.Mode mode) {
        if (opMap.containsKey(operationName)) {
            return opMap.get(operationName);
        }
        WSDLOperationInfo opInfo = wsdlCache.getOperationInfo(operationName.getLocalPart());
        if (opInfo == null) {
            //REVISIT - really map the operation name to a WSDL operation
            for (String opName : wsdlCache.getAllOperationInfo().keySet()) {
                if (operationName.getLocalPart().equalsIgnoreCase(opName)) {
                    opInfo = wsdlCache.getOperationInfo(opName);
                    break;
                }
            }
        }
        boolean inout = false;

        Class<?> serviceInterface = this.getInterface();
        Method meth = getMethod(serviceInterface, operationName.getLocalPart());

        Object proxy = this.getServiceInstance();

        return new SCAServerDataBindingCallback(opInfo, inout, meth, proxy, typeHelper);
    }

    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 DataBindingCallback getFaultDataBindingCallback(ObjectMessageContext objContext) {
        // REVISIT - what to do about faults
        return null;
    }

    public Map<QName, ? extends DataBindingCallback> getOperations() {
        return opMap;
    }

    public SOAPBinding.Style getStyle() {
        return wsdlCache.getStyle();
    }

    public DataBindingCallback.Mode getServiceMode() {
        return DataBindingCallback.Mode.PARTS;
    }

    public WebServiceProvider getWebServiceProvider() {
        //not needed I think
        return null;
    }

    public Executor getExecutor() {
        //Let the transport handle it (or it goes to the Bus default wq
        //if the transport cannot handle it
        return null;
    }

}
TOP

Related Classes of org.apache.tuscany.binding.celtix.CeltixService

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.