[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]