[jboss-svn-commits] JBL Code SVN: r31080 - labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Jan 14 04:35:07 EST 2010
Author: mark.proctor at jboss.com
Date: 2010-01-14 04:35:06 -0500 (Thu, 14 Jan 2010)
New Revision: 31080
Added:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ChainedProperties.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/OSGiLocator.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistry.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistryImpl.java
Removed:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/
Log:
JBRULES-2351 OSGi Ready
-fiddling with service tracker
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ChainedProperties.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/ChainedProperties.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ChainedProperties.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ChainedProperties.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,246 @@
+package org.drools.util;
+
+import java.io.Externalizable;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Priority
+ *
+ * System properties, home directory, working directory, META-INF/ of optionally provided classLoader
+ * META-INF/ of Thread.currentThread().getContextClassLoader() and META-INF/ of ClassLoader.getSystemClassLoader()
+ * @author mproctor
+ *
+ */
+public class ChainedProperties
+ implements
+ Externalizable {
+
+ private List<Properties> props;
+ private List<Properties> defaultProps;
+
+ public ChainedProperties() {
+ }
+
+ public ChainedProperties(String confFileName, ClassLoader classLoader) {
+ this( confFileName,
+ classLoader,
+ true );
+ }
+
+ public ChainedProperties(String confFileName,
+ ClassLoader classLoader,
+ boolean populateDefaults) {
+
+ this.props = new ArrayList<Properties>();
+ this.defaultProps = new ArrayList<Properties>();
+
+ // Properties added in precedence order
+
+ // System defined properties always get precedence
+ addProperties( System.getProperties() );
+
+ // System property defined properties file
+ loadProperties( System.getProperty( "drools." + confFileName ),
+ this.props );
+
+ // User home properties file
+ loadProperties( System.getProperty( "user.home" ) + "/drools." + confFileName,
+ this.props );
+
+ // Working directory properties file
+ loadProperties( "drools." + confFileName,
+ this.props );
+
+// if ( classLoader == null ) {
+// classLoader = Thread.currentThread().getContextClassLoader();
+// if ( classLoader == null ) {
+// classLoader = cls.getClassLoader();
+// }
+// }
+
+ // check META-INF directories for all known ClassLoaders
+ ClassLoader confClassLoader = classLoader;
+ loadProperties( getResources( "META-INF/drools." + confFileName,
+ confClassLoader ),
+ this.props );
+ loadProperties( getResources( "/META-INF/drools." + confFileName,
+ confClassLoader ),
+ this.props );
+
+ confClassLoader = ClassLoader.getSystemClassLoader();
+ if ( confClassLoader != null && confClassLoader != classLoader ) {
+ loadProperties( getResources( "META-INF/drools." + confFileName,
+ confClassLoader ),
+ this.props );
+ loadProperties( getResources( "/META-INF/drools." + confFileName,
+ confClassLoader ),
+ this.props );
+ }
+
+ if ( !populateDefaults ) {
+ return;
+ }
+
+ // load defaults
+ confClassLoader = classLoader;
+ loadProperties( getResources( "META-INF/drools.default." + confFileName,
+ confClassLoader ),
+ this.defaultProps );
+ loadProperties( getResources( "/META-INF/drools.default." + confFileName,
+ confClassLoader ),
+ this.defaultProps );
+
+ confClassLoader = ClassLoader.getSystemClassLoader();
+ if ( confClassLoader != null && confClassLoader != classLoader ) {
+ loadProperties( getResources( "META-INF/drools.default." + confFileName,
+ confClassLoader ),
+ this.defaultProps );
+ loadProperties( getResources( "/META-INF/drools.default." + confFileName,
+ confClassLoader ),
+ this.defaultProps );
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException {
+ props = (List<Properties>) in.readObject();
+ defaultProps = (List<Properties>) in.readObject();
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject( props );
+ out.writeObject( defaultProps );
+ }
+
+ private Enumeration<URL> getResources(String name,
+ ClassLoader classLoader) {
+ Enumeration<URL> enumeration = null;
+ try {
+ enumeration = classLoader.getResources( name );
+ } catch ( IOException e ) {
+ e.printStackTrace();
+ }
+ return enumeration;
+ }
+
+ public void addProperties(Properties properties) {
+ this.props.add( properties );
+ }
+
+ public String getProperty(String key,
+ String defaultValue) {
+ String value = null;
+ for ( Properties props : this.props ) {
+ value = props.getProperty( key );
+ if ( value != null ) {
+ break;
+ }
+ }
+ if ( value == null ) {
+ for ( Properties props : this.defaultProps ) {
+ value = props.getProperty( key );
+ if ( value != null ) {
+ break;
+ }
+ }
+ }
+ return (value != null) ? value : defaultValue;
+ }
+
+ public void mapStartsWith(Map<String, String> map,
+ String startsWith,
+ boolean includeSubProperties) {
+ for ( Properties props : this.props ) {
+ mapStartsWith( map,
+ props,
+ startsWith,
+ includeSubProperties );
+ }
+
+ for ( Properties props : this.defaultProps ) {
+ mapStartsWith( map,
+ props,
+ startsWith,
+ includeSubProperties );
+ }
+ }
+
+ private void mapStartsWith(Map<String, String> map,
+ Properties properties,
+ String startsWith,
+ boolean includeSubProperties) {
+ Enumeration< ? > enumeration = properties.propertyNames();
+ while ( enumeration.hasMoreElements() ) {
+ String key = (String) enumeration.nextElement();
+ if ( key.startsWith( startsWith ) ) {
+ if ( !includeSubProperties && key.substring( startsWith.length() + 1 ).indexOf( '.' ) > 0 ) {
+ // +1 to the length, as we do allow the direct property, just not ones below it
+ // This key has sub properties beyond the given startsWith, so skip
+ continue;
+ }
+ if ( !map.containsKey( key ) ) {
+ map.put( key,
+ properties.getProperty( key ) );
+ }
+
+ }
+ }
+ }
+
+ private void loadProperties(Enumeration<URL> enumeration,
+ List<Properties> chain) {
+ if ( enumeration == null ) {
+ return;
+ }
+
+ while ( enumeration.hasMoreElements() ) {
+ URL url = (URL) enumeration.nextElement();
+ loadProperties( url,
+ chain );
+ }
+ }
+
+ private void loadProperties(String fileName,
+ List<Properties> chain) {
+ if ( fileName != null ) {
+ File file = new File( fileName );
+ if ( file != null && file.exists() ) {
+ try {
+ loadProperties( file.toURL(),
+ chain );
+ } catch ( MalformedURLException e ) {
+ throw new IllegalArgumentException( "file.toURL() failed for " + fileName + " properties value '" + file + "'" );
+ }
+ } else {
+ //throw new IllegalArgumentException( fileName + " is specified but cannot be found '" + file + "'" );
+ }
+ }
+ }
+
+ private void loadProperties(URL confURL,
+ List<Properties> chain) {
+ if ( confURL == null ) {
+ return;
+ }
+ Properties properties = new Properties();
+ try {
+ java.io.InputStream is = confURL.openStream();
+ properties.load( is );
+ is.close();
+ chain.add( properties );
+ } catch ( IOException e ) {
+ //throw new IllegalArgumentException( "Invalid URL to properties file '" + confURL.toExternalForm() + "'" );
+ }
+ }
+}
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/ClassLoaderUtil.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ClassLoaderUtil.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,35 @@
+package org.drools.util;
+
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+public class ClassLoaderUtil {
+ public static ClassLoader getClassLoader(final ClassLoader classLoader, Class cls) {
+ ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+ ClassLoader currentClassLoader = ( cls != null ) ? cls.getClassLoader() : ClassLoaderUtil.class.getClassLoader();
+ ClassLoader systemClassLoader = Class.class.getClassLoader().getSystemClassLoader();
+
+ IdentityHashMap<ClassLoader, Object> map = new IdentityHashMap<ClassLoader, Object>();
+ map.put( classLoader, null );
+ map.put( contextClassLoader, null );
+ map.put( currentClassLoader, null );
+ map.put( systemClassLoader, null );
+
+ if ( map.size() > 0 ) {
+ CompositeClassLoader cl = new CompositeClassLoader( null );
+ for ( ClassLoader entry : map.keySet() ) {
+ if ( entry != null ) {
+ cl.addClassLoader( entry );
+ }
+ }
+
+ return cl;
+
+ } else {
+ return map.keySet().iterator().next();
+ }
+
+ }
+}
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/CompositeClassLoader.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/CompositeClassLoader.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,169 @@
+package org.drools.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class CompositeClassLoader extends ClassLoader {
+ /* Assumption: modifications are really rare, but iterations are frequent. */
+ private final List<ClassLoader> classLoaders = new CopyOnWriteArrayList<ClassLoader>();
+
+ public CompositeClassLoader(final ClassLoader parentClassLoader) {
+ super( null );
+ }
+
+ public synchronized void addClassLoader(final ClassLoader classLoader) {
+ /* NB: we need synchronized here even though we use a COW list:
+ * two threads may try to add the same new class loader, so we need
+ * to protect over a bigger area than just a single iteration.
+ */
+ // don't add duplicate ClassLoaders;
+ for ( final ClassLoader cl : this.classLoaders ) {
+ if ( cl == classLoader ) {
+ return;
+ }
+ }
+ this.classLoaders.add( classLoader );
+ }
+
+ public synchronized void removeClassLoader(final ClassLoader classLoader) {
+ /* synchronized to protect against concurrent runs of
+ * addClassLoader(x) and removeClassLoader(x).
+ */
+ classLoaders.remove( classLoader );
+ }
+
+ /**
+ * This ClassLoader never has classes of it's own, so only search the child ClassLoaders
+ * and the parent ClassLoader if one is provided
+ */
+ public Class< ? > loadClass(final String name,
+ final boolean resolve) throws ClassNotFoundException {
+ // search the child ClassLoaders
+ Class< ? > cls = null;
+
+ for ( final ClassLoader classLoader : this.classLoaders ) {
+ try {
+ cls = classLoader.loadClass( name );
+ } catch ( ClassNotFoundException e ) {
+ // swallow as we need to check more classLoaders
+ }
+ if ( cls != null ) {
+ break;
+ }
+ }
+
+ if ( resolve ) {
+ resolveClass( cls );
+ }
+
+ return cls;
+ }
+
+ /**
+ * This ClassLoader never has classes of it's own, so only search the child ClassLoaders
+ * and the parent ClassLoader if one is provided
+ */
+ public InputStream getResourceAsStream(final String name) {
+ for ( final ClassLoader classLoader : this.classLoaders ) {
+ InputStream stream = classLoader.getResourceAsStream( name );
+ if ( stream != null ) {
+ return stream;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public URL getResource(String name) {
+ for ( final ClassLoader classLoader : this.classLoaders ) {
+ URL url = classLoader.getResource( name );
+ if ( url != null ) {
+ return url;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Enumeration<URL> getResources(String name) throws IOException {
+ CompositeEnumeration<URL> enumerations = new CompositeEnumeration<URL>();
+
+ for ( final ClassLoader classLoader : this.classLoaders ) {
+ Enumeration<URL> e = classLoader.getResources( name );
+ if ( e != null ) {
+ enumerations.addEnumeration( e );
+ }
+ }
+
+ if ( enumerations.size() == 0 ) {
+ return null;
+ } else {
+ return enumerations;
+ }
+ }
+
+ private static class CompositeEnumeration<URL>
+ implements
+ Enumeration<URL> {
+ private List<URL> list;
+ private Iterator<URL> it;
+
+ public void addEnumeration(Enumeration<URL> enumeration) {
+ if ( !enumeration.hasMoreElements() ) {
+ // don't add it, if it's empty
+ return;
+ }
+
+ if ( this.it != null ) {
+ throw new IllegalStateException( "cannot add more enumerations while iterator" );
+ }
+
+ if ( this.list == null ) {
+ this.list = new ArrayList<URL>();
+ }
+
+ while ( enumeration.hasMoreElements() ) {
+ this.list.add( enumeration.nextElement() );
+ }
+ }
+
+ public int size() {
+ if ( this.list == null ) {
+ return 0;
+ } else {
+ return this.list.size();
+ }
+ }
+
+ public boolean hasMoreElements() {
+ if ( this.it == null ) {
+ if ( this.list == null ) {
+ return false;
+ } else {
+ this.it = this.list.iterator();
+ }
+ }
+ return it.hasNext();
+ }
+
+ public URL nextElement() {
+ if ( this.it == null ) {
+ if ( this.list == null ) {
+ throw new NoSuchElementException();
+ } else {
+ this.it = this.list.iterator();
+ }
+ }
+ return it.next();
+ }
+ }
+}
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/OSGiLocator.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/OSGiLocator.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/OSGiLocator.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/OSGiLocator.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,169 @@
+/*
+ * Licensed 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.drools.util;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Maintains a mapping of service names to an ordered set of service
+ * providers when running in an OSGi container.
+ * <p/>
+ * It is expected that a bundle using Drools will populate this map
+ * with properties from its own ClassLoader.
+ * <p/>
+ * This is an adaptation of the technique described by Guillaume Nodet
+ * in his article<i>
+ * <a href='http://gnodet.blogspot.com/2008/05/jee-specs-in-osgi.html'>
+ * Java EE specs in OSGi</a></i>. The main changes were to add comments.
+ *
+ * @author Guillaume Nodet
+ * @author Faron Dutton
+ * @see {@linkplain http://gnodet.blogspot.com/2008/05/jee-specs-in-osgi.html}
+ */
+public final class OSGiLocator {
+
+ /**
+ * Maps a service name (the fully qualified name of the interface)
+ * to an ordered set of factories. Each factory instantiating
+ * a specific service provider (implementation).
+ */
+ private static Map<String, List<Callable<Class< ? >>>> factories;
+
+ /**
+ * Private constructor used to prevent instantiation of this
+ * utility class (i.e., Utility Pattern).
+ */
+ private OSGiLocator() {
+ super();
+ }
+
+ /**
+ * Removes the given service provider factory from the set of
+ * providers for the service.
+ *
+ * @param serviceName
+ * The fully qualified name of the service interface.
+ * @param factory
+ * A factory for creating a specific type of service
+ * provider. May be <tt>null</tt> in which case this
+ * method does nothing.
+ * @throws IllegalArgumentException if serviceName is <tt>null</tt>
+ */
+ public static synchronized void unregister(final String serviceName,
+ final Callable<Class< ? >> factory) {
+ if ( serviceName == null ) {
+ throw new IllegalArgumentException( "serviceName cannot be null" );
+ }
+ if ( factories != null ) {
+ List<Callable<Class< ? >>> l = factories.get( serviceName );
+ if ( l != null ) {
+ l.remove( factory );
+ }
+ }
+ }
+
+ /**
+ * Adds the given service provider factory to the set of
+ * providers for the service.
+ *
+ * @param serviceName
+ * The fully qualified name of the service interface.
+ * @param factory
+ * A factory for creating a specific type of service
+ * provider. May be <tt>null</tt> in which case this
+ * method does nothing.
+ * @throws IllegalArgumentException if serviceName is <tt>null</tt>
+ */
+ public static synchronized void register(final String serviceName,
+ final Callable<Class< ? >> factory) {
+ if ( serviceName == null ) {
+ throw new IllegalArgumentException( "serviceName cannot be null" );
+ }
+ if ( factory != null ) {
+ if ( factories == null ) {
+ factories = new HashMap<String, List<Callable<Class< ? >>>>();
+ }
+ List<Callable<Class< ? >>> l = factories.get( serviceName );
+ if ( l == null ) {
+ l = new ArrayList<Callable<Class< ? >>>();
+ factories.put( serviceName,
+ l );
+ }
+ l.add( factory );
+ }
+ }
+
+ /**
+ * Finds the preferred provider for the given service. The preferred
+ * provider is the last one added to the set of providers.
+ *
+ * @param serviceName
+ * The fully qualified name of the service interface.
+ * @return
+ * The last provider added for the service if any exists.
+ * Otherwise, it returns <tt>null</tt>.
+ * @throws IllegalArgumentException if serviceName is <tt>null</tt>
+ */
+ public static synchronized Class< ? > locate(final String serviceName) {
+ if ( serviceName == null ) {
+ throw new IllegalArgumentException( "serviceName cannot be null" );
+ }
+ if ( factories != null ) {
+ List<Callable<Class< ? >>> l = factories.get( serviceName );
+ if ( l != null && !l.isEmpty() ) {
+ Callable<Class< ? >> c = l.get( l.size() - 1 );
+ try {
+ return c.call();
+ } catch ( Exception e ) {
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Finds all providers for the given service.
+ *
+ * @param serviceName
+ * The fully qualified name of the service interface.
+ * @return
+ * The ordered set of providers for the service if any exists.
+ * Otherwise, it returns an empty list.
+ * @throws IllegalArgumentException if serviceName is <tt>null</tt>
+ */
+ public static synchronized List<Class< ? >> locateAll(final String serviceName) {
+ if ( serviceName == null ) {
+ throw new IllegalArgumentException( "serviceName cannot be null" );
+ }
+ List<Class< ? >> classes = new ArrayList<Class< ? >>();
+ if ( factories != null ) {
+ List<Callable<Class< ? >>> l = factories.get( serviceName );
+ if ( l != null ) {
+ for ( Callable<Class< ? >> c : l ) {
+ try {
+ classes.add( c.call() );
+ } catch ( Exception e ) {
+ }
+ }
+ }
+ }
+ return classes;
+ }
+
+}
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistry.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/ServiceRegistry.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistry.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistry.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,16 @@
+package org.drools.util;
+
+import java.util.concurrent.Callable;
+
+import org.apache.poi.hssf.record.formula.functions.T;
+
+public interface ServiceRegistry {
+
+ public <T> void registerLocator(Class<T> cls,
+ Callable<Class<T>> cal);
+
+ public void unregisterLocator(Class<T> cls);
+
+ public <T> T get(Class<T> cls);
+
+}
\ No newline at end of file
Copied: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistryImpl.java (from rev 31078, labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/internal/ServiceRegistryImpl.java)
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistryImpl.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/util/ServiceRegistryImpl.java 2010-01-14 09:35:06 UTC (rev 31080)
@@ -0,0 +1,123 @@
+/*
+ * Licensed 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.drools.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.poi.hssf.record.formula.functions.T;
+import org.drools.KnowledgeBaseProvider;
+import org.drools.builder.KnowledgeBuilderProvider;
+import org.drools.io.ResourceProvider;
+
+/**
+ * This is an internal class, not for public consumption.
+ *
+ */
+public class ServiceRegistryImpl
+ implements
+ ServiceRegistry {
+ private static ServiceRegistry instance = new ServiceRegistryImpl();
+
+ private Map<String, Callable< ? >> registry = new HashMap<String, Callable< ? >>();
+ private Map<String, Callable< ? >> defaultServices = new HashMap<String, Callable< ? >>();
+
+ public static ServiceRegistry getInstance() {
+ return ServiceRegistryImpl.instance;
+ }
+
+ public ServiceRegistryImpl() {
+ init();
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.util.internal.ServiceRegistry#registerLocator(java.lang.String, java.util.concurrent.Callable)
+ */
+ public synchronized <T> void registerLocator(Class<T> cls,
+ Callable<Class<T>> cal) {
+ this.registry.put( cls.getName(),
+ cal );
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.util.internal.ServiceRegistry#unregisterLocator(java.lang.String)
+ */
+ public synchronized void unregisterLocator(Class<T> cls) {
+ this.registry.remove( cls.getName() );
+ this.registry.put( cls.getName(), this.defaultServices.get( cls.getName() ) );
+ }
+
+ public synchronized <T> T get(Class<T> cls) {
+
+ Callable< ? > cal = this.registry.get( cls.getName() );
+ if ( cal != null ) {
+ try {
+ return cls.cast( cal.call() );
+ } catch ( Exception e ) {
+ throw new IllegalArgumentException( "Unable to instantiate service for Class '" + (cls != null ? cls.getName() : null) + "'",
+ e );
+ }
+ } else {
+ throw new IllegalArgumentException( "Unable to locate a service for Class '" + (cls != null ? cls.getName() : null) + "'" );
+ }
+ }
+
+ private void init() {
+ ReflectionInstantiator<KnowledgeBuilderProvider> kbuilderRi = new ReflectionInstantiator<KnowledgeBuilderProvider>( "org.drools.builder.impl.KnowledgeBuilderProviderImpl" );
+ registry.put( KnowledgeBuilderProvider.class.getName(),
+ kbuilderRi );
+ defaultServices.put( KnowledgeBuilderProvider.class.getName(),
+ kbuilderRi );
+
+ ReflectionInstantiator<KnowledgeBaseProvider> kbaseRi = new ReflectionInstantiator<KnowledgeBaseProvider>( "org.drools.impl.KnowledgeBaseProviderImpl" );
+ registry.put( KnowledgeBaseProvider.class.getName(),
+ kbaseRi );
+ defaultServices.put( KnowledgeBaseProvider.class.getName(),
+ kbaseRi );
+
+ ReflectionInstantiator<ResourceProvider> resourceRi = new ReflectionInstantiator<ResourceProvider>( "org.drools.io.impl.ResourceProviderImpl" );
+ registry.put( ResourceProvider.class.getName(),
+ resourceRi );
+ defaultServices.put( ResourceProvider.class.getName(),
+ resourceRi );
+ }
+
+ static class ReflectionInstantiator<V>
+ implements
+ Callable<V> {
+ private String name;
+
+ public ReflectionInstantiator(String name) {
+ this.name = name;
+ }
+
+ public V call() throws Exception {
+ return (V) newInstance( name );
+ }
+ }
+
+ static <T> T newInstance(String name) {
+ try {
+ Class<T> cls = (Class<T>) Class.forName( name );
+ return cls.newInstance();
+ } catch ( Exception e2 ) {
+ throw new IllegalArgumentException( "Unable to instantiate '" + name + "'",
+ e2 );
+ }
+ }
+
+}
More information about the jboss-svn-commits
mailing list