Package org.apache.tuscany.sca.core.assembly

Source Code of org.apache.tuscany.sca.core.assembly.RuntimeWireImpl

/*
* 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.sca.core.assembly;

import java.util.ArrayList;
import java.util.List;

import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Contract;
import org.apache.tuscany.sca.core.invocation.InvocationChainImpl;
import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.provider.ImplementationProvider;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
import org.apache.tuscany.sca.provider.ReferenceBindingProvider2;
import org.apache.tuscany.sca.runtime.EndpointReference;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.apache.tuscany.sca.runtime.RuntimeWire;
import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
import org.apache.tuscany.sca.work.WorkScheduler;

/**
* @version $Rev: 568826 $ $Date: 2007-08-23 06:27:34 +0100 (Thu, 23 Aug 2007) $
*/
public class RuntimeWireImpl implements RuntimeWire {
    private EndpointReference wireSource;
    private EndpointReference wireTarget;

    private transient RuntimeWireProcessor wireProcessor;
    private transient InterfaceContractMapper interfaceContractMapper;
    private transient WorkScheduler workScheduler;

    private List<InvocationChain> chains;

    /**
     * @param source
     * @param target
     * @param interfaceContractMapper
     * @param workScheduler
     * @param wireProcessor
     */
    public RuntimeWireImpl(EndpointReference source,
                           EndpointReference target,
                           InterfaceContractMapper interfaceContractMapper,
                           WorkScheduler workScheduler,
                           RuntimeWireProcessor wireProcessor) {
        super();
        this.wireSource = source;
        this.wireTarget = target;
        this.interfaceContractMapper = interfaceContractMapper;
        this.workScheduler = workScheduler;
        this.wireProcessor = wireProcessor;
    }

    public synchronized List<InvocationChain> getInvocationChains() {
        if (chains == null) {
            initInvocationChains();
        }
        return chains;
    }

    /**
     * Initialize the invocation chains
     */
    private void initInvocationChains() {
        chains = new ArrayList<InvocationChain>();
        InterfaceContract sourceContract = wireSource.getInterfaceContract();
        InterfaceContract targetContract = wireTarget.getInterfaceContract();

        Contract source = wireSource.getContract();
        if (source instanceof RuntimeComponentReference) {
            // It's the reference wire
            RuntimeComponentReference reference = (RuntimeComponentReference)wireSource.getContract();
            Binding refBinding = wireSource.getBinding();
            for (Operation operation : sourceContract.getInterface().getOperations()) {
                Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
                InvocationChain chain = new InvocationChainImpl(operation, targetOperation);
                if (operation.isNonBlocking()) {
                    addNonBlockingInterceptor(reference, refBinding, chain);
                }
                addBindingInterceptor(reference, refBinding, chain, operation);
                chains.add(chain);
            }
        } else {
            // It's the service wire
            RuntimeComponentService service = (RuntimeComponentService)wireTarget.getContract();
            RuntimeComponent serviceComponent = wireTarget.getComponent();
            for (Operation operation : sourceContract.getInterface().getOperations()) {
                Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
                InvocationChain chain = new InvocationChainImpl(operation, targetOperation);
                addImplementationInterceptor(serviceComponent, service, chain, targetOperation);
                chains.add(chain);
            }
        }
        wireProcessor.process(this);
    }

    public EndpointReference getSource() {
        return wireSource;
    }

    public EndpointReference getTarget() {
        return wireTarget;
    }
   
    public void setTarget(EndpointReference target) {
        this.wireTarget = target;
        this.chains = null;
    }

    /**
     * Add the interceptor for a binding
     *
     * @param reference
     * @param binding
     * @param chain
     * @param operation
     */
    private void addBindingInterceptor(ComponentReference reference,
                                       Binding binding,
                                       InvocationChain chain,
                                       Operation operation) {
        try {
            ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
            if (provider != null) {
                Invoker invoker = null;
                if (provider instanceof ReferenceBindingProvider2) {
                    invoker = ((ReferenceBindingProvider2)provider).createInvoker(operation);
                } else {
                    // must be an old provider that only has the deprecated signature
                    invoker = provider.createInvoker(operation, false);
                }
                if (invoker != null) {
                    chain.addInvoker(invoker);
                }
            }
        } catch (RuntimeException e) {
            // TODO: [rfeng] Ignore the self reference if a runtime exception happens
            if (!reference.getName().startsWith("$self$.")) {
                throw e;
            }
        }
    }

    /**
     * Add a non-blocking interceptor if the reference binding needs it
     *
     * @param reference
     * @param binding
     * @param chain
     */
    private void addNonBlockingInterceptor(ComponentReference reference, Binding binding, InvocationChain chain) {
        ReferenceBindingProvider provider = ((RuntimeComponentReference)reference).getBindingProvider(binding);
        if (provider != null) {
            boolean supportsAsyncOneWayInvocation = false;
            if (provider instanceof ReferenceBindingProvider2) {
                supportsAsyncOneWayInvocation = ((ReferenceBindingProvider2)provider).supportsAsyncOneWayInvocation();
            } else {
                // must be an old provider that doesn't have this method
            }
            if (!supportsAsyncOneWayInvocation) {
                chain.addInterceptor(new NonBlockingInterceptor(workScheduler));
            }
        }
    }

    /**
     * Add the interceptor for a component implementation
     *
     * @param component
     * @param service
     * @param chain
     * @param operation
     */
    private void addImplementationInterceptor(Component component,
                                              ComponentService service,
                                              InvocationChain chain,
                                              Operation operation) {
        ImplementationProvider provider = ((RuntimeComponent)component).getImplementationProvider();
        if (provider != null) {
            Invoker invoker = null;
            invoker = provider.createInvoker((RuntimeComponentService)service, operation);
            chain.addInvoker(invoker);
        }
    }

    /**
     * @see java.lang.Object#clone()
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        RuntimeWireImpl copy =(RuntimeWireImpl) super.clone();
        copy.wireSource = (EndpointReference) wireSource.clone();
        copy.wireTarget = (EndpointReference) wireTarget.clone();
        copy.chains = null;
        return copy;
    }
}
TOP

Related Classes of org.apache.tuscany.sca.core.assembly.RuntimeWireImpl

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.