From e5b7380c874745c989d1816b8f552504f038e1bc Mon Sep 17 00:00:00 2001 From: lresende Date: Thu, 26 Sep 2013 20:33:20 +0000 Subject: 2.0 branch for possible maintenance release git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1526672 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/oasisopen/sca/client/SCAClientFactory.java | 151 ++++++++++ .../sca/client/SCAClientFactoryFinder.java | 36 +++ .../client/impl/SCAClientFactoryFinderImpl.java | 308 +++++++++++++++++++++ 3 files changed, 495 insertions(+) create mode 100644 sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactory.java create mode 100644 sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactoryFinder.java create mode 100644 sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/impl/SCAClientFactoryFinderImpl.java (limited to 'sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client') diff --git a/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactory.java b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactory.java new file mode 100644 index 0000000000..0922bf3e64 --- /dev/null +++ b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactory.java @@ -0,0 +1,151 @@ +/* + * Copyright(C) OASIS(R) 2005,2010. All Rights Reserved. + * OASIS trademark, IPR and other policies apply. + */ +package org.oasisopen.sca.client; + +import java.net.URI; +import java.util.Properties; + +import org.oasisopen.sca.NoSuchDomainException; +import org.oasisopen.sca.NoSuchServiceException; +import org.oasisopen.sca.client.SCAClientFactoryFinder; +import org.oasisopen.sca.client.impl.SCAClientFactoryFinderImpl; + +/** + * The SCAClientFactory can be used by non-SCA managed code to + * lookup services that exist in a SCA Domain. + * + * @see SCAClientFactoryFinderImpl + * + * @author OASIS Open + */ + +public abstract class SCAClientFactory { + + /** + * The SCAClientFactoryFinder. + * Provides a means by which a provider of an SCAClientFactory + * implementation can inject a factory finder implementation into + * the abstract SCAClientFactory class - once this is done, future + * invocations of the SCAClientFactory use the injected factory + * finder to locate and return an instance of a subclass of + * SCAClientFactory. + */ + protected static SCAClientFactoryFinder factoryFinder; + /** + * The Domain URI of the SCA Domain which is accessed by this + * SCAClientFactory + */ + private URI domainURI; + + /** + * Prevent concrete subclasses from using the no-arg constructor + */ + private SCAClientFactory() { + } + + /** + * Constructor used by concrete subclasses + * @param domainURI - The Domain URI of the Domain accessed via this + * SCAClientFactory + */ + protected SCAClientFactory(URI domainURI) + throws NoSuchDomainException { + this.domainURI = domainURI; + } + + /** + * Gets the Domain URI of the Domain accessed via this SCAClientFactory + * @return - the URI for the Domain + */ + protected URI getDomainURI() { + return domainURI; + } + + + /** + * Creates a new instance of the SCAClientFactory that can be + * used to lookup SCA Services. + * + * @param domainURI URI of the target domain for the SCAClientFactory + * @return A new SCAClientFactory + */ + public static SCAClientFactory newInstance( URI domainURI ) + throws NoSuchDomainException { + return newInstance(null, null, domainURI); + } + + /** + * Creates a new instance of the SCAClientFactory that can be + * used to lookup SCA Services. + * + * @param properties Properties that may be used when + * creating a new instance of the SCAClientFactory + * @param domainURI URI of the target domain for the SCAClientFactory + * @return A new SCAClientFactory instance + */ + public static SCAClientFactory newInstance(Properties properties, + URI domainURI) + throws NoSuchDomainException { + return newInstance(properties, null, domainURI); + } + + /** + * Creates a new instance of the SCAClientFactory that can be + * used to lookup SCA Services. + * + * @param classLoader ClassLoader that may be used when + * creating a new instance of the SCAClientFactory + * @param domainURI URI of the target domain for the SCAClientFactory + * @return A new SCAClientFactory instance + */ + public static SCAClientFactory newInstance(ClassLoader classLoader, + URI domainURI) + throws NoSuchDomainException { + return newInstance(null, classLoader, domainURI); + } + + /** + * Creates a new instance of the SCAClientFactory that can be + * used to lookup SCA Services. + * + * @param properties Properties that may be used when + * creating a new instance of the SCAClientFactory + * @param classLoader ClassLoader that may be used when + * creating a new instance of the SCAClientFactory + * @param domainURI URI of the target domain for the SCAClientFactory + * @return A new SCAClientFactory instance + */ + public static SCAClientFactory newInstance(Properties properties, + ClassLoader classLoader, + URI domainURI) + throws NoSuchDomainException { + final SCAClientFactoryFinder finder = + factoryFinder != null ? factoryFinder : + new SCAClientFactoryFinderImpl(); + final SCAClientFactory factory + = finder.find(properties, classLoader, domainURI); + return factory; + } + + /** + * Returns a reference proxy that implements the business interface + * of a service in the SCA Domain handled by this SCAClientFactory + * + * @param serviceURI the relative URI of the target service. Takes the + * form componentName/serviceName. + * Can also take the extended form componentName/serviceName/bindingName + * to use a specific binding of the target service + * + * @param interfaze The business interface class of the service in the + * domain + * @param The business interface class of the service in the domain + * + * @return a proxy to the target service, in the specified SCA Domain + * that implements the business interface . + * @throws NoSuchServiceException Service requested was not found + */ + public abstract T getService(Class interfaze, String serviceURI) + throws NoSuchServiceException; +} diff --git a/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactoryFinder.java b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactoryFinder.java new file mode 100644 index 0000000000..c6bcfd6c28 --- /dev/null +++ b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/SCAClientFactoryFinder.java @@ -0,0 +1,36 @@ +/* + * Copyright(C) OASIS(R) 2005,2010. All Rights Reserved. + * OASIS trademark, IPR and other policies apply. + */ + +package org.oasisopen.sca.client; + +import java.net.URI; +import java.util.Properties; + +import org.oasisopen.sca.NoSuchDomainException; + +/** + * A Service Provider Interface representing a SCAClientFactory finder. + * SCA provides a default reference implementation of this interface. + * SCA runtime vendors can create alternative implementations of this + * interface that use different class loading or lookup mechanisms. + */ +public interface SCAClientFactoryFinder { + + /** + * Method for finding the SCAClientFactory for a given Domain URI using + * a specified set of properties and a a specified ClassLoader + * @param properties - properties to use - may be null + * @param classLoader - ClassLoader to use - may be null + * @param domainURI - the Domain URI - must be a valid SCA Domain URI + * @return - the SCAClientFactory or null if the factory could not be + * @throws - NoSuchDomainException if the domainURI does not reference + * a valid SCA Domain + * found + */ + SCAClientFactory find(Properties properties, + ClassLoader classLoader, + URI domainURI ) + throws NoSuchDomainException ; +} diff --git a/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/impl/SCAClientFactoryFinderImpl.java b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/impl/SCAClientFactoryFinderImpl.java new file mode 100644 index 0000000000..14a02c8b8f --- /dev/null +++ b/sca-java-2.x/branches/2.0/modules/sca-api/src/main/java/org/oasisopen/sca/client/impl/SCAClientFactoryFinderImpl.java @@ -0,0 +1,308 @@ +/* + * Copyright(C) OASIS(R) 2005,2010. All Rights Reserved. + * OASIS trademark, IPR and other policies apply. + */ +package org.oasisopen.sca.client.impl; + +import org.oasisopen.sca.client.SCAClientFactoryFinder; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Constructor; +import java.net.URI; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Properties; + +import org.oasisopen.sca.NoSuchDomainException; +import org.oasisopen.sca.ServiceRuntimeException; +import org.oasisopen.sca.client.SCAClientFactory; + +/** + * This is a default implementation of an SCAClientFactoryFinder which is + * used to find an implementation of the SCAClientFactory interface. + * + * @see SCAClientFactoryFinder + * @see SCAClientFactory + * + * @author OASIS Open + */ +public class SCAClientFactoryFinderImpl implements SCAClientFactoryFinder { + + /** + * The name of the System Property used to determine the SPI + * implementation to use for the SCAClientFactory. + */ + private static final String SCA_CLIENT_FACTORY_PROVIDER_KEY = + SCAClientFactory.class.getName(); + + /** + * The name of the file loaded from the ClassPath to determine + * the SPI implementation to use for the SCAClientFactory. + */ + private static final String SCA_CLIENT_FACTORY_PROVIDER_META_INF_SERVICE + = "META-INF/services/" + SCA_CLIENT_FACTORY_PROVIDER_KEY; + + /** + * Public Constructor + */ + public SCAClientFactoryFinderImpl() { + } + + /** + * Creates an instance of the SCAClientFactorySPI implementation. + * This discovers the SCAClientFactorySPI Implementation and instantiates + * the provider's implementation. + * + * @param properties Properties that may be used when creating a new + * instance of the SCAClient + * @param classLoader ClassLoader that may be used when creating a new + * instance of the SCAClient + * @param domainURI URI for the Domain to which this client instance is connected + * @return new instance of the SCAClientFactory + * @throws ServiceRuntimeException Failed to create SCAClientFactory + * Implementation. + */ + public SCAClientFactory find(Properties properties, + ClassLoader classLoader, + URI domainURI ) + throws NoSuchDomainException, ServiceRuntimeException { + if (classLoader == null) { + classLoader = getThreadContextClassLoader (); + } + final String factoryImplClassName = + discoverProviderFactoryImplClass(properties, classLoader); + final Class factoryImplClass + = loadProviderFactoryClass(factoryImplClassName, + classLoader); + final SCAClientFactory factory = + instantiateSCAClientFactoryClass(factoryImplClass, + domainURI, properties ); + return factory; + } + + /** + * Gets the Context ClassLoader for the current Thread. + * + * @return The Context ClassLoader for the current Thread. + */ + private static ClassLoader getThreadContextClassLoader () { + return AccessController.doPrivileged( + new PrivilegedAction() { + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + }); + } + + /** + * Attempts to discover the class name for the SCAClientFactorySPI + * implementation from the specified Properties, the System Properties + * or the specified ClassLoader. + * + * @param properties Properties that may be used when creating a new + * instance of the SCAClient + * @param classLoader ClassLoader that may be used when creating a new + * instance of the SCAClient + * @return The class name of the SCAClientFactorySPI implementation + * @throw ServiceRuntimeException Failed to find implementation for + * SCAClientFactorySPI. + */ + private static String + discoverProviderFactoryImplClass(Properties properties, + ClassLoader classLoader) + throws ServiceRuntimeException { + String providerClassName = + checkPropertiesForSPIClassName(properties); + if (providerClassName != null) { + return providerClassName; + } + + providerClassName = + checkPropertiesForSPIClassName(System.getProperties()); + if (providerClassName != null) { + return providerClassName; + } + + providerClassName = checkMETAINFServicesForSPIClassName(classLoader); + if (providerClassName == null) { + throw new ServiceRuntimeException( + "Failed to find implementation for SCAClientFactory"); + } + + return providerClassName; + } + + /** + * Attempts to find the class name for the SCAClientFactorySPI + * implementation from the specified Properties. + * + * @param properties Properties that may be used when creating a new + * instance of the SCAClient + * @return The class name for the SCAClientFactorySPI implementation + * or null if not found. + */ + private static String + checkPropertiesForSPIClassName(Properties properties) { + if (properties == null) { + return null; + } + + final String providerClassName = + properties.getProperty(SCA_CLIENT_FACTORY_PROVIDER_KEY); + if (providerClassName != null && providerClassName.length() > 0) { + return providerClassName; + } + + return null; + } + + /** + * Attempts to find the class name for the SCAClientFactorySPI + * implementation from the META-INF/services directory + * + * @param cl ClassLoader that may be used when creating a new + * instance of the SCAClient + * @return The class name for the SCAClientFactorySPI implementation or + * null if not found. + */ + private static String checkMETAINFServicesForSPIClassName(ClassLoader cl) + { + final URL url = + cl.getResource(SCA_CLIENT_FACTORY_PROVIDER_META_INF_SERVICE); + if (url == null) { + return null; + } + + InputStream in = null; + try { + in = url.openStream(); + BufferedReader reader = null; + try { + reader = + new BufferedReader(new InputStreamReader(in, "UTF-8")); + + String line; + while ((line = readNextLine(reader)) != null) { + if (!line.startsWith("#") && line.length() > 0) { + return line; + } + } + + return null; + } finally { + closeStream(reader); + } + } catch (IOException ex) { + throw new ServiceRuntimeException( + "Failed to discover SCAClientFactory provider", ex); + } finally { + closeStream(in); + } + } + + /** + * Reads the next line from the reader and returns the trimmed version + * of that line + * + * @param reader The reader from which to read the next line + * @return The trimmed next line or null if the end of the + * stream has been reached + * @throws IOException I/O error occurred while reading from Reader + */ + private static String readNextLine(BufferedReader reader) + throws IOException { + + String line = reader.readLine(); + if (line != null) { + line = line.trim(); + } + return line; + } + + /** + * Loads the specified SCAClientFactory Implementation class. + * + * @param factoryImplClassName The name of the SCAClientFactory + * Implementation class to load + * @param classLoader ClassLoader that may be used when creating a new + * instance of the SCAClient + * @return The specified SCAClientFactory Implementation class + * @throws ServiceRuntimeException Failed to load the SCAClientFactory + * Implementation class + */ + private static Class + loadProviderFactoryClass(String factoryImplClassName, + ClassLoader classLoader) + throws ServiceRuntimeException { + + try { + final Class providerClass = + classLoader.loadClass(factoryImplClassName); + final Class providerFactoryClass = + providerClass.asSubclass(SCAClientFactory.class); + return providerFactoryClass; + } catch (ClassNotFoundException ex) { + throw new ServiceRuntimeException( + "Failed to load SCAClientFactory implementation class " + + factoryImplClassName, ex); + } catch (ClassCastException ex) { + throw new ServiceRuntimeException( + "Loaded SCAClientFactory implementation class " + + factoryImplClassName + + " is not a subclass of " + + SCAClientFactory.class.getName() , ex); + } + } + + /** + * Instantiate an instance of the specified SCAClientFactorySPI + * Implementation class. + * + * @param factoryImplClass The SCAClientFactorySPI Implementation + * class to instantiate. + * @param domainURI URI for the Domain to which this client instance is connected + * @param properties Properties that may be used when creating a new + * instance of the SCAClient + * @return An instance of the SCAClientFactorySPI Implementation class + * @throws ServiceRuntimeException Failed to instantiate the specified + * specified SCAClientFactorySPI Implementation class + */ + private static SCAClientFactory instantiateSCAClientFactoryClass( + Class factoryImplClass, + URI domainURI, Properties properties) + throws NoSuchDomainException, ServiceRuntimeException { + + try { + Constructor URIConstructor = + factoryImplClass.getConstructor(URI.class, Properties.class); + SCAClientFactory provider = + URIConstructor.newInstance( domainURI, properties ); + return provider; + } catch (Throwable ex) { + throw new ServiceRuntimeException( + "Failed to instantiate SCAClientFactory implementation class " + + factoryImplClass, ex); + } + } + + /** + * Utility method for closing Closeable Object. + * + * @param closeable The Object to close. + */ + private static void closeStream(Closeable closeable) { + if (closeable != null) { + try{ + closeable.close(); + } catch (IOException ex) { + throw new ServiceRuntimeException("Failed to close stream", + ex); + } + } + } +} -- cgit v1.2.3