Package org.apache.tuscany.sca.core.context

Source Code of org.apache.tuscany.sca.core.context.ComponentContextImpl

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

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Collection;
import java.util.ArrayList;

import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentProperty;
import org.apache.tuscany.sca.assembly.ComponentReference;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.assembly.OptimizableBinding;
import org.apache.tuscany.sca.assembly.Reference;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.context.PropertyValueFactory;
import org.apache.tuscany.sca.context.RequestContextFactory;
import org.apache.tuscany.sca.core.assembly.CompositeActivator;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeComponentService;
import org.osoa.sca.CallableReference;
import org.osoa.sca.RequestContext;
import org.osoa.sca.ServiceReference;
import org.osoa.sca.ServiceRuntimeException;

/**
* Implementation of ComponentContext that delegates to a ComponentContextProvider.
*
* @version $Rev: 696666 $ $Date: 2008-09-18 15:54:01 +0100 (Thu, 18 Sep 2008) $
*/
public class ComponentContextImpl implements RuntimeComponentContext {
    private final RuntimeComponent component;

    private final CompositeActivator compositeActivator;
    private final RequestContextFactory requestContextFactory;
    private final ProxyFactory proxyFactory;
    private final AssemblyFactory assemblyFactory;
    private final JavaInterfaceFactory javaInterfaceFactory;

    /**
     * This is a reference to the PropertyValueFactory that is provided by the Implementation
     * that can be used to get the value from a Property Object.
     *
     * @see #setPropertyValueFactory(PropertyValueFactory)
     * @see #getProperty(Class, String)
     */
    private PropertyValueFactory propertyFactory;
   
    public ComponentContextImpl(CompositeActivator compositeActivator,
                                AssemblyFactory assemblyFactory,
                                ProxyFactory proxyFactory,
                                InterfaceContractMapper interfaceContractMapper,
                                RequestContextFactory requestContextFactory,
                                JavaInterfaceFactory javaInterfaceFactory,
                                RuntimeComponent component) {
        super();
        this.compositeActivator = compositeActivator;
        this.assemblyFactory = assemblyFactory;
        this.proxyFactory = proxyFactory;
        this.requestContextFactory = requestContextFactory;
        this.javaInterfaceFactory = javaInterfaceFactory;
        this.component = component;
    }

    public String getURI() {
        return component.getURI();
    }

    public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
        return (R)proxyFactory.cast(target);
    }

    public <B> B getService(Class<B> businessInterface, String referenceName) {
        ServiceReference<B> serviceRef = getServiceReference(businessInterface, referenceName);
        return serviceRef.getService();
    }

    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
        try {
            for (ComponentReference ref : component.getReferences()) {
                if (referenceName.equals(ref.getName())) {
                    /* ******************** Contribution for issue TUSCANY-2281 ******************** */
                    Multiplicity multiplicity = ref.getMultiplicity();
                    if( multiplicity == Multiplicity.ZERO_N || multiplicity == Multiplicity.ONE_N)
                    {
                      throw new IllegalArgumentException("Reference " + referenceName + " has multiplicity " + multiplicity);
                    }
                    /* ******************** Contribution for issue TUSCANY-2281 ******************** */
                   
                    return getServiceReference(businessInterface, (RuntimeComponentReference)ref, null);
                }
            }
            throw new ServiceRuntimeException("Reference not found: " + referenceName);
        } catch (ServiceRuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new ServiceRuntimeException(e.getMessage(), e);
        }
    }

    /**
     * The Implementation is responsible for calling this method to set the
     * PropertyValueFactory that is used to get the Property Value from
     * a Tuscany Property object.
     *  
     * @param factory The PropertyValueFactory to use
     *
     * @see #getProperty(Class, String)
     */
    public void setPropertyValueFactory(PropertyValueFactory factory) {
        propertyFactory = factory;
    }

    /**
     * Gets the value for the specified property with the specified type.
     *
     * @param type The type of the property value we are getting
     * @param propertyName The name of the property we are getting
     * @param B The class of the property value we are getting
     *
     * @throws ServiceRuntimeException If a Property for the specified propertyName
     *         is not found
     *        
     * @see #setPropertyValueFactory(PropertyValueFactory)        
     */
    public <B> B getProperty(Class<B> type, String propertyName) {
        for (ComponentProperty p : component.getProperties()) {
            if (propertyName.equals(p.getName())) {
                return propertyFactory.createPropertyValue(p, type);
            }
        }
        throw new ServiceRuntimeException("Property not found: " + propertyName);
    }

    public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface) {
        ComponentService service = ComponentContextHelper.getSingleService(component);
        try {
            return createSelfReference(businessInterface, service);
        } catch (Exception e) {
            throw new ServiceRuntimeException(e.getMessage(), e);
        }
    }

    public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, String serviceName) {
        try {
            for (ComponentService service : component.getServices()) {
                if (serviceName.equals(service.getName())) {
                    return createSelfReference(businessInterface, service);
                }
            }
            throw new ServiceRuntimeException("Service not found: " + serviceName);
        } catch (ServiceRuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new ServiceRuntimeException(e.getMessage(), e);
        }
    }

    /**
     * @param <B>
     * @param businessInterface
     * @param service
     * @return
     */
    public <B> ServiceReference<B> createSelfReference(Class<B> businessInterface, ComponentService service) {
        try {
            RuntimeComponentReference ref =
                (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
            ref.setComponent(component);
            return getServiceReference(businessInterface, ref, null);
        } catch (Exception e) {
            throw new ServiceRuntimeException(e);
        }
    }

    public RequestContext getRequestContext() {
        if (requestContextFactory != null) {
            return requestContextFactory.createRequestContext();
        } else {
            return new RequestContextImpl(proxyFactory);
        }
    }

    /**
     * @param businessInterface
     * @param reference
     * @return
     * @throws CloneNotSupportedException
     * @throws InvalidInterfaceException
     */
    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, RuntimeComponentReference reference, Binding binding) {
        try {
            RuntimeComponentReference ref = (RuntimeComponentReference)reference;
            InterfaceContract interfaceContract = reference.getInterfaceContract();
            Reference componentTypeReference = reference.getReference();
            if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
                interfaceContract = componentTypeReference.getInterfaceContract();
            }
            InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
            if (refInterfaceContract != interfaceContract) {
                ref = (RuntimeComponentReference)reference.clone();
                if (interfaceContract != null) {
                    ref.setInterfaceContract(interfaceContract);
                } else {
                    ref.setInterfaceContract(refInterfaceContract);
                }
            }
            ref.setComponent(component);
            return new ServiceReferenceImpl<B>(businessInterface, component, ref, binding, proxyFactory, compositeActivator);
        } catch (Exception e) {
            throw new ServiceRuntimeException(e);
        }
    }   

    /**
     * Bind a component reference to a component service
     * @param <B>
     * @param businessInterface
     * @param reference
     * @param service
     * @return
     * @throws CloneNotSupportedException
     * @throws InvalidInterfaceException
     */
    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface,
                                                       RuntimeComponentReference reference,
                                                       RuntimeComponent component,
                                                       RuntimeComponentService service) {
        try {
            RuntimeComponentReference ref = (RuntimeComponentReference)reference.clone();
            InterfaceContract interfaceContract = reference.getInterfaceContract();
            Reference componentTypeReference = reference.getReference();
            if (componentTypeReference != null && componentTypeReference.getInterfaceContract() != null) {
                interfaceContract = componentTypeReference.getInterfaceContract();
            }
            InterfaceContract refInterfaceContract = getInterfaceContract(interfaceContract, businessInterface);
            if (refInterfaceContract != interfaceContract) {
                ref = (RuntimeComponentReference)reference.clone();
                ref.setInterfaceContract(interfaceContract);
            }
            ref.getTargets().add(service);
            ref.getBindings().clear();
            for (Binding binding : service.getBindings()) {
                if (binding instanceof OptimizableBinding) {
                    OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
                    optimizableBinding.setTargetBinding(binding);
                    optimizableBinding.setTargetComponent(component);
                    optimizableBinding.setTargetComponentService(service);
                    ref.getBindings().add(optimizableBinding);
                } else {
                    ref.getBindings().add(binding);
                }
            }
            return new ServiceReferenceImpl<B>(businessInterface, component, ref, proxyFactory, compositeActivator);
        } catch (Exception e) {
            throw new ServiceRuntimeException(e);
        }
    }

    public <B> CallableReference<B> getCallableReference(Class<B> businessInterface,
                                                         RuntimeComponent component,
                                                         RuntimeComponentService service) {
        try {
            if (businessInterface == null) {
                InterfaceContract contract = service.getInterfaceContract();
                businessInterface = (Class<B>)((JavaInterface)contract.getInterface()).getJavaClass();
            }
            RuntimeComponentReference ref =
                (RuntimeComponentReference)createSelfReference(component, service, businessInterface);
            ref.setComponent(component);
            return new CallableReferenceImpl<B>(businessInterface, component, ref, null, proxyFactory,
                                                compositeActivator);
        } catch (Exception e) {
            throw new ServiceRuntimeException(e);
        }
    }

    /**
     * Create a self-reference for a component service
     * @param component
     * @param service
     * @throws CloneNotSupportedException
     * @throws InvalidInterfaceException
     */
    private ComponentReference createSelfReference(Component component,
                                                   ComponentService service,
                                                   Class<?> businessInterface) throws CloneNotSupportedException,
        InvalidInterfaceException {
        ComponentReference componentReference = assemblyFactory.createComponentReference();
        componentReference.setName("$self$." + service.getName());
        for (Binding binding : service.getBindings()) {
            if (binding instanceof OptimizableBinding) {
                OptimizableBinding optimizableBinding = (OptimizableBinding)((OptimizableBinding)binding).clone();
                optimizableBinding.setTargetBinding(binding);
                optimizableBinding.setTargetComponent(component);
                optimizableBinding.setTargetComponentService(service);
                componentReference.getBindings().add(optimizableBinding);
            } else {
                componentReference.getBindings().add(binding);
            }
        }

        componentReference.setCallback(service.getCallback());
        componentReference.getTargets().add(service);
        componentReference.getPolicySets().addAll(service.getPolicySets());
        componentReference.getRequiredIntents().addAll(service.getRequiredIntents());

        InterfaceContract interfaceContract = service.getInterfaceContract();
        Service componentTypeService = service.getService();
        if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
            interfaceContract = componentTypeService.getInterfaceContract();
        }
        interfaceContract = getInterfaceContract(interfaceContract, businessInterface);
        componentReference.setInterfaceContract(interfaceContract);
        componentReference.setMultiplicity(Multiplicity.ONE_ONE);
        // component.getReferences().add(componentReference);
        return componentReference;
    }

    /**
     * @param interfaceContract
     * @param businessInterface
     * @return
     * @throws CloneNotSupportedException
     * @throws InvalidInterfaceException
     */
    private InterfaceContract getInterfaceContract(InterfaceContract interfaceContract, Class<?> businessInterface)
        throws CloneNotSupportedException, InvalidInterfaceException {
        boolean compatible = false;
        if (interfaceContract != null && interfaceContract.getInterface() != null) {
            Interface interfaze = interfaceContract.getInterface();
            if (interfaze instanceof JavaInterface) {
                Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
                if (businessInterface.isAssignableFrom(cls)) {
                    compatible = true;
                }
            }
        }

        if (!compatible) {
            // The interface is not assignable from the interface contract
            interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
            JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(businessInterface);
            interfaceContract.setInterface(callInterface);
            if (callInterface.getCallbackClass() != null) {
                interfaceContract.setCallbackInterface(javaInterfaceFactory.createJavaInterface(callInterface
                    .getCallbackClass()));
            }
        }

        return interfaceContract;
    }

    /**
     * @return the compositeActivator
     */
    public CompositeActivator getCompositeActivator() {
        return compositeActivator;
    }

    /**
     * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#start(org.apache.tuscany.sca.runtime.RuntimeComponentReference)
     */
    public void start(RuntimeComponentReference reference) {
        compositeActivator.start(component, reference);
    }

    /**
     * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#read(java.io.Reader)
     */
    public RuntimeComponent read(Reader reader) throws IOException {
        RuntimeComponent component = compositeActivator.getComponentContextHelper().read(reader);
        compositeActivator.configureComponentContext(component);
        return component;
    }

    /**
     * @see org.apache.tuscany.sca.runtime.RuntimeComponentContext#write(org.apache.tuscany.sca.runtime.RuntimeComponentReference, java.io.Writer)
     */
    public void write(RuntimeComponentReference reference, Writer writer) throws IOException {
        compositeActivator.getComponentContextHelper().write(component, reference, writer);
    }

    /* ******************** Contribution for issue TUSCANY-2281 ******************** */
   
    /**
     * @see ComponentContext#getServices(Class<B>, String)
     */
    public <B> Collection<B> getServices(Class<B> businessInterface, String referenceName) {
      ArrayList<B> services = new ArrayList<B>();
      Collection<ServiceReference<B>> serviceRefs = getServiceReferences(businessInterface, referenceName);
      for (ServiceReference<B> serviceRef : serviceRefs) {
        services.add(serviceRef.getService());
      }
      return services;
    }
   
    /**
     * @see ComponentContext#getServiceReferences(Class<B>, String)
     */
    public <B> Collection<ServiceReference<B>> getServiceReferences(Class<B> businessInterface, String referenceName) {
      try {
        for (ComponentReference ref : component.getReferences()) {
          if (referenceName.equals(ref.getName())) {
            ArrayList<ServiceReference<B>> serviceRefs = new ArrayList<ServiceReference<B>>();
            for(Binding binding :  ref.getBindings())
            {
              serviceRefs.add( getServiceReference(businessInterface, (RuntimeComponentReference) ref, binding) );
            }
            return serviceRefs;
          }
        }
        throw new ServiceRuntimeException("Reference not found: " + referenceName);
      } catch (ServiceRuntimeException e) {
        throw e;
      } catch (Exception e) {
        throw new ServiceRuntimeException(e.getMessage(), e);
      }
    }
    /* ******************** Contribution for issue TUSCANY-2281 ******************** */
   
}
TOP

Related Classes of org.apache.tuscany.sca.core.context.ComponentContextImpl

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.