[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