blob: 47bee4fa6507669486781137cb2d72bae5bf3735 [file] [log] [blame]
/*
* 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.impl;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
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.Endpoint;
import org.apache.tuscany.sca.assembly.EndpointReference;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.context.CompositeContext;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.core.assembly.impl.RuntimeEndpointReferenceImpl;
import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
import org.apache.tuscany.sca.core.invocation.ProxyFactory;
import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint;
import org.apache.tuscany.sca.core.invocation.impl.AsyncJDKInvocationHandler;
import org.apache.tuscany.sca.core.invocation.impl.DOMInvokerImpl;
import org.apache.tuscany.sca.deployment.Deployer;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
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.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.ContributionDescription;
import org.apache.tuscany.sca.runtime.DOMInvoker;
import org.apache.tuscany.sca.runtime.DomainRegistry;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
import org.apache.tuscany.sca.runtime.TuscanyServiceReference;
import org.oasisopen.sca.NoSuchServiceException;
import org.oasisopen.sca.ServiceRuntimeException;
import org.oasisopen.sca.annotation.Remotable;
import org.w3c.dom.Node;
/**
* TODO: Merge this into sca-client RemoteServiceInvocationHandler
*
* All the code for creating a service proxy in this helper class as it feels like
* it doesn't all belong in the node but i can't see where to refactor it to yet.
* (perhaps its just the remote proxy bit that needs to go somewhere else?)
*/
public class ServiceHelper {
public static <T> T getService(Class<T> interfaze, String serviceURI, DomainRegistry domainRegistry, ExtensionPointRegistry extensionPointRegistry, Deployer deployer) throws NoSuchServiceException {
List<Endpoint> endpoints = domainRegistry.findEndpoint(serviceURI);
if (endpoints.size() < 1) {
throw new NoSuchServiceException(serviceURI);
}
String serviceName = null;
if (serviceURI.contains("/")) {
int i = serviceURI.indexOf("/");
if (i < serviceURI.length() - 1) {
serviceName = serviceURI.substring(i + 1);
}
}
Endpoint ep = endpoints.get(0);
if (((RuntimeComponent)ep.getComponent()).getComponentContext() != null) {
return ((RuntimeComponent)ep.getComponent()).getServiceReference(interfaze, serviceName).getService();
} else {
return getRemoteProxy(interfaze, ep, domainRegistry, extensionPointRegistry, deployer);
}
}
public static DOMInvoker getDOMInvoker(String serviceURI, DomainRegistry domainRegistry, ExtensionPointRegistry extensionPointRegistry, Deployer deployer) throws NoSuchServiceException {
List<Endpoint> endpoints = domainRegistry.findEndpoint(serviceURI);
if (endpoints.size() < 1) {
throw new NoSuchServiceException(serviceURI);
}
String serviceName = null;
if (serviceURI.contains("/")) {
int i = serviceURI.indexOf("/");
if (i < serviceURI.length() - 1) {
serviceName = serviceURI.substring(i + 1);
}
}
Endpoint ep = endpoints.get(0);
if (((RuntimeComponent)ep.getComponent()).getComponentContext() != null) {
return ((TuscanyServiceReference<?>)((RuntimeComponent)ep.getComponent()).getServiceReference(null, serviceName)).getDOMInvoker();
} else {
// throw new NoSuchServiceException(serviceURI);
return getRemoteDOMInvoker(ep, domainRegistry, extensionPointRegistry, deployer);
}
}
private static <T> T getRemoteProxy(Class<T> serviceInterface, Endpoint endpoint, DomainRegistry domainRegistry, ExtensionPointRegistry extensionPointRegistry, Deployer deployer) throws NoSuchServiceException {
FactoryExtensionPoint factories = extensionPointRegistry.getExtensionPoint(FactoryExtensionPoint.class);
AssemblyFactory assemblyFactory = factories.getFactory(AssemblyFactory.class);
JavaInterfaceFactory javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
ProxyFactory proxyFactory =
new ExtensibleProxyFactory(extensionPointRegistry.getExtensionPoint(ProxyFactoryExtensionPoint.class));
CompositeContext compositeContext =
new CompositeContext(extensionPointRegistry, domainRegistry, null, null, null,
deployer.getSystemDefinitions());
if (serviceInterface == null) {
try {
serviceInterface = (Class<T>)findInterface(endpoint, domainRegistry);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
RuntimeEndpointReference epr;
try {
epr =
createEndpointReference(javaInterfaceFactory,
compositeContext,
assemblyFactory,
endpoint,
serviceInterface);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
return proxyFactory.createProxy(serviceInterface, epr);
}
private static DOMInvoker getRemoteDOMInvoker(Endpoint endpoint, DomainRegistry domainRegistry, ExtensionPointRegistry extensionPointRegistry, Deployer deployer) throws NoSuchServiceException {
FactoryExtensionPoint factories = extensionPointRegistry.getExtensionPoint(FactoryExtensionPoint.class);
AssemblyFactory assemblyFactory = factories.getFactory(AssemblyFactory.class);
JavaInterfaceFactory javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
ProxyFactory proxyFactory =
new ExtensibleProxyFactory(extensionPointRegistry.getExtensionPoint(ProxyFactoryExtensionPoint.class));
CompositeContext compositeContext =
new CompositeContext(extensionPointRegistry, domainRegistry, null, null, null,
deployer.getSystemDefinitions());
RuntimeEndpointReference epr;
try {
epr =
createEndpointReference(javaInterfaceFactory,
compositeContext,
assemblyFactory,
endpoint,
null);
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
InterfaceContract ic;
try {
ic = (InterfaceContract)epr.getGeneratedWSDLContract(epr.getBindingInterfaceContract()).clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
ic.getInterface().resetDataBinding(Node.class.getName());
((RuntimeEndpointReferenceImpl)epr).setreferenceInterfaceContract(ic);
epr.rebuild();
AsyncJDKInvocationHandler handler = new AsyncJDKInvocationHandler(extensionPointRegistry, factories.getFactory(MessageFactory.class), null, epr);
return new DOMInvokerImpl(handler);
}
private static RuntimeEndpointReference createEndpointReference(JavaInterfaceFactory javaInterfaceFactory,
CompositeContext compositeContext,
AssemblyFactory assemblyFactory,
Endpoint endpoint,
Class<?> businessInterface)
throws CloneNotSupportedException, InvalidInterfaceException {
Component component = endpoint.getComponent();
ComponentService service = endpoint.getService();
ComponentReference componentReference = assemblyFactory.createComponentReference();
componentReference.setName("sca.client." + service.getName());
componentReference.setCallback(service.getCallback());
componentReference.getTargets().add(service);
componentReference.getPolicySets().addAll(service.getPolicySets());
componentReference.getRequiredIntents().addAll(service.getRequiredIntents());
componentReference.getBindings().add(endpoint.getBinding());
InterfaceContract interfaceContract = service.getInterfaceContract();
Service componentTypeService = service.getService();
if (componentTypeService != null && componentTypeService.getInterfaceContract() != null) {
interfaceContract = componentTypeService.getInterfaceContract();
}
interfaceContract = getInterfaceContract(javaInterfaceFactory, interfaceContract, businessInterface);
componentReference.setInterfaceContract(interfaceContract);
componentReference.setMultiplicity(Multiplicity.ONE_ONE);
// component.getReferences().add(componentReference);
// create endpoint reference
EndpointReference endpointReference = assemblyFactory.createEndpointReference();
endpointReference.setComponent(component);
endpointReference.setReference(componentReference);
endpointReference.setBinding(endpoint.getBinding());
endpointReference.setUnresolved(false);
endpointReference.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
endpointReference.setTargetEndpoint(endpoint);
componentReference.getEndpointReferences().add(endpointReference);
((RuntimeComponentReference)componentReference).setComponent((RuntimeComponent)component);
((RuntimeEndpointReference)endpointReference).bind(compositeContext);
return (RuntimeEndpointReference)endpointReference;
}
private static InterfaceContract getInterfaceContract(JavaInterfaceFactory javaInterfaceFactory,
InterfaceContract interfaceContract,
Class<?> businessInterface) throws CloneNotSupportedException,
InvalidInterfaceException {
if (businessInterface == null) {
return interfaceContract;
}
boolean compatible = false;
if (interfaceContract != null && interfaceContract.getInterface() != null) {
Interface interfaze = interfaceContract.getInterface();
if (interfaze instanceof JavaInterface) {
Class<?> cls = ((JavaInterface)interfaze).getJavaClass();
if (cls != null && businessInterface.isAssignableFrom(cls)) {
compatible = true;
}
}
}
if (!compatible) {
// The interface is not assignable from the interface contract
interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(businessInterface);
callInterface.setRemotable(true);
interfaceContract.setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
interfaceContract.setCallbackInterface(javaInterfaceFactory.createJavaInterface(callInterface
.getCallbackClass()));
}
}
return interfaceContract;
}
private static Class<?> findInterface(Endpoint endpoint, DomainRegistry domainRegistry) throws MalformedURLException, ClassNotFoundException {
Interface iface = endpoint.getService().getInterfaceContract().getInterface();
if (iface instanceof JavaInterface) {
String curi = domainRegistry.getContainingCompositesContributionURI(endpoint.getComponent().getName());
if (curi != null) {
ContributionDescription ic = domainRegistry.getInstalledContribution(curi);
ClassLoader cl = new URLClassLoader(new URL[]{new URL(ic.getURL())}, Remotable.class.getClassLoader());
return cl.loadClass(((JavaInterface)iface).getName());
}
}
return null;
}
}