[dna-commits] DNA SVN: r350 - in trunk/dna-common/src: test/java/org/jboss/dna/common/component and 1 other directory.

dna-commits at lists.jboss.org dna-commits at lists.jboss.org
Wed Jul 9 17:20:54 EDT 2008


Author: rhauch
Date: 2008-07-09 17:20:54 -0400 (Wed, 09 Jul 2008)
New Revision: 350

Modified:
   trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java
   trunk/dna-common/src/test/java/org/jboss/dna/common/component/ComponentLibraryTest.java
Log:
DNA-176 - Changing class loader factory on ComponentLibrary should update the instances 
http://jira.jboss.com/jira/browse/DNA-176

Added method to explicitly refresh the instances, and should automatically do this when setting the class loader factory.

Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java	2008-07-09 20:37:01 UTC (rev 349)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java	2008-07-09 21:20:54 UTC (rev 350)
@@ -37,11 +37,11 @@
 /**
  * Maintains the list of component instances for the system. This class does not actively update the component configurations, but
  * is designed to properly maintain the sequencer instances when those configurations are changed by other callers. If the
- * components are subclasses of {@link Component}, then they will be
- * {@link Component#setConfiguration(ComponentConfig) configured} with the appropriate configuration.
+ * components are subclasses of {@link Component}, then they will be {@link Component#setConfiguration(ComponentConfig)
+ * configured} with the appropriate configuration.
  * <p>
- * Therefore, this library does guarantee that the {@link #getInstances() instances} at the time they are
- * {@link #getInstances() obtained} are always reflected by the configurations.
+ * Therefore, this library does guarantee that the {@link #getInstances() instances} at the time they are {@link #getInstances()
+ * obtained} are always reflected by the configurations.
  * </p>
  * 
  * @author Randall Hauch
@@ -52,9 +52,8 @@
 public class ComponentLibrary<ComponentType, ConfigType extends ComponentConfig> {
 
     /**
-     * Class loader factory instance that always returns the
-     * {@link Thread#getContextClassLoader() current thread's context class loader} (if not null) or component library's class
-     * loader.
+     * Class loader factory instance that always returns the {@link Thread#getContextClassLoader() current thread's context class
+     * loader} (if not null) or component library's class loader.
      */
     public static final ClassLoaderFactory DEFAULT = new StandardClassLoaderFactory(ComponentLibrary.class.getClassLoader());
 
@@ -81,9 +80,8 @@
 
     /**
      * Get the class loader factory that should be used to load the component classes. Unless changed, the library uses the
-     * {@link #DEFAULT default} class loader factory, which uses the
-     * {@link Thread#getContextClassLoader() current thread's context class loader} if not null or the class loader that loaded
-     * the library class.
+     * {@link #DEFAULT default} class loader factory, which uses the {@link Thread#getContextClassLoader() current thread's
+     * context class loader} if not null or the class loader that loaded the library class.
      * 
      * @return the class loader factory; never null
      * @see #setClassLoaderFactory(ClassLoaderFactory)
@@ -94,9 +92,8 @@
 
     /**
      * Set the Maven Repository that should be used to load the sequencer classes. Unless changed, the library uses the
-     * {@link #DEFAULT default} class loader factory, which uses the
-     * {@link Thread#getContextClassLoader() current thread's context class loader} if not null or the class loader that loaded
-     * the library class.
+     * {@link #DEFAULT default} class loader factory, which uses the {@link Thread#getContextClassLoader() current thread's
+     * context class loader} if not null or the class loader that loaded the library class.
      * 
      * @param classLoaderFactory the class loader factory reference, or null if the {@link #DEFAULT default class loader factory}
      *        should be used
@@ -104,11 +101,12 @@
      */
     public void setClassLoaderFactory( ClassLoaderFactory classLoaderFactory ) {
         this.classLoaderFactory.set(classLoaderFactory != null ? classLoaderFactory : DEFAULT);
+        refreshInstances();
     }
 
     /**
-     * Add the configuration for a sequencer, or update any existing one that represents the
-     * {@link ConfigType#equals(Object) same configuration}
+     * Add the configuration for a sequencer, or update any existing one that represents the {@link ConfigType#equals(Object) same
+     * configuration}
      * 
      * @param config the new configuration
      * @return true if the component was added, or false if there already was an existing and
@@ -143,7 +141,8 @@
     }
 
     /**
-     * Update the configuration for a sequencer, or add it if there is no {@link ConfigType#equals(Object) matching configuration}.
+     * Update the configuration for a sequencer, or add it if there is no {@link ConfigType#equals(Object) matching configuration}
+     * .
      * 
      * @param config the updated (or new) configuration
      * @return true if the component was updated, or false if there already was an existing and
@@ -184,6 +183,29 @@
     }
 
     /**
+     * Refresh the instances by attempting to re-instantiate each registered configuration.
+     * 
+     * @return true if at least one instance was instantiated, or false if none were
+     */
+    public boolean refreshInstances() {
+        try {
+            this.lock.lock();
+            // Loop through and create new instances for each configuration ...
+            boolean found = false;
+            int index = 0;
+            for (ConfigType config : this.configs) {
+                ComponentType instance = newInstance(config);
+                found = found || instance != null;
+                this.instances.set(index, instance);
+                ++index;
+            }
+            return found;
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    /**
      * Return the list of sequencers.
      * 
      * @return the unmodifiable list of sequencers; never null

Modified: trunk/dna-common/src/test/java/org/jboss/dna/common/component/ComponentLibraryTest.java
===================================================================
--- trunk/dna-common/src/test/java/org/jboss/dna/common/component/ComponentLibraryTest.java	2008-07-09 20:37:01 UTC (rev 349)
+++ trunk/dna-common/src/test/java/org/jboss/dna/common/component/ComponentLibraryTest.java	2008-07-09 21:20:54 UTC (rev 350)
@@ -168,4 +168,66 @@
         }
         assertThat(firstComponentB.getCounter(), is(10));
     }
+
+    @Test
+    public void shouldRefreshInstancesWhenCalledDirectly() {
+        library.add(configA);
+        library.add(configB);
+        List<SampleComponent> components = library.getInstances();
+        assertThat(components.size(), is(2));
+        assertThat(components.get(0), instanceOf(MockComponentA.class));
+        assertThat(components.get(1), instanceOf(MockComponentB.class));
+        MockComponentA firstInstanceA = (MockComponentA)components.get(0);
+        MockComponentB firstInstanceB = (MockComponentB)components.get(1);
+        assertThat(components.get(0), is(sameInstance((SampleComponent)firstInstanceA)));
+        assertThat(components.get(1), is(sameInstance((SampleComponent)firstInstanceB)));
+
+        // Refresh the instances ...
+        assertThat(library.refreshInstances(), is(true));
+
+        // Check that there are instances for each of the components ...
+        components = library.getInstances();
+        assertThat(components.size(), is(2));
+        assertThat(components.get(0), instanceOf(MockComponentA.class));
+        assertThat(components.get(1), instanceOf(MockComponentB.class));
+        MockComponentA secondInstanceA = (MockComponentA)components.get(0);
+        MockComponentB secondInstanceB = (MockComponentB)components.get(1);
+        assertThat(components.get(0), is(sameInstance((SampleComponent)secondInstanceA)));
+        assertThat(components.get(1), is(sameInstance((SampleComponent)secondInstanceB)));
+
+        // And check that the instances have changed ...
+        assertThat(firstInstanceA, is(not(sameInstance((SampleComponent)secondInstanceA))));
+        assertThat(firstInstanceB, is(not(sameInstance((SampleComponent)secondInstanceB))));
+    }
+
+    @Test
+    public void shouldRefreshInstancesWhenSettingClassLoaderFactory() {
+        library.add(configA);
+        library.add(configB);
+        List<SampleComponent> components = library.getInstances();
+        assertThat(components.size(), is(2));
+        assertThat(components.get(0), instanceOf(MockComponentA.class));
+        assertThat(components.get(1), instanceOf(MockComponentB.class));
+        MockComponentA firstInstanceA = (MockComponentA)components.get(0);
+        MockComponentB firstInstanceB = (MockComponentB)components.get(1);
+        assertThat(components.get(0), is(sameInstance((SampleComponent)firstInstanceA)));
+        assertThat(components.get(1), is(sameInstance((SampleComponent)firstInstanceB)));
+
+        // Set the class loader factory to the SAME instance, and this should always refresh the instances ...
+        library.setClassLoaderFactory(library.getClassLoaderFactory());
+
+        // Check that there are instances for each of the components ...
+        components = library.getInstances();
+        assertThat(components.size(), is(2));
+        assertThat(components.get(0), instanceOf(MockComponentA.class));
+        assertThat(components.get(1), instanceOf(MockComponentB.class));
+        MockComponentA secondInstanceA = (MockComponentA)components.get(0);
+        MockComponentB secondInstanceB = (MockComponentB)components.get(1);
+        assertThat(components.get(0), is(sameInstance((SampleComponent)secondInstanceA)));
+        assertThat(components.get(1), is(sameInstance((SampleComponent)secondInstanceB)));
+
+        // And check that the instances have changed ...
+        assertThat(firstInstanceA, is(not(sameInstance((SampleComponent)secondInstanceA))));
+        assertThat(firstInstanceB, is(not(sameInstance((SampleComponent)secondInstanceB))));
+    }
 }




More information about the dna-commits mailing list