[jbosscache-commits] JBoss Cache SVN: r7481 - in core/branches/flat/src: main/java/org/jboss/starobrno/commands and 14 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Thu Jan 15 13:46:35 EST 2009


Author: manik.surtani at jboss.com
Date: 2009-01-15 13:46:35 -0500 (Thu, 15 Jan 2009)
New Revision: 7481

Added:
   core/branches/flat/src/main/java/org/jboss/starobrno/config/GlobalConfiguration.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/AbstractComponentRegistry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/GlobalComponentRegistry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/
   core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Address.java
   core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Transport.java
Removed:
   core/branches/flat/src/main/java/org/jboss/starobrno/config/SharedConfiguration.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/HierarchicalComponentRegistry.java
Modified:
   core/branches/flat/src/main/java/org/jboss/starobrno/EvictionManager.java
   core/branches/flat/src/main/java/org/jboss/starobrno/commands/CommandsFactory.java
   core/branches/flat/src/main/java/org/jboss/starobrno/config/ConfigurationComponent.java
   core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParser.java
   core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParserImpl.java
   core/branches/flat/src/main/java/org/jboss/starobrno/container/DataContainer.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentFactory.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/DefaultCacheFactory.java
   core/branches/flat/src/main/java/org/jboss/starobrno/factories/scopes/Scopes.java
   core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/InterceptorChain.java
   core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/base/CommandInterceptor.java
   core/branches/flat/src/main/java/org/jboss/starobrno/invocation/InvocationContextContainer.java
   core/branches/flat/src/main/java/org/jboss/starobrno/loader/CacheLoader.java
   core/branches/flat/src/main/java/org/jboss/starobrno/manager/CacheManager.java
   core/branches/flat/src/main/java/org/jboss/starobrno/notifications/NotifierImpl.java
   core/branches/flat/src/main/java/org/jboss/starobrno/remoting/RPCManager.java
   core/branches/flat/src/test/java/org/jboss/starobrno/factories/scopes/ScopeDetectorTest.java
Log:
Initial implementation of stuff

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/EvictionManager.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/EvictionManager.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/EvictionManager.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -11,7 +11,7 @@
  */
 @ThreadSafe
 @NonVolatile
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public interface EvictionManager
 {
    /**

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/commands/CommandsFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/commands/CommandsFactory.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/commands/CommandsFactory.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -45,7 +45,7 @@
 /**
  * @author Mircea.Markus at jboss.com
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public interface CommandsFactory
 {
    PutKeyValueCommand buildPutKeyValueCommand(Object key, Object value);

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/config/ConfigurationComponent.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/config/ConfigurationComponent.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/config/ConfigurationComponent.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -46,7 +46,7 @@
  * @version $Revision$
  * @see #testImmutability(String)
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public abstract class ConfigurationComponent implements CloneableConfigurationComponent
 {
    private static final long serialVersionUID = 4879873994727821938L;

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/config/GlobalConfiguration.java (from rev 7474, core/branches/flat/src/main/java/org/jboss/starobrno/config/SharedConfiguration.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/config/GlobalConfiguration.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/config/GlobalConfiguration.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,208 @@
+package org.jboss.starobrno.config;
+
+import org.jboss.starobrno.CacheException;
+
+import java.util.Properties;
+
+/**
+ * Configuration component that encapsulates the global configuration.
+ *
+ * @author Manik Surtani
+ */
+public class GlobalConfiguration extends ConfigurationComponent
+{
+   String asyncListenerExecutorFactoryClass;
+   String asyncSerializationExecutorFactoryClass;
+   String evictionScheduledExecutorFactoryClass;
+   String replicationQueueScheduledExecutorFactoryClass;
+   String marshallerClass;
+   String marshallVersion;
+   int objectInputStreamPoolSize;
+   int objectOutputStreamPoolSize;
+   String transportClass;
+   Properties transportProperties;
+   Configuration defaultConfiguration;
+
+   public String getAsyncListenerExecutorFactoryClass()
+   {
+      return asyncListenerExecutorFactoryClass;
+   }
+
+   public void setAsyncListenerExecutorFactoryClass(String asyncListenerExecutorFactoryClass)
+   {
+      testImmutability("asyncListenerExecutorFactoryClass");
+      this.asyncListenerExecutorFactoryClass = asyncListenerExecutorFactoryClass;
+   }
+
+   public String getAsyncSerializationExecutorFactoryClass()
+   {
+      return asyncSerializationExecutorFactoryClass;
+   }
+
+   public void setAsyncSerializationExecutorFactoryClass(String asyncSerializationExecutorFactoryClass)
+   {
+      testImmutability("asyncSerializationExecutorFactoryClass");
+      this.asyncSerializationExecutorFactoryClass = asyncSerializationExecutorFactoryClass;
+   }
+
+   public String getEvictionScheduledExecutorFactoryClass()
+   {
+      return evictionScheduledExecutorFactoryClass;
+   }
+
+   public void setEvictionScheduledExecutorFactoryClass(String evictionScheduledExecutorFactoryClass)
+   {
+      testImmutability("evictionScheduledExecutorFactoryClass");
+      this.evictionScheduledExecutorFactoryClass = evictionScheduledExecutorFactoryClass;
+   }
+
+   public String getReplicationQueueScheduledExecutorFactoryClass()
+   {
+      return replicationQueueScheduledExecutorFactoryClass;
+   }
+
+   public void setReplicationQueueScheduledExecutorFactoryClass(String replicationQueueScheduledExecutorFactoryClass)
+   {
+      testImmutability("replicationQueueScheduledExecutorFactoryClass");
+      this.replicationQueueScheduledExecutorFactoryClass = replicationQueueScheduledExecutorFactoryClass;
+   }
+
+   public String getMarshallerClass()
+   {
+      return marshallerClass;
+   }
+
+   public void setMarshallerClass(String marshallerClass)
+   {
+      testImmutability("marshallerClass");
+      this.marshallerClass = marshallerClass;
+   }
+
+   public String getMarshallVersion()
+   {
+      return marshallVersion;
+   }
+
+   public void setMarshallVersion(String marshallVersion)
+   {
+      testImmutability("marshallVersion");
+      this.marshallVersion = marshallVersion;
+   }
+
+   public int getObjectInputStreamPoolSize()
+   {
+      return objectInputStreamPoolSize;
+   }
+
+   public void setObjectInputStreamPoolSize(int objectInputStreamPoolSize)
+   {
+      testImmutability("objectInputStreamPoolSize");
+      this.objectInputStreamPoolSize = objectInputStreamPoolSize;
+   }
+
+   public int getObjectOutputStreamPoolSize()
+   {
+      return objectOutputStreamPoolSize;
+   }
+
+   public void setObjectOutputStreamPoolSize(int objectOutputStreamPoolSize)
+   {
+      testImmutability("objectOutputStreamPoolSize");
+      this.objectOutputStreamPoolSize = objectOutputStreamPoolSize;
+   }
+
+   public String getTransportClass()
+   {
+      return transportClass;
+   }
+
+   public void setTransportClass(String transportClass)
+   {
+      testImmutability("transportClass");
+      this.transportClass = transportClass;
+   }
+
+   public Properties getTransportProperties()
+   {
+      return transportProperties;
+   }
+
+   public void setTransportProperties(Properties transportProperties)
+   {
+      testImmutability("transportProperties");
+      this.transportProperties = transportProperties;
+   }
+
+   public Configuration getDefaultConfiguration()
+   {
+      return defaultConfiguration;
+   }
+
+   public void setDefaultConfiguration(Configuration defaultConfiguration)
+   {
+      testImmutability("defaultConfiguration");
+      this.defaultConfiguration = defaultConfiguration;
+   }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      GlobalConfiguration that = (GlobalConfiguration) o;
+
+      if (objectInputStreamPoolSize != that.objectInputStreamPoolSize) return false;
+      if (objectOutputStreamPoolSize != that.objectOutputStreamPoolSize) return false;
+      if (asyncListenerExecutorFactoryClass != null ? !asyncListenerExecutorFactoryClass.equals(that.asyncListenerExecutorFactoryClass) : that.asyncListenerExecutorFactoryClass != null)
+         return false;
+      if (asyncSerializationExecutorFactoryClass != null ? !asyncSerializationExecutorFactoryClass.equals(that.asyncSerializationExecutorFactoryClass) : that.asyncSerializationExecutorFactoryClass != null)
+         return false;
+      if (defaultConfiguration != null ? !defaultConfiguration.equals(that.defaultConfiguration) : that.defaultConfiguration != null)
+         return false;
+      if (evictionScheduledExecutorFactoryClass != null ? !evictionScheduledExecutorFactoryClass.equals(that.evictionScheduledExecutorFactoryClass) : that.evictionScheduledExecutorFactoryClass != null)
+         return false;
+      if (marshallVersion != null ? !marshallVersion.equals(that.marshallVersion) : that.marshallVersion != null)
+         return false;
+      if (marshallerClass != null ? !marshallerClass.equals(that.marshallerClass) : that.marshallerClass != null)
+         return false;
+      if (replicationQueueScheduledExecutorFactoryClass != null ? !replicationQueueScheduledExecutorFactoryClass.equals(that.replicationQueueScheduledExecutorFactoryClass) : that.replicationQueueScheduledExecutorFactoryClass != null)
+         return false;
+      if (transportClass != null ? !transportClass.equals(that.transportClass) : that.transportClass != null)
+         return false;
+      if (transportProperties != null ? !transportProperties.equals(that.transportProperties) : that.transportProperties != null)
+         return false;
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int result = asyncListenerExecutorFactoryClass != null ? asyncListenerExecutorFactoryClass.hashCode() : 0;
+      result = 31 * result + (asyncSerializationExecutorFactoryClass != null ? asyncSerializationExecutorFactoryClass.hashCode() : 0);
+      result = 31 * result + (evictionScheduledExecutorFactoryClass != null ? evictionScheduledExecutorFactoryClass.hashCode() : 0);
+      result = 31 * result + (replicationQueueScheduledExecutorFactoryClass != null ? replicationQueueScheduledExecutorFactoryClass.hashCode() : 0);
+      result = 31 * result + (marshallerClass != null ? marshallerClass.hashCode() : 0);
+      result = 31 * result + (marshallVersion != null ? marshallVersion.hashCode() : 0);
+      result = 31 * result + objectInputStreamPoolSize;
+      result = 31 * result + objectOutputStreamPoolSize;
+      result = 31 * result + (transportClass != null ? transportClass.hashCode() : 0);
+      result = 31 * result + (transportProperties != null ? transportProperties.hashCode() : 0);
+      result = 31 * result + (defaultConfiguration != null ? defaultConfiguration.hashCode() : 0);
+      return result;
+   }
+
+   @Override
+   public GlobalConfiguration clone()
+   {
+      try
+      {
+         return (GlobalConfiguration) super.clone();
+      }
+      catch (CloneNotSupportedException e)
+      {
+         throw new CacheException("Problems cloning configuration component!", e);
+      }
+   }
+}

Deleted: core/branches/flat/src/main/java/org/jboss/starobrno/config/SharedConfiguration.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/config/SharedConfiguration.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/config/SharedConfiguration.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -1,42 +0,0 @@
-package org.jboss.starobrno.config;
-
-/**
- * // TODO: Manik: Document this!
- *
- * @author Manik Surtani
- */
-public class SharedConfiguration extends ConfigurationComponent
-{
-   /*
-   <asyncListenerExecutor factory="org.jboss.starobrno.executors.DefaultExecutorFactory">
-            <property name="maxThreads">5</property>
-            <property name="threadNamePrefix">AsyncListenerThread</property>
-        </asyncListenerExecutor>
-
-        <asyncSerializationExecutor factory="org.jboss.starobrno.executors.DefaultExecutorFactory">
-            <property name="maxThreads">25</property>
-            <property name="threadNamePrefix">AsyncSerializationThread</property>
-        </asyncSerializationExecutor>
-
-        <evictionScheduledExecutor factory="org.jboss.starobrno.executors.DefaultScheduledExecutorFactory">
-            <property name="threadNamePrefix">EvictionThread</property>
-        </evictionScheduledExecutor>
-
-        <replicationQueueScheduledExecutor factory="org.jboss.starobrno.executors.DefaultScheduledExecutorFactory">
-            <property name="threadNamePrefix">ReplicationQueueThread</property>
-        </replicationQueueScheduledExecutor>
-
-        <jgroupsConfig configFile="udp.xml"/>
-
-        <serialization marshallerClass="org.jboss.starobrno.marshall.CacheMarshallerStarobrno" version="1.0"
-                       objectInputStreamPoolSize="100" objectOutputStreamPoolSize="100"/>
-    */
-   String asyncListenerExecutorFactoryClass;
-   String asyncSerializationExecutorFactoryClass;
-   String evictionScheduledExecutorFactoryClass;
-   String replicationQueueScheduledExecutorFactoryClass;
-   String marshallerClass;
-   String marshallVersion;
-   int objectInputStreamPoolSize;
-   int objectOutputStreamPoolSize;
-}

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParser.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParser.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParser.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -2,6 +2,7 @@
 
 import org.jboss.starobrno.config.Configuration;
 import org.jboss.starobrno.config.ConfigurationException;
+import org.jboss.starobrno.config.GlobalConfiguration;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -33,18 +34,19 @@
    void initialize(InputStream inputStream) throws IOException;
 
    /**
-    * Parses and retrieves the default configuration.  This is typically used to configure the {@link org.jboss.starobrno.manager.CacheManager}.
+    * Parses and retrieves configuration overrides for named caches.
     *
-    * @return a Configuration
+    * @return a Map of Configuration overrides keyed on cache name
     * @throws ConfigurationException if there is a problem parsing the configuration XML
     */
-   Configuration parseDefaultConfiguration() throws ConfigurationException;
+   Map<String, Configuration> parseNamedConfigurations() throws ConfigurationException;
 
    /**
-    * Parses and retrieves configuration overrides for named caches.
+    * GlobalConfiguration would also have a reference to the template default configuration, accessible via {@link org.jboss.starobrno.config.GlobalConfiguration#getDefaultConfiguration()}
+    * <p/>
+    * This is typically used to configure a {@link org.jboss.starobrno.manager.CacheManager}
     *
-    * @return a Map of Configuration overrides keyed on cache name
-    * @throws ConfigurationException if there is a problem parsing the configuration XML
+    * @return a GlobalConfiguration as parsed from the configuration file.
     */
-   Map<String, Configuration> parseNamedConfigurations() throws ConfigurationException;
+   GlobalConfiguration parseGlobalConfiguration();
 }

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParserImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParserImpl.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/config/parsing/XmlConfigurationParserImpl.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -2,6 +2,7 @@
 
 import org.jboss.starobrno.config.Configuration;
 import org.jboss.starobrno.config.ConfigurationException;
+import org.jboss.starobrno.config.GlobalConfiguration;
 import org.jboss.starobrno.util.FileLookup;
 import org.w3c.dom.Element;
 
@@ -93,6 +94,11 @@
       return namedConfigurations;
    }
 
+   public GlobalConfiguration parseGlobalConfiguration()
+   {
+      throw new RuntimeException("Implement me");
+   }
+
    private void assertInitialized()
    {
       if (!initialized)

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/container/DataContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/container/DataContainer.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/container/DataContainer.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -32,7 +32,7 @@
  * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
  * @since 3.0
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public interface DataContainer<K, V>
 {
    V get(K k);

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/factories/AbstractComponentRegistry.java (from rev 7474, core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/AbstractComponentRegistry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/AbstractComponentRegistry.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,966 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.factories;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.Version;
+import org.jboss.starobrno.CacheException;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.config.ConfigurationException;
+import org.jboss.starobrno.config.RuntimeConfig;
+import org.jboss.starobrno.factories.annotations.DefaultFactoryFor;
+import org.jboss.starobrno.factories.annotations.Destroy;
+import org.jboss.starobrno.factories.annotations.Inject;
+import org.jboss.starobrno.factories.annotations.NonVolatile;
+import org.jboss.starobrno.factories.annotations.Start;
+import org.jboss.starobrno.factories.annotations.Stop;
+import org.jboss.starobrno.factories.scopes.Scope;
+import org.jboss.starobrno.factories.scopes.Scopes;
+import org.jboss.starobrno.lifecycle.Lifecycle;
+import org.jboss.starobrno.util.BeanUtils;
+import org.jboss.starobrno.util.ReflectionUtil;
+
+import javax.management.MBeanServerFactory;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A registry where components which have been created are stored.  Components are stored as singletons, registered under
+ * a specific name.
+ * <p/>
+ * Components can be retrieved from the registry using {@link #getComponent(Class)}.
+ * <p/>
+ * Components can be registered using {@link #registerComponent(Object, Class)}, which will cause any dependencies to be
+ * wired in as well.  Components that need to be created as a result of wiring will be done using {@link #getOrCreateComponent(Class)},
+ * which will look up the default factory for the component type (factories annotated with the appropriate {@link DefaultFactoryFor} annotation.
+ * <p/>
+ * Default factories are treated as components too and will need to be wired before being used.
+ * <p/>
+ * The registry can exist in one of several states, as defined by the {@link CacheStatus} enumeration.  In terms of the cache,
+ * state changes in the following manner:
+ * <ul>
+ * <li>INSTANTIATED - when first constructed</li>
+ * <li>CONSTRUCTED - when created using the DefaultCacheFactory</li>
+ * <li>When {@link org.jboss.cache.Cache_Legacy#create()} is called, the components are rewired.</li>
+ * <li>STARTED - when {@link org.jboss.cache.Cache_Legacy#start()} is called</li>
+ * <li>STOPPED - when {@link org.jboss.cache.Cache_Legacy#stop()} is called</li>
+ * <li>DESTROYED - when {@link org.jboss.cache.Cache_Legacy#destroy()} is called.</li>
+ * </ul>
+ * <p/>
+ * Cache configuration can only be changed and will only be reinjected if the cache is not in the {@link org.jboss.cache.CacheStatus#STARTED} state.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.1.0
+ */
+ at NonVolatile
+ at Scope(Scopes.NAMED_CACHE)
+public abstract class AbstractComponentRegistry implements Lifecycle
+{
+   /**
+    * Contains class definitions of component factories that can be used to construct certain components
+    */
+   private Map<Class, Class<? extends ComponentFactory>> defaultFactories = null;
+
+   private static final Log log = LogFactory.getLog(AbstractComponentRegistry.class);
+   private static final boolean trace = log.isTraceEnabled();
+   protected static final Object NULL_COMPONENT = new Object();
+
+   // component and method containers
+   final Map<String, Component> componentLookup = new HashMap<String, Component>();
+
+   CacheStatus state = CacheStatus.INSTANTIATED;
+
+   /**
+    * Hook to shut down the cache when the JVM exits.
+    */
+   private Thread shutdownHook;
+   /**
+    * A flag that the shutdown hook sets before calling cache.stop().  Allows stop() to identify if it has been called
+    * from a shutdown hook.
+    */
+   private boolean invokedFromShutdownHook;
+
+   /**
+    * Retrieves the state of the registry
+    *
+    * @return state of the registry
+    */
+   public CacheStatus getState()
+   {
+      return state;
+   }
+
+   /**
+    * Wires an object instance with dependencies annotated with the {@link org.jboss.cache.factories.annotations.Inject} annotation, creating more components
+    * as needed based on the Configuration passed in if these additional components don't exist in the
+    * {@link ComponentRegistry}.  Strictly for components that don't otherwise live in the registry and have a lifecycle, such as Nodes.
+    *
+    * @param target object to wire
+    * @throws ConfigurationException if there is a problem wiring the instance
+    */
+   public void wireDependencies(Object target) throws ConfigurationException
+   {
+      try
+      {
+         // don't use the reflection cache for wireDependencies calls since these are not managed by the ComponentRegistry
+         // and may be invoked at any time, even after the cache starts.
+         List<Method> methods = ReflectionUtil.getAllMethods(target.getClass(), Inject.class);
+
+         // search for anything we need to inject
+         for (Method method : methods) invokeInjectionMethod(target, method);
+      }
+      catch (Exception e)
+      {
+         throw new ConfigurationException("Unable to configure component (type: " + target.getClass() + ", instance " + target + ")", e);
+      }
+   }
+
+   /**
+    * This is hard coded for now, since scanning the classpath for factories annotated with {@link org.jboss.cache.factories.annotations.DefaultFactoryFor}
+    * does not work with all class loaders.  This is a temporary solution until a more elegant one can be designed.
+    * <p/>
+    * BE SURE TO ADD ANY NEW FACTORY TYPES ANNOTATED WITH DefaultFactoryFor TO THIS SET!!
+    * <p/>
+    *
+    * @return set of known factory types.
+    */
+   private Set<Class<? extends ComponentFactory>> getHardcodedFactories()
+   {
+      Set<Class<? extends ComponentFactory>> s = new HashSet<Class<? extends ComponentFactory>>();
+      s.add(BootstrapFactory.class);
+      s.add(BuddyManagerFactory.class);
+      s.add(EmptyConstructorFactory.class);
+      s.add(InterceptorChainFactory.class);
+      s.add(RuntimeConfigAwareFactory.class);
+      s.add(TransactionManagerFactory.class);
+      s.add(ReplicationQueueFactory.class);
+      s.add(StateTransferManagerFactory.class);
+      s.add(StateTransferFactory.class);
+      s.add(NullComponentFactory.class);
+      s.add(LockManagerFactory.class);
+      s.add(DataContainerFactory.class);
+      s.add(EvictionManagerFactory.class);
+      return s;
+   }
+
+   /**
+    * Registers a component in the registry under the given type, and injects any dependencies needed.  If a component
+    * of this type already exists, it is overwritten.
+    *
+    * @param component component to register
+    * @param type      type of component
+    */
+   public void registerComponent(Object component, Class type)
+   {
+
+      String name = type.getName();
+      Component old = componentLookup.get(name);
+
+      if (old != null)
+      {
+         // if they are equal don't bother
+         if (old.instance.equals(component))
+         {
+            if (trace)
+               log.trace("Attempting to register a component equal to one that already exists under the same name (" + name + ").  Not doing anything.");
+            return;
+         }
+      }
+
+      Component c;
+      if (old != null)
+      {
+         if (trace) log.trace("Replacing old component " + old + " with new instance " + component);
+         old.instance = component;
+         old.methodsScanned = false;
+         c = old;
+
+         if (state == CacheStatus.STARTED) populateLifecycleMethods();
+      }
+      else
+      {
+         c = new Component();
+         c.name = name;
+         c.instance = component;
+         if (trace) log.trace("Registering component " + c + " under name " + name);
+         componentLookup.put(name, c);
+      }
+      c.nonVolatile = component.getClass().isAnnotationPresent(NonVolatile.class) || type.isAnnotationPresent(NonVolatile.class);
+      addComponentDependencies(c);
+      // inject dependencies for this component
+      c.injectDependencies();
+   }
+
+   /**
+    * Adds component dependencies for a given component, by populating {@link Component#injectionMethods}.
+    *
+    * @param c component to add dependencies to
+    */
+   protected void addComponentDependencies(Component c)
+   {
+      Class type = c.instance.getClass();
+      List<Method> methods = ReflectionUtil.getAllMethods(type, Inject.class);
+      c.injectionMethods.clear();
+      c.injectionMethods.addAll(methods);
+   }
+
+   @SuppressWarnings("unchecked")
+   protected void invokeInjectionMethod(Object o, Method m)
+   {
+      Class[] dependencies = m.getParameterTypes();
+      Object[] params = new Object[dependencies.length];
+
+      for (int i = 0; i < dependencies.length; i++)
+      {
+         params[i] = getOrCreateComponent(dependencies[i]);
+      }
+
+      ReflectionUtil.invokeAccessibly(o, m, params);
+   }
+
+   /**
+    * Retrieves a component if one exists, and if not, attempts to find a factory capable of constructing the component
+    * (factories annotated with the {@link DefaultFactoryFor} annotation that is capable of creating the component class).
+    * <p/>
+    * If an instance needs to be constructed, dependencies are then automatically wired into the instance, based on methods
+    * on the component type annotated with {@link Inject}.
+    * <p/>
+    * Summing it up, component retrieval happens in the following order:<br />
+    * 1.  Look for a component that has already been created and registered.
+    * 2.  Look for an appropriate component that exists in the {@link Configuration} that may be injected from an external system.
+    * 3.  Look for a class definition passed in to the {@link org.jboss.cache.config.Configuration} - such as an EvictionPolicy implementation
+    * 4.  Attempt to create it by looking for an appropriate factory (annotated with {@link DefaultFactoryFor})
+    * <p/>
+    *
+    * @param componentClass type of component to be retrieved.  Should not be null.
+    * @return a fully wired component instance, or null if one cannot be found or constructed.
+    * @throws ConfigurationException if there is a problem with consructing or wiring the instance.
+    */
+   protected <T> T getOrCreateComponent(Class<T> componentClass)
+   {
+
+      T component = getComponent(componentClass);
+
+      if (component == null)
+      {
+         // first see if this has been injected externally.
+         component = getFromConfiguration(componentClass);
+         boolean attemptedFactoryConstruction = false;
+
+         if (component == null)
+         {
+            // create this component and add it to the registry
+            ComponentFactory factory = getFactory(componentClass);
+            component = factory.construct(componentClass);
+            attemptedFactoryConstruction = true;
+
+         }
+
+         if (component != null)
+         {
+            registerComponent(component, componentClass);
+         }
+         else if (attemptedFactoryConstruction)
+         {
+            if (trace) log.trace("Registering a null for component " + componentClass.getSimpleName());
+            registerNullComponent(componentClass);
+         }
+      }
+
+      return component;
+   }
+
+   /**
+    * Retrieves a component factory instance capable of constructing components of a specified type.  If the factory doesn't
+    * exist in the registry, one is created.
+    *
+    * @param componentClass type of component to construct
+    * @return component factory capable of constructing such components
+    */
+   protected ComponentFactory getFactory(Class componentClass)
+   {
+      Map<Class, Class<? extends ComponentFactory>> defaultFactoryMap = getDefaultFactoryMap();
+      Class<? extends ComponentFactory> cfClass = defaultFactoryMap.get(componentClass);
+      if (cfClass == null)
+         throw new ConfigurationException("No registered default factory for component " + componentClass + " found!");
+      // a component factory is a component too!  See if one has been created and exists in the registry
+      ComponentFactory cf = getComponent(cfClass);
+      if (cf == null)
+      {
+         // hasn't yet been created.  Create and put in registry
+         cf = instantiateFactory(cfClass);
+         if (cf == null)
+            throw new ConfigurationException("Unable to locate component factory for component " + componentClass);
+         // we simply register this factory.  Registration will take care of constructing any dependencies.
+         registerComponent(cf, cfClass);
+      }
+
+      // ensure the component factory is in the STARTED state!
+      Component c = componentLookup.get(cfClass.getName());
+      if (c.instance != cf)
+         throw new ConfigurationException("Component factory " + cfClass + " incorrectly registered!");
+      return cf;
+   }
+
+   protected Map<Class, Class<? extends ComponentFactory>> getDefaultFactoryMap()
+   {
+      if (defaultFactories == null) scanDefaultFactories();
+      return defaultFactories;
+   }
+
+   /**
+    * Scans the class path for classes annotated with {@link org.jboss.cache.factories.annotations.DefaultFactoryFor}, and
+    * analyses which components can be created by such factories.
+    */
+   void scanDefaultFactories()
+   {
+      defaultFactories = new HashMap<Class, Class<? extends ComponentFactory>>();
+
+      Set<Class<? extends ComponentFactory>> factories = getHardcodedFactories();
+
+      for (Class<? extends ComponentFactory> factory : factories)
+      {
+         DefaultFactoryFor dFFAnnotation = factory.getAnnotation(DefaultFactoryFor.class);
+         for (Class targetClass : dFFAnnotation.classes()) defaultFactories.put(targetClass, factory);
+      }
+   }
+
+   /**
+    * No such thing as a meta factory yet.  Factories are created using this method which attempts to use an empty public
+    * constructor.
+    *
+    * @param factory class of factory to be created
+    * @return factory instance
+    */
+   ComponentFactory instantiateFactory(Class<? extends ComponentFactory> factory)
+   {
+      try
+      {
+         return factory.newInstance();
+      }
+      catch (Exception e)
+      {
+         // unable to get a hold of an instance!!
+         throw new ConfigurationException("Unable to instantiate factory " + factory, e);
+      }
+   }
+
+   /**
+    * registers a special "null" component that has no dependencies.
+    *
+    * @param type type of component to register as a null
+    */
+   void registerNullComponent(Class type)
+   {
+      registerComponent(NULL_COMPONENT, type);
+   }
+
+   /**
+    * Retrieves a component from the {@link Configuration} or {@link RuntimeConfig}.
+    *
+    * @param componentClass component type
+    * @return component, or null if it cannot be found
+    */
+   @SuppressWarnings("unchecked")
+   protected <T> T getFromConfiguration(Class<T> componentClass)
+   {
+      if (log.isDebugEnabled())
+         log.debug("Looking in configuration for an instance of " + componentClass + " that may have been injected from an external source.");
+      Method getter = BeanUtils.getterMethod(Configuration.class, componentClass);
+      T returnValue = null;
+
+      if (getter != null)
+      {
+         try
+         {
+            returnValue = (T) getter.invoke(getConfiguration());
+         }
+         catch (Exception e)
+         {
+            log.warn("Unable to invoke getter " + getter + " on Configuration.class!", e);
+         }
+      }
+
+      // now try the RuntimeConfig - a legacy "registry" of sorts.
+      if (returnValue == null)
+      {
+         getter = BeanUtils.getterMethod(RuntimeConfig.class, componentClass);
+         if (getter != null)
+         {
+            try
+            {
+               returnValue = (T) getter.invoke(getConfiguration().getRuntimeConfig());
+            }
+            catch (Exception e)
+            {
+               log.warn("Unable to invoke getter " + getter + " on RuntimeConfig.class!", e);
+            }
+         }
+      }
+      return returnValue;
+   }
+
+   /**
+    * Retrieves the configuration component.
+    *
+    * @return a Configuration object
+    */
+   protected Configuration getConfiguration()
+   {
+      // this is assumed to always be present as a part of the bootstrap/construction of a ComponentRegistry.
+      return getComponent(Configuration.class);
+   }
+
+   /**
+    * Retrieves a component of a specified type from the registry, or null if it cannot be found.
+    *
+    * @param type type to find
+    * @return component, or null
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getComponent(Class<T> type)
+   {
+      Component wrapper = componentLookup.get(type.getName());
+      if (wrapper == null) return null;
+
+      return (T) (wrapper.instance == NULL_COMPONENT ? null : wrapper.instance);
+   }
+
+   /**
+    * Rewires components.  Can only be called if the current state is WIRED or STARTED.
+    */
+   public void rewire()
+   {
+      // need to re-inject everything again.
+      for (Component c : new HashSet<Component>(componentLookup.values()))
+      {
+         // inject dependencies for this component
+         c.injectDependencies();
+      }
+   }
+
+   /**
+    * Scans each registered component for lifecycle methods, and adds them to the appropriate lists, and then sorts them
+    * by priority.
+    */
+   private void populateLifecycleMethods()
+   {
+      for (Component c : componentLookup.values())
+      {
+         if (!c.methodsScanned)
+         {
+            c.methodsScanned = true;
+            c.startMethods.clear();
+            c.stopMethods.clear();
+            c.destroyMethods.clear();
+
+            List<Method> methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Start.class);
+            for (Method m : methods)
+            {
+               PrioritizedMethod em = new PrioritizedMethod();
+               em.component = c;
+               em.method = m;
+               em.priority = m.getAnnotation(Start.class).priority();
+               c.startMethods.add(em);
+            }
+
+            methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Stop.class);
+            for (Method m : methods)
+            {
+               PrioritizedMethod em = new PrioritizedMethod();
+               em.component = c;
+               em.method = m;
+               em.priority = m.getAnnotation(Stop.class).priority();
+               c.stopMethods.add(em);
+            }
+
+            methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Destroy.class);
+            for (Method m : methods)
+            {
+               PrioritizedMethod em = new PrioritizedMethod();
+               em.component = c;
+               em.method = m;
+               em.priority = m.getAnnotation(Destroy.class).priority();
+               c.destroyMethods.add(em);
+            }
+         }
+      }
+   }
+
+   /**
+    * Removes any components not annotated as @NonVolatile.
+    */
+   public void resetNonVolatile()
+   {
+      // destroy all components to clean up resources
+      for (Component c : new HashSet<Component>(componentLookup.values()))
+      {
+         // the component is volatile!!
+         if (!c.nonVolatile)
+         {
+            componentLookup.remove(c.name);
+         }
+      }
+
+      if (trace) log.trace("Reset volatile components.  Registry now contains " + componentLookup.keySet());
+   }
+
+   // ------------------------------ START: Publicly available lifecycle methods -----------------------------
+   //   These methods perform a check for appropriate transition and then delegate to similarly named internal methods.
+
+   /**
+    * Creates the components needed by a cache instance and sets the cache status to {@link org.jboss.cache.CacheStatus#CREATED}
+    * when it is done.
+    */
+   public void create()
+   {
+      if (!state.createAllowed())
+      {
+         if (state.needToDestroyFailedCache())
+            destroy();
+         else
+            return;
+      }
+
+      try
+      {
+         internalCreate();
+      }
+      catch (Throwable t)
+      {
+         handleLifecycleTransitionFailure(t);
+      }
+   }
+
+   /**
+    * This starts the components in the cache, connecting to channels, starting service threads, etc.  If the cache is
+    * not in the {@link org.jboss.cache.CacheStatus#CREATED} state, {@link #create()} will be invoked first.
+    */
+   public void start()
+   {
+      boolean createdInStart = false;
+      if (!state.startAllowed())
+      {
+         if (state.needToDestroyFailedCache())
+            destroy(); // this will take us back to DESTROYED
+
+         if (state.needCreateBeforeStart())
+         {
+            create();
+            createdInStart = true;
+         }
+         else
+            return;
+      }
+
+      try
+      {
+         internalStart(createdInStart);
+      }
+      catch (Throwable t)
+      {
+         handleLifecycleTransitionFailure(t);
+      }
+   }
+
+   /**
+    * Stops the cache and sets the cache status to {@link org.jboss.cache.CacheStatus#STOPPED} once it is done.  If the cache is not in
+    * the {@link org.jboss.cache.CacheStatus#STARTED} state, this is a no-op.
+    */
+   public void stop()
+   {
+      if (!state.stopAllowed())
+      {
+         return;
+      }
+
+      // Trying to stop() from FAILED is valid, but may not work
+      boolean failed = state == CacheStatus.FAILED;
+
+      try
+      {
+         internalStop();
+      }
+      catch (Throwable t)
+      {
+         if (failed)
+         {
+            log.warn("Attempted to stop() from FAILED state, but caught exception; try calling destroy()", t);
+         }
+         failed = true;
+         handleLifecycleTransitionFailure(t);
+      }
+      finally
+      {
+         if (!failed) state = CacheStatus.STOPPED;
+      }
+   }
+
+   /**
+    * Destroys the cache and frees up any resources.  Sets the cache status to {@link CacheStatus#DESTROYED} when it is done.
+    * <p/>
+    * If the cache is in {@link org.jboss.cache.CacheStatus#STARTED} when this method is called, it will first call {@link #stop()}
+    * to stop the cache.
+    */
+   public void destroy()
+   {
+      if (!state.destroyAllowed())
+      {
+         if (state.needStopBeforeDestroy())
+         {
+            try
+            {
+               stop();
+            }
+            catch (CacheException e)
+            {
+               log.warn("Needed to call stop() before destroying but stop() threw exception. Proceeding to destroy", e);
+            }
+         }
+         else
+            return;
+      }
+
+      try
+      {
+         internalDestroy();
+      }
+      finally
+      {
+         // We always progress to destroyed
+         state = CacheStatus.DESTROYED;
+      }
+   }
+   // ------------------------------ END: Publicly available lifecycle methods -----------------------------
+
+   // ------------------------------ START: Actual internal lifecycle methods --------------------------------
+
+   /**
+    * Sets the cacheStatus to FAILED and rethrows the problem as one
+    * of the declared types. Converts any non-RuntimeException Exception
+    * to CacheException.
+    *
+    * @param t throwable thrown during failure
+    */
+   private void handleLifecycleTransitionFailure(Throwable t)
+   {
+      state = CacheStatus.FAILED;
+      if (t instanceof CacheException)
+         throw (CacheException) t;
+      else if (t instanceof RuntimeException)
+         throw (RuntimeException) t;
+      else if (t instanceof Error)
+         throw (Error) t;
+      else
+         throw new CacheException(t);
+   }
+
+   /**
+    * The actual create implementation.
+    */
+   private void internalCreate()
+   {
+      state = CacheStatus.CREATING;
+      resetNonVolatile();
+      rewire();
+      state = CacheStatus.CREATED;
+   }
+
+   private void internalStart(boolean createdInStart) throws CacheException, IllegalArgumentException
+   {
+      if (!createdInStart)
+      {
+         // re-wire all dependencies in case stuff has changed since the cache was created
+         // remove any components whose construction may have depended upon a configuration that may have changed.
+         resetNonVolatile();
+         rewire();
+      }
+
+      state = CacheStatus.STARTING;
+
+      // start all internal components
+      // first cache all start, stop and destroy methods.
+      populateLifecycleMethods();
+
+      List<PrioritizedMethod> startMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
+      for (Component c : componentLookup.values()) startMethods.addAll(c.startMethods);
+
+      // sort the start methods by priority
+      Collections.sort(startMethods);
+
+      // fire all START methods according to priority
+
+
+      for (PrioritizedMethod em : startMethods) em.invoke();
+
+      addShutdownHook();
+
+      log.info("JBoss Cache version: " + Version.printVersion());
+      state = CacheStatus.STARTED;
+   }
+
+   private void addShutdownHook()
+   {
+      ArrayList al = MBeanServerFactory.findMBeanServer(null);
+      boolean registerShutdownHook = (getConfiguration().getShutdownHookBehavior() == Configuration.ShutdownHookBehavior.DEFAULT && al.size() == 0)
+            || getConfiguration().getShutdownHookBehavior() == Configuration.ShutdownHookBehavior.REGISTER;
+
+      if (registerShutdownHook)
+      {
+         if (log.isTraceEnabled())
+            log.trace("Registering a shutdown hook.  Configured behavior = " + getConfiguration().getShutdownHookBehavior());
+         shutdownHook = new Thread()
+         {
+            @Override
+            public void run()
+            {
+               try
+               {
+                  invokedFromShutdownHook = true;
+                  AbstractComponentRegistry.this.stop();
+               }
+               finally
+               {
+                  invokedFromShutdownHook = false;
+               }
+            }
+         };
+
+         Runtime.getRuntime().addShutdownHook(shutdownHook);
+      }
+      else
+      {
+         if (log.isTraceEnabled())
+            log.trace("Not registering a shutdown hook.  Configured behavior = " + getConfiguration().getShutdownHookBehavior());
+      }
+   }
+
+   /**
+    * Actual stop
+    */
+   private void internalStop()
+   {
+      state = CacheStatus.STOPPING;
+      // if this is called from a source other than the shutdown hook, deregister the shutdown hook.
+      if (!invokedFromShutdownHook && shutdownHook != null) Runtime.getRuntime().removeShutdownHook(shutdownHook);
+
+      List<PrioritizedMethod> stopMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
+      for (Component c : componentLookup.values()) stopMethods.addAll(c.stopMethods);
+
+      Collections.sort(stopMethods);
+
+      // fire all STOP methods according to priority
+      for (PrioritizedMethod em : stopMethods) em.invoke();
+
+      state = CacheStatus.STOPPED;
+   }
+
+   /**
+    * Actual destroy
+    */
+   private void internalDestroy()
+   {
+
+      state = CacheStatus.DESTROYING;
+
+      resetNonVolatile();
+
+      List<PrioritizedMethod> destroyMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
+      for (Component c : componentLookup.values()) destroyMethods.addAll(c.destroyMethods);
+
+      Collections.sort(destroyMethods);
+
+      // fire all DESTROY methods according to priority
+      for (PrioritizedMethod em : destroyMethods) em.invoke();
+
+      state = CacheStatus.DESTROYED;
+   }
+
+   // ------------------------------ END: Actual internal lifecycle methods --------------------------------
+
+   /**
+    * Asserts whether invocations are allowed on the cache or not.  Returns <tt>true</tt> if invocations are to be allowed,
+    * <tt>false</tt> otherwise.  If the origin of the call is remote and the cache status is {@link org.jboss.cache.CacheStatus#STARTING},
+    * this method will block for up to {@link org.jboss.cache.config.Configuration#getStateRetrievalTimeout()} millis, checking
+    * for a valid state.
+    *
+    * @param originLocal true if the call originates locally (i.e., from the {@link org.jboss.cache.invocation.CacheInvocationDelegate} or false if it originates remotely, i.e., from the {@link org.jboss.cache.marshall.CommandAwareRpcDispatcher}.
+    * @return true if invocations are allowed, false otherwise.
+    */
+   public boolean invocationsAllowed(boolean originLocal)
+   {
+      log.trace("Testing if invocations are allowed.");
+      if (state.allowInvocations()) return true;
+
+      // if this is a locally originating call and the cache is not in a valid state, return false.
+      if (originLocal) return false;
+
+      log.trace("Is remotely originating.");
+
+      // else if this is a remote call and the status is STARTING, wait until the cache starts.
+      if (state == CacheStatus.STARTING)
+      {
+         log.trace("Cache is starting; block.");
+         try
+         {
+            blockUntilCacheStarts();
+            return true;
+         }
+         catch (InterruptedException e)
+         {
+            Thread.currentThread().interrupt();
+         }
+      }
+      else
+      {
+         log.warn("Received a remote call but the cache is not in STARTED state - ignoring call.");
+      }
+      return false;
+   }
+
+   /**
+    * Blocks until the current cache instance is in its {@link org.jboss.cache.CacheStatus#STARTED started} phase.  Blocks
+    * for up to {@link org.jboss.cache.config.Configuration#getStateRetrievalTimeout()} milliseconds, throwing an IllegalStateException
+    * if the cache doesn't reach this state even after this maximum wait time.
+    *
+    * @throws InterruptedException  if interrupted while waiting
+    * @throws IllegalStateException if even after waiting the cache has not started.
+    */
+   private void blockUntilCacheStarts() throws InterruptedException, IllegalStateException
+   {
+      int pollFrequencyMS = 100;
+      long startupWaitTime = getConfiguration().getStateRetrievalTimeout();
+      long giveUpTime = System.currentTimeMillis() + startupWaitTime;
+
+      while (System.currentTimeMillis() < giveUpTime)
+      {
+         if (state.allowInvocations()) break;
+         Thread.sleep(pollFrequencyMS);
+      }
+
+      // check if we have started.
+      if (!state.allowInvocations())
+         throw new IllegalStateException("Cache not in STARTED state, even after waiting " + getConfiguration().getStateRetrievalTimeout() + " millis.");
+   }
+
+   /**
+    * A wrapper representing a component in the registry
+    */
+   public class Component
+   {
+      /**
+       * A reference to the object instance for this component.
+       */
+      Object instance;
+      /**
+       * The name of the component
+       */
+      String name;
+      boolean methodsScanned;
+      /**
+       * List of injection methods used to inject dependencies into the component
+       */
+      List<Method> injectionMethods = new ArrayList<Method>(2);
+      List<PrioritizedMethod> startMethods = new ArrayList<PrioritizedMethod>(2);
+      List<PrioritizedMethod> stopMethods = new ArrayList<PrioritizedMethod>(2);
+      List<PrioritizedMethod> destroyMethods = new ArrayList<PrioritizedMethod>(2);
+      /**
+       * If true, then this component is not flushed before starting the ComponentRegistry.
+       */
+      boolean nonVolatile;
+
+      @Override
+      public String toString()
+      {
+         return "Component{" +
+               "instance=" + instance +
+               ", name=" + name +
+               ", nonVolatile=" + nonVolatile +
+               '}';
+      }
+
+      /**
+       * Injects dependencies into this component.
+       */
+      public void injectDependencies()
+      {
+         for (Method m : injectionMethods) invokeInjectionMethod(instance, m);
+      }
+
+      public Object getInstance()
+      {
+         return instance;
+      }
+
+      public String getName()
+      {
+         return name;
+      }
+   }
+
+
+   /**
+    * Wrapper to encapsulate a method along with a priority
+    */
+   static class PrioritizedMethod implements Comparable<PrioritizedMethod>
+   {
+      Method method;
+      Component component;
+      int priority;
+
+      public int compareTo(PrioritizedMethod o)
+      {
+         return (priority < o.priority ? -1 : (priority == o.priority ? 0 : 1));
+      }
+
+      void invoke()
+      {
+         ReflectionUtil.invokeAccessibly(component.instance, method, null);
+      }
+
+      @Override
+      public String toString()
+      {
+         return "PrioritizedMethod{" +
+               "method=" + method +
+               ", priority=" + priority +
+               '}';
+      }
+   }
+
+   /**
+    * Returns an immutable set contating all the components that exists in the reporsitory at this moment.
+    */
+   public Set<Component> getRegiteredComponents()
+   {
+      HashSet<Component> defensiveCopy = new HashSet<Component>(componentLookup.values());
+      return Collections.unmodifiableSet(defensiveCopy);
+   }
+}


Property changes on: core/branches/flat/src/main/java/org/jboss/starobrno/factories/AbstractComponentRegistry.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentFactory.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentFactory.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -42,7 +42,7 @@
  * @see ComponentRegistry
  * @since 2.1.0
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public abstract class ComponentFactory
 {
    protected final Log log = LogFactory.getLog(getClass());

Deleted: core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -1,1002 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.starobrno.factories;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.jboss.cache.CacheStatus;
-import org.jboss.cache.Version;
-import org.jboss.starobrno.CacheException;
-import org.jboss.starobrno.CacheSPI;
-import org.jboss.starobrno.config.Configuration;
-import org.jboss.starobrno.config.ConfigurationException;
-import org.jboss.starobrno.config.RuntimeConfig;
-import org.jboss.starobrno.factories.annotations.DefaultFactoryFor;
-import org.jboss.starobrno.factories.annotations.Destroy;
-import org.jboss.starobrno.factories.annotations.Inject;
-import org.jboss.starobrno.factories.annotations.NonVolatile;
-import org.jboss.starobrno.factories.annotations.Start;
-import org.jboss.starobrno.factories.annotations.Stop;
-import org.jboss.starobrno.factories.scopes.Scope;
-import org.jboss.starobrno.factories.scopes.Scopes;
-import org.jboss.starobrno.lifecycle.Lifecycle;
-import org.jboss.starobrno.util.BeanUtils;
-import org.jboss.starobrno.util.ReflectionUtil;
-
-import javax.management.MBeanServerFactory;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A registry where components which have been created are stored.  Components are stored as singletons, registered under
- * a specific name.
- * <p/>
- * Components can be retrieved from the registry using {@link #getComponent(Class)}.
- * <p/>
- * Components can be registered using {@link #registerComponent(Object, Class)}, which will cause any dependencies to be
- * wired in as well.  Components that need to be created as a result of wiring will be done using {@link #getOrCreateComponent(Class)},
- * which will look up the default factory for the component type (factories annotated with the appropriate {@link DefaultFactoryFor} annotation.
- * <p/>
- * Default factories are treated as components too and will need to be wired before being used.
- * <p/>
- * The registry can exist in one of several states, as defined by the {@link CacheStatus} enumeration.  In terms of the cache,
- * state changes in the following manner:
- * <ul>
- * <li>INSTANTIATED - when first constructed</li>
- * <li>CONSTRUCTED - when created using the DefaultCacheFactory</li>
- * <li>When {@link org.jboss.cache.Cache_Legacy#create()} is called, the components are rewired.</li>
- * <li>STARTED - when {@link org.jboss.cache.Cache_Legacy#start()} is called</li>
- * <li>STOPPED - when {@link org.jboss.cache.Cache_Legacy#stop()} is called</li>
- * <li>DESTROYED - when {@link org.jboss.cache.Cache_Legacy#destroy()} is called.</li>
- * </ul>
- * <p/>
- * Cache configuration can only be changed and will only be reinjected if the cache is not in the {@link org.jboss.cache.CacheStatus#STARTED} state.
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 2.1.0
- */
- at NonVolatile
- at Scope(Scopes.CACHE_ONLY)
-public class ComponentRegistry implements Lifecycle
-{
-   /**
-    * Contains class definitions of component factories that can be used to construct certain components
-    */
-   private Map<Class, Class<? extends ComponentFactory>> defaultFactories = null;
-
-   private static final Log log = LogFactory.getLog(ComponentRegistry.class);
-   private static final boolean trace = log.isTraceEnabled();
-   protected static final Object NULL_COMPONENT = new Object();
-
-   // component and method containers
-   final Map<String, Component> componentLookup = new HashMap<String, Component>();
-
-   CacheStatus state = CacheStatus.INSTANTIATED;
-
-   /**
-    * Hook to shut down the cache when the JVM exits.
-    */
-   private Thread shutdownHook;
-   /**
-    * A flag that the shutdown hook sets before calling cache.stop().  Allows stop() to identify if it has been called
-    * from a shutdown hook.
-    */
-   private boolean invokedFromShutdownHook;
-
-   /**
-    * Creates an instance of the component registry.  The configuration passed in is automatically registered.
-    *
-    * @param configuration configuration with which this is created
-    */
-   public ComponentRegistry(Configuration configuration, CacheSPI cache)
-   {
-      try
-      {
-         // bootstrap.
-         registerDefaultClassLoader(null);
-         registerComponent(this, ComponentRegistry.class);
-         registerComponent(configuration, Configuration.class);
-         registerComponent(new BootstrapFactory(cache, configuration, this), BootstrapFactory.class);
-      }
-      catch (Exception e)
-      {
-         throw new CacheException("Unable to construct ComponentRegistry", e);
-      }
-   }
-
-   /**
-    * Retrieves the state of the registry
-    *
-    * @return state of the registry
-    */
-   public CacheStatus getState()
-   {
-      return state;
-   }
-
-   /**
-    * Wires an object instance with dependencies annotated with the {@link org.jboss.cache.factories.annotations.Inject} annotation, creating more components
-    * as needed based on the Configuration passed in if these additional components don't exist in the
-    * {@link ComponentRegistry}.  Strictly for components that don't otherwise live in the registry and have a lifecycle, such as Nodes.
-    *
-    * @param target object to wire
-    * @throws ConfigurationException if there is a problem wiring the instance
-    */
-   public void wireDependencies(Object target) throws ConfigurationException
-   {
-      try
-      {
-         // don't use the reflection cache for wireDependencies calls since these are not managed by the ComponentRegistry
-         // and may be invoked at any time, even after the cache starts.
-         List<Method> methods = ReflectionUtil.getAllMethods(target.getClass(), Inject.class);
-
-         // search for anything we need to inject
-         for (Method method : methods) invokeInjectionMethod(target, method);
-      }
-      catch (Exception e)
-      {
-         throw new ConfigurationException("Unable to configure component (type: " + target.getClass() + ", instance " + target + ")", e);
-      }
-   }
-
-   /**
-    * Registers the default class loader.  This method *must* be called before any other components are registered,
-    * typically called by bootstrap code.  Defensively, it is called in the constructor of ComponentRegistry with a null
-    * parameter.
-    *
-    * @param loader a class loader to use by default.  If this is null, the class loader used to load this instance of ComponentRegistry is used.
-    */
-   public void registerDefaultClassLoader(ClassLoader loader)
-   {
-      registerComponent(loader == null ? getClass().getClassLoader() : loader, ClassLoader.class);
-      // make sure the class loader is non-volatile, so it survives restarts.
-      componentLookup.get(ClassLoader.class.getName()).nonVolatile = true;
-   }
-
-   /**
-    * This is hard coded for now, since scanning the classpath for factories annotated with {@link org.jboss.cache.factories.annotations.DefaultFactoryFor}
-    * does not work with all class loaders.  This is a temporary solution until a more elegant one can be designed.
-    * <p/>
-    * BE SURE TO ADD ANY NEW FACTORY TYPES ANNOTATED WITH DefaultFactoryFor TO THIS SET!!
-    * <p/>
-    *
-    * @return set of known factory types.
-    */
-   private Set<Class<? extends ComponentFactory>> getHardcodedFactories()
-   {
-      Set<Class<? extends ComponentFactory>> s = new HashSet<Class<? extends ComponentFactory>>();
-      s.add(BootstrapFactory.class);
-      s.add(BuddyManagerFactory.class);
-      s.add(EmptyConstructorFactory.class);
-      s.add(InterceptorChainFactory.class);
-      s.add(RuntimeConfigAwareFactory.class);
-      s.add(TransactionManagerFactory.class);
-      s.add(ReplicationQueueFactory.class);
-      s.add(StateTransferManagerFactory.class);
-      s.add(StateTransferFactory.class);
-      s.add(NullComponentFactory.class);
-      s.add(LockManagerFactory.class);
-      s.add(DataContainerFactory.class);
-      s.add(EvictionManagerFactory.class);
-      return s;
-   }
-
-   /**
-    * Registers a component in the registry under the given type, and injects any dependencies needed.  If a component
-    * of this type already exists, it is overwritten.
-    *
-    * @param component component to register
-    * @param type      type of component
-    */
-   public void registerComponent(Object component, Class type)
-   {
-
-      String name = type.getName();
-      Component old = componentLookup.get(name);
-
-      if (old != null)
-      {
-         // if they are equal don't bother
-         if (old.instance.equals(component))
-         {
-            if (trace)
-               log.trace("Attempting to register a component equal to one that already exists under the same name (" + name + ").  Not doing anything.");
-            return;
-         }
-      }
-
-      Component c;
-      if (old != null)
-      {
-         if (trace) log.trace("Replacing old component " + old + " with new instance " + component);
-         old.instance = component;
-         old.methodsScanned = false;
-         c = old;
-
-         if (state == CacheStatus.STARTED) populateLifecycleMethods();
-      }
-      else
-      {
-         c = new Component();
-         c.name = name;
-         c.instance = component;
-         if (trace) log.trace("Registering component " + c + " under name " + name);
-         componentLookup.put(name, c);
-      }
-      c.nonVolatile = component.getClass().isAnnotationPresent(NonVolatile.class) || type.isAnnotationPresent(NonVolatile.class);
-      addComponentDependencies(c);
-      // inject dependencies for this component
-      c.injectDependencies();
-   }
-
-   /**
-    * Adds component dependencies for a given component, by populating {@link Component#injectionMethods}.
-    *
-    * @param c component to add dependencies to
-    */
-   protected void addComponentDependencies(Component c)
-   {
-      Class type = c.instance.getClass();
-      List<Method> methods = ReflectionUtil.getAllMethods(type, Inject.class);
-      c.injectionMethods.clear();
-      c.injectionMethods.addAll(methods);
-   }
-
-   @SuppressWarnings("unchecked")
-   protected void invokeInjectionMethod(Object o, Method m)
-   {
-      Class[] dependencies = m.getParameterTypes();
-      Object[] params = new Object[dependencies.length];
-
-      for (int i = 0; i < dependencies.length; i++)
-      {
-         params[i] = getOrCreateComponent(dependencies[i]);
-      }
-
-      ReflectionUtil.invokeAccessibly(o, m, params);
-   }
-
-   /**
-    * Retrieves a component if one exists, and if not, attempts to find a factory capable of constructing the component
-    * (factories annotated with the {@link DefaultFactoryFor} annotation that is capable of creating the component class).
-    * <p/>
-    * If an instance needs to be constructed, dependencies are then automatically wired into the instance, based on methods
-    * on the component type annotated with {@link Inject}.
-    * <p/>
-    * Summing it up, component retrieval happens in the following order:<br />
-    * 1.  Look for a component that has already been created and registered.
-    * 2.  Look for an appropriate component that exists in the {@link Configuration} that may be injected from an external system.
-    * 3.  Look for a class definition passed in to the {@link org.jboss.cache.config.Configuration} - such as an EvictionPolicy implementation
-    * 4.  Attempt to create it by looking for an appropriate factory (annotated with {@link DefaultFactoryFor})
-    * <p/>
-    *
-    * @param componentClass type of component to be retrieved.  Should not be null.
-    * @return a fully wired component instance, or null if one cannot be found or constructed.
-    * @throws ConfigurationException if there is a problem with consructing or wiring the instance.
-    */
-   protected <T> T getOrCreateComponent(Class<T> componentClass)
-   {
-
-      T component = getComponent(componentClass);
-
-      if (component == null)
-      {
-         // first see if this has been injected externally.
-         component = getFromConfiguration(componentClass);
-         boolean attemptedFactoryConstruction = false;
-
-         if (component == null)
-         {
-            // create this component and add it to the registry
-            ComponentFactory factory = getFactory(componentClass);
-            component = factory.construct(componentClass);
-            attemptedFactoryConstruction = true;
-
-         }
-
-         if (component != null)
-         {
-            registerComponent(component, componentClass);
-         }
-         else if (attemptedFactoryConstruction)
-         {
-            if (trace) log.trace("Registering a null for component " + componentClass.getSimpleName());
-            registerNullComponent(componentClass);
-         }
-      }
-
-      return component;
-   }
-
-   /**
-    * Retrieves a component factory instance capable of constructing components of a specified type.  If the factory doesn't
-    * exist in the registry, one is created.
-    *
-    * @param componentClass type of component to construct
-    * @return component factory capable of constructing such components
-    */
-   protected ComponentFactory getFactory(Class componentClass)
-   {
-      Map<Class, Class<? extends ComponentFactory>> defaultFactoryMap = getDefaultFactoryMap();
-      Class<? extends ComponentFactory> cfClass = defaultFactoryMap.get(componentClass);
-      if (cfClass == null)
-         throw new ConfigurationException("No registered default factory for component " + componentClass + " found!");
-      // a component factory is a component too!  See if one has been created and exists in the registry
-      ComponentFactory cf = getComponent(cfClass);
-      if (cf == null)
-      {
-         // hasn't yet been created.  Create and put in registry
-         cf = instantiateFactory(cfClass);
-         if (cf == null)
-            throw new ConfigurationException("Unable to locate component factory for component " + componentClass);
-         // we simply register this factory.  Registration will take care of constructing any dependencies.
-         registerComponent(cf, cfClass);
-      }
-
-      // ensure the component factory is in the STARTED state!
-      Component c = componentLookup.get(cfClass.getName());
-      if (c.instance != cf)
-         throw new ConfigurationException("Component factory " + cfClass + " incorrectly registered!");
-      return cf;
-   }
-
-   protected Map<Class, Class<? extends ComponentFactory>> getDefaultFactoryMap()
-   {
-      if (defaultFactories == null) scanDefaultFactories();
-      return defaultFactories;
-   }
-
-   /**
-    * Scans the class path for classes annotated with {@link org.jboss.cache.factories.annotations.DefaultFactoryFor}, and
-    * analyses which components can be created by such factories.
-    */
-   void scanDefaultFactories()
-   {
-      defaultFactories = new HashMap<Class, Class<? extends ComponentFactory>>();
-
-      Set<Class<? extends ComponentFactory>> factories = getHardcodedFactories();
-
-      for (Class<? extends ComponentFactory> factory : factories)
-      {
-         DefaultFactoryFor dFFAnnotation = factory.getAnnotation(DefaultFactoryFor.class);
-         for (Class targetClass : dFFAnnotation.classes()) defaultFactories.put(targetClass, factory);
-      }
-   }
-
-   /**
-    * No such thing as a meta factory yet.  Factories are created using this method which attempts to use an empty public
-    * constructor.
-    *
-    * @param factory class of factory to be created
-    * @return factory instance
-    */
-   ComponentFactory instantiateFactory(Class<? extends ComponentFactory> factory)
-   {
-      try
-      {
-         return factory.newInstance();
-      }
-      catch (Exception e)
-      {
-         // unable to get a hold of an instance!!
-         throw new ConfigurationException("Unable to instantiate factory " + factory, e);
-      }
-   }
-
-   /**
-    * registers a special "null" component that has no dependencies.
-    *
-    * @param type type of component to register as a null
-    */
-   void registerNullComponent(Class type)
-   {
-      registerComponent(NULL_COMPONENT, type);
-   }
-
-   /**
-    * Retrieves a component from the {@link Configuration} or {@link RuntimeConfig}.
-    *
-    * @param componentClass component type
-    * @return component, or null if it cannot be found
-    */
-   @SuppressWarnings("unchecked")
-   protected <T> T getFromConfiguration(Class<T> componentClass)
-   {
-      if (log.isDebugEnabled())
-         log.debug("Looking in configuration for an instance of " + componentClass + " that may have been injected from an external source.");
-      Method getter = BeanUtils.getterMethod(Configuration.class, componentClass);
-      T returnValue = null;
-
-      if (getter != null)
-      {
-         try
-         {
-            returnValue = (T) getter.invoke(getConfiguration());
-         }
-         catch (Exception e)
-         {
-            log.warn("Unable to invoke getter " + getter + " on Configuration.class!", e);
-         }
-      }
-
-      // now try the RuntimeConfig - a legacy "registry" of sorts.
-      if (returnValue == null)
-      {
-         getter = BeanUtils.getterMethod(RuntimeConfig.class, componentClass);
-         if (getter != null)
-         {
-            try
-            {
-               returnValue = (T) getter.invoke(getConfiguration().getRuntimeConfig());
-            }
-            catch (Exception e)
-            {
-               log.warn("Unable to invoke getter " + getter + " on RuntimeConfig.class!", e);
-            }
-         }
-      }
-      return returnValue;
-   }
-
-   /**
-    * Retrieves the configuration component.
-    *
-    * @return a Configuration object
-    */
-   protected Configuration getConfiguration()
-   {
-      // this is assumed to always be present as a part of the bootstrap/construction of a ComponentRegistry.
-      return getComponent(Configuration.class);
-   }
-
-   /**
-    * Retrieves a component of a specified type from the registry, or null if it cannot be found.
-    *
-    * @param type type to find
-    * @return component, or null
-    */
-   @SuppressWarnings("unchecked")
-   public <T> T getComponent(Class<T> type)
-   {
-      Component wrapper = componentLookup.get(type.getName());
-      if (wrapper == null) return null;
-
-      return (T) (wrapper.instance == NULL_COMPONENT ? null : wrapper.instance);
-   }
-
-   /**
-    * Rewires components.  Can only be called if the current state is WIRED or STARTED.
-    */
-   public void rewire()
-   {
-      // need to re-inject everything again.
-      for (Component c : new HashSet<Component>(componentLookup.values()))
-      {
-         // inject dependencies for this component
-         c.injectDependencies();
-      }
-   }
-
-   /**
-    * Scans each registered component for lifecycle methods, and adds them to the appropriate lists, and then sorts them
-    * by priority.
-    */
-   private void populateLifecycleMethods()
-   {
-      for (Component c : componentLookup.values())
-      {
-         if (!c.methodsScanned)
-         {
-            c.methodsScanned = true;
-            c.startMethods.clear();
-            c.stopMethods.clear();
-            c.destroyMethods.clear();
-
-            List<Method> methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Start.class);
-            for (Method m : methods)
-            {
-               PrioritizedMethod em = new PrioritizedMethod();
-               em.component = c;
-               em.method = m;
-               em.priority = m.getAnnotation(Start.class).priority();
-               c.startMethods.add(em);
-            }
-
-            methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Stop.class);
-            for (Method m : methods)
-            {
-               PrioritizedMethod em = new PrioritizedMethod();
-               em.component = c;
-               em.method = m;
-               em.priority = m.getAnnotation(Stop.class).priority();
-               c.stopMethods.add(em);
-            }
-
-            methods = ReflectionUtil.getAllMethods(c.instance.getClass(), Destroy.class);
-            for (Method m : methods)
-            {
-               PrioritizedMethod em = new PrioritizedMethod();
-               em.component = c;
-               em.method = m;
-               em.priority = m.getAnnotation(Destroy.class).priority();
-               c.destroyMethods.add(em);
-            }
-         }
-      }
-   }
-
-   /**
-    * Removes any components not annotated as @NonVolatile.
-    */
-   public void resetNonVolatile()
-   {
-      // destroy all components to clean up resources
-      for (Component c : new HashSet<Component>(componentLookup.values()))
-      {
-         // the component is volatile!!
-         if (!c.nonVolatile)
-         {
-            componentLookup.remove(c.name);
-         }
-      }
-
-      if (trace) log.trace("Reset volatile components.  Registry now contains " + componentLookup.keySet());
-   }
-
-   // ------------------------------ START: Publicly available lifecycle methods -----------------------------
-   //   These methods perform a check for appropriate transition and then delegate to similarly named internal methods.
-
-   /**
-    * Creates the components needed by a cache instance and sets the cache status to {@link org.jboss.cache.CacheStatus#CREATED}
-    * when it is done.
-    */
-   public void create()
-   {
-      if (!state.createAllowed())
-      {
-         if (state.needToDestroyFailedCache())
-            destroy();
-         else
-            return;
-      }
-
-      try
-      {
-         internalCreate();
-      }
-      catch (Throwable t)
-      {
-         handleLifecycleTransitionFailure(t);
-      }
-   }
-
-   /**
-    * This starts the components in the cache, connecting to channels, starting service threads, etc.  If the cache is
-    * not in the {@link org.jboss.cache.CacheStatus#CREATED} state, {@link #create()} will be invoked first.
-    */
-   public void start()
-   {
-      boolean createdInStart = false;
-      if (!state.startAllowed())
-      {
-         if (state.needToDestroyFailedCache())
-            destroy(); // this will take us back to DESTROYED
-
-         if (state.needCreateBeforeStart())
-         {
-            create();
-            createdInStart = true;
-         }
-         else
-            return;
-      }
-
-      try
-      {
-         internalStart(createdInStart);
-      }
-      catch (Throwable t)
-      {
-         handleLifecycleTransitionFailure(t);
-      }
-   }
-
-   /**
-    * Stops the cache and sets the cache status to {@link org.jboss.cache.CacheStatus#STOPPED} once it is done.  If the cache is not in
-    * the {@link org.jboss.cache.CacheStatus#STARTED} state, this is a no-op.
-    */
-   public void stop()
-   {
-      if (!state.stopAllowed())
-      {
-         return;
-      }
-
-      // Trying to stop() from FAILED is valid, but may not work
-      boolean failed = state == CacheStatus.FAILED;
-
-      try
-      {
-         internalStop();
-      }
-      catch (Throwable t)
-      {
-         if (failed)
-         {
-            log.warn("Attempted to stop() from FAILED state, but caught exception; try calling destroy()", t);
-         }
-         failed = true;
-         handleLifecycleTransitionFailure(t);
-      }
-      finally
-      {
-         if (!failed) state = CacheStatus.STOPPED;
-      }
-   }
-
-   /**
-    * Destroys the cache and frees up any resources.  Sets the cache status to {@link CacheStatus#DESTROYED} when it is done.
-    * <p/>
-    * If the cache is in {@link org.jboss.cache.CacheStatus#STARTED} when this method is called, it will first call {@link #stop()}
-    * to stop the cache.
-    */
-   public void destroy()
-   {
-      if (!state.destroyAllowed())
-      {
-         if (state.needStopBeforeDestroy())
-         {
-            try
-            {
-               stop();
-            }
-            catch (CacheException e)
-            {
-               log.warn("Needed to call stop() before destroying but stop() threw exception. Proceeding to destroy", e);
-            }
-         }
-         else
-            return;
-      }
-
-      try
-      {
-         internalDestroy();
-      }
-      finally
-      {
-         // We always progress to destroyed
-         state = CacheStatus.DESTROYED;
-      }
-   }
-   // ------------------------------ END: Publicly available lifecycle methods -----------------------------
-
-   // ------------------------------ START: Actual internal lifecycle methods --------------------------------
-
-   /**
-    * Sets the cacheStatus to FAILED and rethrows the problem as one
-    * of the declared types. Converts any non-RuntimeException Exception
-    * to CacheException.
-    *
-    * @param t throwable thrown during failure
-    */
-   private void handleLifecycleTransitionFailure(Throwable t)
-   {
-      state = CacheStatus.FAILED;
-      if (t instanceof CacheException)
-         throw (CacheException) t;
-      else if (t instanceof RuntimeException)
-         throw (RuntimeException) t;
-      else if (t instanceof Error)
-         throw (Error) t;
-      else
-         throw new CacheException(t);
-   }
-
-   /**
-    * The actual create implementation.
-    */
-   private void internalCreate()
-   {
-      state = CacheStatus.CREATING;
-      resetNonVolatile();
-      rewire();
-      state = CacheStatus.CREATED;
-   }
-
-   private void internalStart(boolean createdInStart) throws CacheException, IllegalArgumentException
-   {
-      if (!createdInStart)
-      {
-         // re-wire all dependencies in case stuff has changed since the cache was created
-         // remove any components whose construction may have depended upon a configuration that may have changed.
-         resetNonVolatile();
-         rewire();
-      }
-
-      state = CacheStatus.STARTING;
-
-      // start all internal components
-      // first cache all start, stop and destroy methods.
-      populateLifecycleMethods();
-
-      List<PrioritizedMethod> startMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
-      for (Component c : componentLookup.values()) startMethods.addAll(c.startMethods);
-
-      // sort the start methods by priority
-      Collections.sort(startMethods);
-
-      // fire all START methods according to priority
-
-
-      for (PrioritizedMethod em : startMethods) em.invoke();
-
-      addShutdownHook();
-
-      log.info("JBoss Cache version: " + Version.printVersion());
-      state = CacheStatus.STARTED;
-   }
-
-   private void addShutdownHook()
-   {
-      ArrayList al = MBeanServerFactory.findMBeanServer(null);
-      boolean registerShutdownHook = (getConfiguration().getShutdownHookBehavior() == Configuration.ShutdownHookBehavior.DEFAULT && al.size() == 0)
-            || getConfiguration().getShutdownHookBehavior() == Configuration.ShutdownHookBehavior.REGISTER;
-
-      if (registerShutdownHook)
-      {
-         if (log.isTraceEnabled())
-            log.trace("Registering a shutdown hook.  Configured behavior = " + getConfiguration().getShutdownHookBehavior());
-         shutdownHook = new Thread()
-         {
-            @Override
-            public void run()
-            {
-               try
-               {
-                  invokedFromShutdownHook = true;
-                  ComponentRegistry.this.stop();
-               }
-               finally
-               {
-                  invokedFromShutdownHook = false;
-               }
-            }
-         };
-
-         Runtime.getRuntime().addShutdownHook(shutdownHook);
-      }
-      else
-      {
-         if (log.isTraceEnabled())
-            log.trace("Not registering a shutdown hook.  Configured behavior = " + getConfiguration().getShutdownHookBehavior());
-      }
-   }
-
-   /**
-    * Actual stop
-    */
-   private void internalStop()
-   {
-      state = CacheStatus.STOPPING;
-      // if this is called from a source other than the shutdown hook, deregister the shutdown hook.
-      if (!invokedFromShutdownHook && shutdownHook != null) Runtime.getRuntime().removeShutdownHook(shutdownHook);
-
-      List<PrioritizedMethod> stopMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
-      for (Component c : componentLookup.values()) stopMethods.addAll(c.stopMethods);
-
-      Collections.sort(stopMethods);
-
-      // fire all STOP methods according to priority
-      for (PrioritizedMethod em : stopMethods) em.invoke();
-
-      state = CacheStatus.STOPPED;
-   }
-
-   /**
-    * Actual destroy
-    */
-   private void internalDestroy()
-   {
-
-      state = CacheStatus.DESTROYING;
-
-      resetNonVolatile();
-
-      List<PrioritizedMethod> destroyMethods = new ArrayList<PrioritizedMethod>(componentLookup.size());
-      for (Component c : componentLookup.values()) destroyMethods.addAll(c.destroyMethods);
-
-      Collections.sort(destroyMethods);
-
-      // fire all DESTROY methods according to priority
-      for (PrioritizedMethod em : destroyMethods) em.invoke();
-
-      state = CacheStatus.DESTROYED;
-   }
-
-   // ------------------------------ END: Actual internal lifecycle methods --------------------------------
-
-   /**
-    * Asserts whether invocations are allowed on the cache or not.  Returns <tt>true</tt> if invocations are to be allowed,
-    * <tt>false</tt> otherwise.  If the origin of the call is remote and the cache status is {@link org.jboss.cache.CacheStatus#STARTING},
-    * this method will block for up to {@link org.jboss.cache.config.Configuration#getStateRetrievalTimeout()} millis, checking
-    * for a valid state.
-    *
-    * @param originLocal true if the call originates locally (i.e., from the {@link org.jboss.cache.invocation.CacheInvocationDelegate} or false if it originates remotely, i.e., from the {@link org.jboss.cache.marshall.CommandAwareRpcDispatcher}.
-    * @return true if invocations are allowed, false otherwise.
-    */
-   public boolean invocationsAllowed(boolean originLocal)
-   {
-      log.trace("Testing if invocations are allowed.");
-      if (state.allowInvocations()) return true;
-
-      // if this is a locally originating call and the cache is not in a valid state, return false.
-      if (originLocal) return false;
-
-      log.trace("Is remotely originating.");
-
-      // else if this is a remote call and the status is STARTING, wait until the cache starts.
-      if (state == CacheStatus.STARTING)
-      {
-         log.trace("Cache is starting; block.");
-         try
-         {
-            blockUntilCacheStarts();
-            return true;
-         }
-         catch (InterruptedException e)
-         {
-            Thread.currentThread().interrupt();
-         }
-      }
-      else
-      {
-         log.warn("Received a remote call but the cache is not in STARTED state - ignoring call.");
-      }
-      return false;
-   }
-
-   /**
-    * Blocks until the current cache instance is in its {@link org.jboss.cache.CacheStatus#STARTED started} phase.  Blocks
-    * for up to {@link org.jboss.cache.config.Configuration#getStateRetrievalTimeout()} milliseconds, throwing an IllegalStateException
-    * if the cache doesn't reach this state even after this maximum wait time.
-    *
-    * @throws InterruptedException  if interrupted while waiting
-    * @throws IllegalStateException if even after waiting the cache has not started.
-    */
-   private void blockUntilCacheStarts() throws InterruptedException, IllegalStateException
-   {
-      int pollFrequencyMS = 100;
-      long startupWaitTime = getConfiguration().getStateRetrievalTimeout();
-      long giveUpTime = System.currentTimeMillis() + startupWaitTime;
-
-      while (System.currentTimeMillis() < giveUpTime)
-      {
-         if (state.allowInvocations()) break;
-         Thread.sleep(pollFrequencyMS);
-      }
-
-      // check if we have started.
-      if (!state.allowInvocations())
-         throw new IllegalStateException("Cache not in STARTED state, even after waiting " + getConfiguration().getStateRetrievalTimeout() + " millis.");
-   }
-
-   /**
-    * A wrapper representing a component in the registry
-    */
-   public class Component
-   {
-      /**
-       * A reference to the object instance for this component.
-       */
-      Object instance;
-      /**
-       * The name of the component
-       */
-      String name;
-      boolean methodsScanned;
-      /**
-       * List of injection methods used to inject dependencies into the component
-       */
-      List<Method> injectionMethods = new ArrayList<Method>(2);
-      List<PrioritizedMethod> startMethods = new ArrayList<PrioritizedMethod>(2);
-      List<PrioritizedMethod> stopMethods = new ArrayList<PrioritizedMethod>(2);
-      List<PrioritizedMethod> destroyMethods = new ArrayList<PrioritizedMethod>(2);
-      /**
-       * If true, then this component is not flushed before starting the ComponentRegistry.
-       */
-      boolean nonVolatile;
-
-      @Override
-      public String toString()
-      {
-         return "Component{" +
-               "instance=" + instance +
-               ", name=" + name +
-               ", nonVolatile=" + nonVolatile +
-               '}';
-      }
-
-      /**
-       * Injects dependencies into this component.
-       */
-      public void injectDependencies()
-      {
-         for (Method m : injectionMethods) invokeInjectionMethod(instance, m);
-      }
-
-      public Object getInstance()
-      {
-         return instance;
-      }
-
-      public String getName()
-      {
-         return name;
-      }
-   }
-
-
-   /**
-    * Wrapper to encapsulate a method along with a priority
-    */
-   static class PrioritizedMethod implements Comparable<PrioritizedMethod>
-   {
-      Method method;
-      Component component;
-      int priority;
-
-      public int compareTo(PrioritizedMethod o)
-      {
-         return (priority < o.priority ? -1 : (priority == o.priority ? 0 : 1));
-      }
-
-      void invoke()
-      {
-         ReflectionUtil.invokeAccessibly(component.instance, method, null);
-      }
-
-      @Override
-      public String toString()
-      {
-         return "PrioritizedMethod{" +
-               "method=" + method +
-               ", priority=" + priority +
-               '}';
-      }
-   }
-
-   /**
-    * Returns an immutable set contating all the components that exists in the reporsitory at this moment.
-    */
-   public Set<Component> getRegiteredComponents()
-   {
-      HashSet<Component> defensiveCopy = new HashSet<Component>(componentLookup.values());
-      return Collections.unmodifiableSet(defensiveCopy);
-   }
-}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/ComponentRegistry.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,93 @@
+package org.jboss.starobrno.factories;
+
+import org.jboss.starobrno.CacheException;
+import org.jboss.starobrno.CacheSPI;
+import org.jboss.starobrno.config.Configuration;
+import org.jboss.starobrno.factories.scopes.ScopeDetector;
+import org.jboss.starobrno.factories.scopes.Scopes;
+
+import java.util.Map;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ */
+public class ComponentRegistry extends AbstractComponentRegistry
+{
+   GlobalComponentRegistry globalComponents;
+
+   /**
+    * Creates an instance of the component registry.  The configuration passed in is automatically registered.
+    *
+    * @param configuration    configuration with which this is created
+    * @param cache            cache
+    * @param globalComponents Shared Component Registry to delegate to
+    */
+   public ComponentRegistry(Configuration configuration, CacheSPI cache, GlobalComponentRegistry globalComponents)
+   {
+
+      try
+      {
+         registerDefaultClassLoader(null);
+         registerComponent(this, ComponentRegistry.class);
+         registerComponent(configuration, Configuration.class);
+         registerComponent(new BootstrapFactory(cache, configuration, this), BootstrapFactory.class);
+
+         this.globalComponents = globalComponents;
+      }
+      catch (Exception e)
+      {
+         throw new CacheException("Unable to construct a ComponentRegistry!", e);
+      }
+   }
+
+   /**
+    * Registers the default class loader.  This method *must* be called before any other components are registered,
+    * typically called by bootstrap code.  Defensively, it is called in the constructor of ComponentRegistry with a null
+    * parameter.
+    *
+    * @param loader a class loader to use by default.  If this is null, the class loader used to load this instance of ComponentRegistry is used.
+    */
+   public void registerDefaultClassLoader(ClassLoader loader)
+   {
+      registerComponent(loader == null ? getClass().getClassLoader() : loader, ClassLoader.class);
+      // make sure the class loader is non-volatile, so it survives restarts.
+      componentLookup.get(ClassLoader.class.getName()).nonVolatile = true;
+   }
+
+
+   @Override
+   public <T> T getComponent(Class<T> componentType)
+   {
+      // first try in the local registry
+      Scopes componentScope = ScopeDetector.detectScope(componentType);
+      switch (componentScope)
+      {
+         case GLOBAL:
+            return globalComponents.getComponent(componentType);
+         case NAMED_CACHE:
+            return super.getComponent(componentType);
+         default:
+            throw new IllegalArgumentException("Unknown component scope " + componentScope);
+      }
+   }
+
+   @Override
+   protected Map<Class, Class<? extends ComponentFactory>> getDefaultFactoryMap()
+   {
+      // delegate to parent.  No sense maintaining multiple copies of this map.
+      return globalComponents.getDefaultFactoryMap();
+   }
+
+   @Override
+   protected ComponentFactory getFactory(Class componentClass)
+   {
+      return super.getFactory(componentClass);
+   }
+
+   public GlobalComponentRegistry getSharedComponentRegistry()
+   {
+      return globalComponents;
+   }
+}

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/factories/DefaultCacheFactory.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/DefaultCacheFactory.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/DefaultCacheFactory.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -51,11 +51,11 @@
     * @return a cache
     * @throws ConfigurationException if there are problems with the cfg
     */
-   public Cache<K, V> createCache(Configuration configuration, ComponentRegistry parentComponentRegistry, String cacheName) throws ConfigurationException
+   public Cache<K, V> createCache(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws ConfigurationException
    {
       try
       {
-         CacheSPI<K, V> cache = createAndWire(configuration, parentComponentRegistry, cacheName);
+         CacheSPI<K, V> cache = createAndWire(configuration, globalComponentRegistry, cacheName);
          cache.start();
          return cache;
       }
@@ -78,23 +78,23 @@
       return createCache(configuration, null, CacheManager.DEFAULT_CACHE_NAME);
    }
 
-   protected CacheSPI<K, V> createAndWire(Configuration configuration, ComponentRegistry parentComponentRegistry, String cacheName) throws Exception
+   protected CacheSPI<K, V> createAndWire(Configuration configuration, GlobalComponentRegistry globalComponentRegistry, String cacheName) throws Exception
    {
       CacheSPI<K, V> spi = new CacheDelegate<K, V>(cacheName);
-      bootstrap(spi, configuration, parentComponentRegistry);
+      bootstrap(spi, configuration, globalComponentRegistry);
       return spi;
    }
 
    /**
     * Bootstraps this factory with a Configuration and a ComponentRegistry.
     */
-   private void bootstrap(CacheSPI spi, Configuration configuration, ComponentRegistry parentComponentRegistry)
+   private void bootstrap(CacheSPI spi, Configuration configuration, GlobalComponentRegistry globalComponentRegistry)
    {
-      // injection bootstrap stuff
-      componentRegistry = parentComponentRegistry == null ? new ComponentRegistry(configuration, spi) : new HierarchicalComponentRegistry(configuration, spi, parentComponentRegistry);
-      componentRegistry.registerDefaultClassLoader(defaultClassLoader);
       this.configuration = configuration;
 
+      // injection bootstrap stuff
+      componentRegistry = new ComponentRegistry(configuration, spi, globalComponentRegistry);
+      componentRegistry.registerDefaultClassLoader(defaultClassLoader);
       componentRegistry.registerComponent(spi, CacheSPI.class);
       componentRegistry.registerComponent(new PlatformMBeanServerRegistration(), PlatformMBeanServerRegistration.class);
    }
@@ -114,9 +114,4 @@
    {
       throw new UnsupportedOperationException("Should never be invoked - this is a bootstrap factory.");
    }
-
-//   public Cache<K, V> createCache() throws ConfigurationException
-//   {
-//      throw new UnsupportedOperationException("Should never be invoked - this is a bootstrap factory.");
-//   }
 }

Added: core/branches/flat/src/main/java/org/jboss/starobrno/factories/GlobalComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/GlobalComponentRegistry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/GlobalComponentRegistry.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,30 @@
+package org.jboss.starobrno.factories;
+
+import org.jboss.starobrno.CacheException;
+import org.jboss.starobrno.config.GlobalConfiguration;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ */
+public class GlobalComponentRegistry extends AbstractComponentRegistry
+{
+   /**
+    * Creates an instance of the component registry.  The configuration passed in is automatically registered.
+    *
+    * @param configuration configuration with which this is created
+    */
+   public GlobalComponentRegistry(GlobalConfiguration configuration)
+   {
+      try
+      {
+         registerComponent(configuration, GlobalConfiguration.class);
+         registerComponent(this, GlobalComponentRegistry.class);
+      }
+      catch (Exception e)
+      {
+         throw new CacheException("Unable to construct a GlobalComponentRegistry!", e);
+      }
+   }
+}

Deleted: core/branches/flat/src/main/java/org/jboss/starobrno/factories/HierarchicalComponentRegistry.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/HierarchicalComponentRegistry.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/HierarchicalComponentRegistry.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -1,60 +0,0 @@
-package org.jboss.starobrno.factories;
-
-import org.jboss.starobrno.CacheSPI;
-import org.jboss.starobrno.config.Configuration;
-import org.jboss.starobrno.factories.scopes.ScopeDetector;
-import org.jboss.starobrno.factories.scopes.Scopes;
-
-import java.util.Map;
-
-/**
- * // TODO: Manik: Document this!
- *
- * @author Manik Surtani
- */
-public class HierarchicalComponentRegistry extends ComponentRegistry
-{
-   ComponentRegistry parent;
-
-   /**
-    * Creates an instance of the component registry.  The configuration passed in is automatically registered.
-    *
-    * @param configuration configuration with which this is created
-    * @param cache         cache
-    * @param parent        parent Component Registry to delegate to
-    */
-   public HierarchicalComponentRegistry(Configuration configuration, CacheSPI cache, ComponentRegistry parent)
-   {
-      super(configuration, cache);
-      this.parent = parent;
-   }
-
-   @Override
-   public <T> T getComponent(Class<T> componentType)
-   {
-      // first try in the local registry
-      Scopes componentScope = ScopeDetector.detectScope(componentType);
-      switch (componentScope)
-      {
-         case CACHE_MANAGER_ONLY:
-            return parent.getComponent(componentType);
-         case CACHE_ONLY:
-            return super.getComponent(componentType);
-         default:
-            throw new IllegalArgumentException("Unknown component scope " + componentScope);
-      }
-   }
-
-   @Override
-   protected Map<Class, Class<? extends ComponentFactory>> getDefaultFactoryMap()
-   {
-      // delegate to parent.  No sense maintaining multiple copies of this map.
-      return parent.getDefaultFactoryMap();
-   }
-
-   @Override
-   protected ComponentFactory getFactory(Class componentClass)
-   {
-      return super.getFactory(componentClass);
-   }
-}

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/factories/scopes/Scopes.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/factories/scopes/Scopes.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/factories/scopes/Scopes.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -2,7 +2,7 @@
 
 /**
  * The different scopes that can be declared for a component in the cache system.  If components are not bounded to a
- * specific scope explicity, then it defaults to the {@link #CACHE_ONLY} scope.
+ * specific scope explicity, then it defaults to the {@link #NAMED_CACHE} scope.
  *
  * @author Manik Surtani
  * @see Scope
@@ -13,16 +13,16 @@
     * Components bounded to this scope can only be created by a {@link org.jboss.starobrno.manager.CacheManager} and exist in the
     * {@link org.jboss.starobrno.manager.CacheManager}'s {@link org.jboss.starobrno.factories.ComponentRegistry}.
     */
-   CACHE_MANAGER_ONLY,
+   GLOBAL,
 
    /**
     * Components bounded to this scope can only be created by a {@link org.jboss.starobrno.Cache} and exist in the
     * {@link org.jboss.starobrno.Cache}'s {@link org.jboss.starobrno.factories.ComponentRegistry}.
     */
-   CACHE_ONLY;
+   NAMED_CACHE;
 
    public static Scopes getDefaultScope()
    {
-      return CACHE_ONLY;
+      return NAMED_CACHE;
    }
 }

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/InterceptorChain.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/InterceptorChain.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/InterceptorChain.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -46,7 +46,7 @@
  *        todo - if you add the same interceptor instance twice, things get really dirty.
  *        -- this should be treated as an missuse and an exception should be thrown
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public class InterceptorChain
 {
    /**

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/base/CommandInterceptor.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/base/CommandInterceptor.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/interceptors/base/CommandInterceptor.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -54,7 +54,7 @@
  * @see org.jboss.cache.interceptors.InterceptorChain
  * @since 2.2
  */
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public class CommandInterceptor extends AbstractVisitor
 {
    private CommandInterceptor next;

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/invocation/InvocationContextContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/invocation/InvocationContextContainer.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/invocation/InvocationContextContainer.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -36,7 +36,7 @@
  * @since 2.1.0
  */
 @NonVolatile
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public class InvocationContextContainer extends ThreadLocal<InvocationContext>
 {
    ContextFactory contextFactory;

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/loader/CacheLoader.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/loader/CacheLoader.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/loader/CacheLoader.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -62,7 +62,7 @@
  * @since 2.0.0
  */
 @ThreadSafe
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public interface CacheLoader<K, V>
 {
    /**

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/manager/CacheManager.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/manager/CacheManager.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/manager/CacheManager.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -25,10 +25,11 @@
 import org.jboss.starobrno.CacheSPI;
 import org.jboss.starobrno.config.Configuration;
 import org.jboss.starobrno.config.ConfigurationException;
+import org.jboss.starobrno.config.GlobalConfiguration;
 import org.jboss.starobrno.config.parsing.XmlConfigurationParser;
 import org.jboss.starobrno.config.parsing.XmlConfigurationParserImpl;
-import org.jboss.starobrno.factories.ComponentRegistry;
 import org.jboss.starobrno.factories.DefaultCacheFactory;
+import org.jboss.starobrno.factories.GlobalComponentRegistry;
 import org.jboss.starobrno.lifecycle.Lifecycle;
 
 import java.io.IOException;
@@ -81,10 +82,10 @@
 public class CacheManager implements Lifecycle
 {
    public static final String DEFAULT_CACHE_NAME = "org.jboss.starobrno.manager.CacheManager.DEFAULT_CACHE_NAME";
-   protected Configuration configuration;
+   protected GlobalConfiguration globalConfiguration;
    private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
    private final ConcurrentMap<String, Configuration> configurationOverrides = new ConcurrentHashMap<String, Configuration>();
-   private ComponentRegistry sharedComponentRegistry;
+   private GlobalComponentRegistry globalComponentRegistry;
 
 
    /**
@@ -92,7 +93,7 @@
     */
    public CacheManager()
    {
-      this(false);
+      this(null, null, true);
    }
 
    /**
@@ -102,32 +103,72 @@
     */
    public CacheManager(boolean start)
    {
-      configuration = new Configuration();
-      if (start) start();
+      this(null, null, start);
    }
 
    /**
-    * Constructs and starts a new instance of the CacheManager, using the configuration file passed in.
+    * Constructs and starts a new instance of the CacheManager, using the default configuration passed in.  Uses
+    * defaults for a {@link org.jboss.starobrno.config.GlobalConfiguration}.
     *
-    * @param configuration configuration file to use as a template for all caches created
+    * @param defaultConfiguration configuration to use as a template for all caches created
     */
-   public CacheManager(Configuration configuration)
+   public CacheManager(Configuration defaultConfiguration)
    {
-      this(configuration, true);
+      this(null, defaultConfiguration, true);
    }
 
    /**
-    * Constructs a new instance of the CacheManager, using the configuration file passed in.
+    * Constructs a new instance of the CacheManager, using the default configuration passed in.  Uses
+    * defaults for a {@link org.jboss.starobrno.config.GlobalConfiguration}.
     *
-    * @param configuration configuration file to use as a template for all caches created
-    * @param start         if true, the cache manager is started
+    * @param defaultConfiguration configuration file to use as a template for all caches created
+    * @param start                if true, the cache manager is started
     */
-   public CacheManager(Configuration configuration, boolean start)
+   public CacheManager(Configuration defaultConfiguration, boolean start)
    {
-      this.configuration = configuration.clone();
+      this(null, defaultConfiguration, start);
+   }
+
+   /**
+    * Constructs and starts a new instance of the CacheManager, using the global configuration passed in, and
+    * system defaults for the default named cache configuration.
+    *
+    * @param globalConfiguration GlobalConfiguration to use for all caches created
+    */
+   public CacheManager(GlobalConfiguration globalConfiguration)
+   {
+      this(globalConfiguration, null, true);
+   }
+
+   /**
+    * Constructs a new instance of the CacheManager, using the global configuration passed in, and
+    * system defaults for the default named cache configuration.
+    *
+    * @param globalConfiguration GlobalConfiguration to use for all caches created
+    * @param start               if true, the cache manager is started.
+    */
+   public CacheManager(GlobalConfiguration globalConfiguration, boolean start)
+   {
+      this(globalConfiguration, null, start);
+   }
+
+   /**
+    * Constructs a new instance of the CacheManager, using the global and default configurations passed in.  If either
+    * of these are null, system defaults are used.
+    *
+    * @param globalConfiguration  global configuration to use.  If null, a default instance is created.
+    * @param defaultConfiguration default configuration to use.  If null, a default instance is created.
+    * @param start                if true, the cache manager is started
+    */
+   public CacheManager(GlobalConfiguration globalConfiguration, Configuration defaultConfiguration, boolean start)
+   {
+      this.globalConfiguration = globalConfiguration == null ? new GlobalConfiguration() : globalConfiguration.clone();
+      this.globalConfiguration.setDefaultConfiguration(defaultConfiguration == null ? new Configuration() : defaultConfiguration.clone());
+      globalComponentRegistry = new GlobalComponentRegistry(globalConfiguration);
       if (start) start();
    }
 
+
    /**
     * Constructs and starts a new instance of the CacheManager, using the configuration file name passed in.  This constructor
     * first searches for the named file on the classpath, and failing that, treats the file name as an absolute
@@ -196,7 +237,7 @@
 
    private void initialize(XmlConfigurationParser initializedParser)
    {
-      configuration = initializedParser.parseDefaultConfiguration();
+      this.globalConfiguration = initializedParser.parseGlobalConfiguration();
       configurationOverrides.putAll(initializedParser.parseNamedConfigurations());
    }
 
@@ -260,14 +301,14 @@
 
    private Cache createCache(String cacheName)
    {
-      Configuration c = configuration.clone();
+      Configuration c = globalConfiguration.getDefaultConfiguration().clone();
       if (!cacheName.equals(DEFAULT_CACHE_NAME))
       {
          Configuration overrides = configurationOverrides.get(cacheName);
          if (overrides != null) c.applyOverrides(overrides);
       }
 
-      Cache cache = new DefaultCacheFactory().createCache(c, sharedComponentRegistry, cacheName);
+      Cache cache = new DefaultCacheFactory().createCache(c, globalComponentRegistry, cacheName);
       Cache other = caches.putIfAbsent(cacheName, cache);
       if (other == null)
       {
@@ -284,7 +325,7 @@
    {
       // get a hold of the "default" cache to start this?
       CacheSPI defaultCache = (CacheSPI) getCache();
-      sharedComponentRegistry = defaultCache.getComponentRegistry();
+      globalComponentRegistry = defaultCache.getComponentRegistry().getSharedComponentRegistry();
    }
 
    public void stop()

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/notifications/NotifierImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/notifications/NotifierImpl.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/notifications/NotifierImpl.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -65,7 +65,7 @@
  * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
  */
 @NonVolatile
- at Scope(Scopes.CACHE_ONLY)
+ at Scope(Scopes.NAMED_CACHE)
 public class NotifierImpl implements Notifier
 {
    private static final Log log = LogFactory.getLog(NotifierImpl.class);

Modified: core/branches/flat/src/main/java/org/jboss/starobrno/remoting/RPCManager.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/remoting/RPCManager.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/remoting/RPCManager.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -45,7 +45,7 @@
  * @author Manik Surtani
  * @since 2.1.0
  */
- at Scope(Scopes.CACHE_MANAGER_ONLY)
+ at Scope(Scopes.GLOBAL)
 public interface RPCManager
 {
    /**

Added: core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Address.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Address.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Address.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,10 @@
+package org.jboss.starobrno.remoting.transport;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ */
+public interface Address
+{
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Transport.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Transport.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/remoting/transport/Transport.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -0,0 +1,22 @@
+package org.jboss.starobrno.remoting.transport;
+
+import org.jboss.starobrno.lifecycle.Lifecycle;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * // TODO: Manik: Document this!
+ *
+ * @author Manik Surtani
+ */
+public interface Transport extends Lifecycle
+{
+   void setProperties(Properties p);
+
+   Address getAddress();
+
+   boolean isCoordinator();
+
+   List<Address> getMembers();
+}

Modified: core/branches/flat/src/test/java/org/jboss/starobrno/factories/scopes/ScopeDetectorTest.java
===================================================================
--- core/branches/flat/src/test/java/org/jboss/starobrno/factories/scopes/ScopeDetectorTest.java	2009-01-15 16:48:16 UTC (rev 7480)
+++ core/branches/flat/src/test/java/org/jboss/starobrno/factories/scopes/ScopeDetectorTest.java	2009-01-15 18:46:35 UTC (rev 7481)
@@ -10,28 +10,28 @@
 {
    public void testScopeOnClass()
    {
-      testScopes(Test1.class, Scopes.CACHE_MANAGER_ONLY);
+      testScopes(Test1.class, Scopes.GLOBAL);
 
    }
 
    public void testScopeOnInterface()
    {
-      testScopes(Test2.class, Scopes.CACHE_MANAGER_ONLY);
+      testScopes(Test2.class, Scopes.GLOBAL);
    }
 
    public void testScopeOnSuperClass()
    {
-      testScopes(Test3.class, Scopes.CACHE_MANAGER_ONLY);
+      testScopes(Test3.class, Scopes.GLOBAL);
    }
 
    public void testScopeOnSuperInterface()
    {
-      testScopes(Test4.class, Scopes.CACHE_MANAGER_ONLY);
+      testScopes(Test4.class, Scopes.GLOBAL);
    }
 
    public void testNoScopes()
    {
-      testScopes(Test6.class, Scopes.CACHE_ONLY);
+      testScopes(Test6.class, Scopes.NAMED_CACHE);
    }
 
    private void testScopes(Class clazz, Scopes expected)
@@ -45,13 +45,13 @@
 
    }
 
-   @Scope(Scopes.CACHE_MANAGER_ONLY)
+   @Scope(Scopes.GLOBAL)
    public static interface Scoped
    {
 
    }
 
-   @Scope(Scopes.CACHE_MANAGER_ONLY)
+   @Scope(Scopes.GLOBAL)
    public static class SuperScoped
    {
 
@@ -62,7 +62,7 @@
 
    }
 
-   @Scope(Scopes.CACHE_MANAGER_ONLY)
+   @Scope(Scopes.GLOBAL)
    public static class Test1
    {
 




More information about the jbosscache-commits mailing list