[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: Re: AW: [sdo] New HelperProvider implementation
|
Hi Frank, What about making the implementation look-up more pluggable? Attached is a modified version of SDOImplementation that provides a plug-in mechanism for looking up implementations (ImplmentationResolver). By default it behaves exactly as what you proposed. The plugin-mechanism would allow the behaviour to be changed for other environments such as OSGi. -Blaise Blaise Doughan wrote: 498C58FB.6080102@oracle.com" type="cite"> Hi Frank, |
/**
* <copyright>
*
* Service Data Objects
* Version 3.0
* Licensed Materials
*
* (c) Copyright BEA Systems, Inc., International Business Machines Corporation,
* Oracle Corporation, Primeton Technologies Ltd., Rogue Wave Software, SAP AG.,
* Software AG., Sun Microsystems, Sybase Inc., Xcalia, Zend Technologies,
* 2005-2008. All rights reserved.
*
* </copyright>
*
*/
package commonj.sdo.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.impl.ExternalizableDelegator.Resolvable;
/**
* Central access to an implementation of SDO.
*/
public abstract class SDOImplementation
{
/**
* Gets the implementation's default HelperContext.
* @return a HelperContext object
*/
public abstract HelperContext getDefaultHelperContext();
/**
* Create a new HelperContext in this implementation.
* @return a HelperContext object
*/
public abstract HelperContext createHelperContext();
private static ImplementationResolver implementationResolver;
public static ImplementationResolver getImplementationResolver() {
if(null == implementationResolver) {
implementationResolver = new DefaultImplementationResolver();
}
return implementationResolver;
}
public static void setImplementationResolver(ImplementationResolver anImplementationResolver) {
implementationResolver = anImplementationResolver;
}
public static SDOImplementation getInstance() {
return getImplementationResolver().getInstance();
}
public static SDOImplementation getInstance(String implName) {
return getImplementationResolver().getInstance(implName);
}
protected SDOImplementation()
{
}
protected abstract Resolvable resolvable();
protected abstract Resolvable resolvable(Object target);
public static interface ImplementationResolver {
/**
* The name of the system property that will be checked for an implementation name.
*/
static final String PROPERTY_NAME = "commonj.sdo.impl.SDOImplementation";
/**
* The name of the resource that is used for service location.
*/
static final String SERVICE_RESOURCE_NAME = "META-INF/services/commonj.sdo.impl.SDOImplementation";
SDOImplementation getInstance();
SDOImplementation getInstance(String implName);
}
private static class DefaultImplementationResolver implements ImplementationResolver {
/**
* Locate and instantiate the default SDOImplementation.
* @see getInstance(String)
*/
public SDOImplementation getInstance()
{
return getInstance(null);
}
/**
* Locate and instantiate an SDOImplementation.
* <p/>
* If the specified implName is not null, attempt to instantiate an implementation
* class with that name. If implName is null, then the name of the implementation to use
* is determined by the value of the "commonj.sdo.impl.SDOImplementation" system property.
* If this is not set or this code does not have permission to read it then the name
* will be retrieved from the META-INF/services/commonj.sdo.impl.SDOImplementation resource.
* <p/>
* Name lookup and class loading is done using first the Thread's current context classloader
* and then, if that is not set, not readable, or does not provide an implementation,
* using the classloader used to load the SDOImplementation class itself.
* <p/>
* @param implName The name of the implementation class.
* @return A singleton instance of the selected SDOImplementation.
*/
public SDOImplementation getInstance(String implName)
{
if (implName == null) {
implName = getImplementationName();
}
ClassLoader cl = getContextClassLoader();
if (cl != null) {
SDOImplementation impl = getInstance(cl, implName);
if (impl != null) {
return impl;
}
}
cl = SDOImplementation.class.getClassLoader();
SDOImplementation impl = getInstance(cl, implName);
if (impl != null) {
return impl;
}
return null;
}
/**
* Map from implementation classes to their corresponding singleton instances.
*/
protected final HashMap<Class, SDOImplementation> instanceMap = new HashMap<Class, SDOImplementation>();
protected SDOImplementation getInstance(ClassLoader cl, String implName)
{
try {
if (implName == null) {
implName = getImplementationName(cl);
if (implName == null)
return null;
}
Class instanceClass = cl.loadClass(implName);
SDOImplementation instance = instanceMap.get(instanceClass);
if (instance == null) {
instance = (SDOImplementation)instanceClass.newInstance();
instanceMap.put(instanceClass, instance);
}
return instance;
}
catch (Exception e)
{
return null;
}
}
protected String getImplementationName(ClassLoader cl) throws IOException
{
InputStream is = cl.getResourceAsStream(SERVICE_RESOURCE_NAME);
if (is == null) return null;
InputStreamReader in = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(in, 128);
try {
String line;
while ((line = reader.readLine()) != null) {
int i = line.indexOf('#');
if (i != -1) {
line = line.substring(0, i);
}
line = line.trim();
if (line.length() > 0) return line;
}
return null;
} finally {
reader.close();
}
}
protected String getImplementationName() {
try {
return (String)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(PROPERTY_NAME);
}
});
} catch (SecurityException e) {
return null;
}
}
protected ClassLoader getContextClassLoader() {
try {
return (ClassLoader)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return Thread.currentThread().getContextClassLoader();
}
});
} catch (SecurityException e) {
return null;
}
}
}
}
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]