You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by hl...@apache.org on 2003/10/01 22:43:24 UTC

cvs commit: jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test TestMisc.java

hlship      2003/10/01 13:43:24

  Modified:    hivemind/framework/src/test/hivemind/test/services
                        TestServices.java
               hivemind/framework/src/java/org/apache/commons/hivemind/schema
                        SchemaProcessor.java
               hivemind/xdocs override.xml services.xml
               hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        ConfigurationPointImpl.java ModuleImpl.java
                        SingletonServiceModel.java ProxyBuilder.java
                        AbstractServiceModelImpl.java RegistryBuilder.java
                        DeferredServiceModel.java
                        ServiceExtensionPointImpl.java
                        ElementsProxyList.java RegistryImpl.java
                        SchemaProcessorImpl.java ThreadedServiceModel.java
               hivemind/framework/src/java/org/apache/commons/hivemind
                        Module.java HiveMindMessages.properties
                        Registry.java HiveMind.java
               hivemind/framework/src/test/hivemind/test/rules
                        MockModule.java
               hivemind/framework/src/test/hivemind/test/parse
                        TestToString.java
               hivemind/framework/src/java/org/apache/commons/hivemind/parse
                        DescriptorParser.java
               hivemind/framework/src/test/hivemind/test/config
                        TestConfigurationPoint.java
               hivemind/framework/src/test/hivemind/test TestMisc.java
  Added:       hivemind/framework/src/test/hivemind/test/services/impl
                        RunnableImpl.java
               hivemind/framework/src/test/hivemind/test/services
                        TestShutdown.java Shutdown.xml
               hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        ShutdownCoordinator.java
                        ConstructableServiceExtensionPoint.java
                        ElementsInnerProxyList.java ContributionImpl.java
               hivemind/framework/src/java/org/apache/commons/hivemind
                        Contribution.java RegistryShutdownListener.java
               hivemind/framework/src/test/hivemind/test/util
                        TestShutdownCoordinator.java
  Removed:     hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        ConfigurationImpl.java
               hivemind/framework/src/java/org/apache/commons/hivemind
                        ConstructableServiceExtensionPoint.java
                        Configuration.java
  Log:
  Add Registry.shutdown(), RegistryShutdownListener and all related support.
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/services/impl/RunnableImpl.java
  
  Index: RunnableImpl.java
  ===================================================================
  package hivemind.test.services.impl;
  
  import org.apache.commons.hivemind.RegistryShutdownListener;
  import org.apache.commons.logging.Log;
  
  
  /**
   * Used to test that singleton and deferred services properly registrer
   * core impls for registry shutdown.
   *
   * @author Howard Lewis Ship
   * @version $Id: RunnableImpl.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public class RunnableImpl implements Runnable, RegistryShutdownListener
  {
  	private Log _log;
  	private String _type;
  	
      public void run()
      {
  		_log.debug("run -- " + _type);
      }
  
      public void registryDidShutdown()
      {
  		_log.debug("registryDidShutdown -- " + _type);
      }
  
      public void setType(String string)
      {
          _type = string;
      }
  
      public void setLog(Log log)
      {
          _log = log;
      }
  
  }
  
  
  
  1.5       +1 -9      jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/services/TestServices.java
  
  Index: TestServices.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/services/TestServices.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestServices.java	22 Sep 2003 20:06:00 -0000	1.4
  +++ TestServices.java	1 Oct 2003 20:43:21 -0000	1.5
  @@ -131,14 +131,6 @@
           assertEquals(19, s.add(11, 8));
   
           assertEquals(2, CountFactory.getCount());
  -
  -        SimpleService s2 =
  -            (SimpleService) r.getService("hivemind.test.services.Simple", SimpleService.class);
  -        assertNotSame(s, s2);
  -
  -        assertEquals(
  -            "<Interceptor: hivemind.test.services.CountFactory for hivemind.test.services.Simple(hivemind.test.services.SimpleService)>",
  -            s2.toString());
       }
   
       public void testInterceptorSort() throws Exception
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/services/TestShutdown.java
  
  Index: TestShutdown.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package hivemind.test.services;
  
  import hivemind.test.FrameworkTestCase;
  
  import org.apache.commons.hivemind.ApplicationRuntimeException;
  import org.apache.commons.hivemind.Registry;
  
  /**
   * Tests shutdown on the registry and on deferred and threaded services.
   *
   * @author Howard Lewis Ship
   * @version $Id: TestShutdown.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public class TestShutdown extends FrameworkTestCase
  {
  
      public TestShutdown(String name)
      {
          super(name);
      }
  
      public void testShutdownDeferred() throws Exception
      {
          Registry r = buildFrameworkRegistry("SimpleModule.xml");
          SimpleService s =
              (SimpleService) r.getService("hivemind.test.services.Simple", SimpleService.class);
  
          assertEquals(11, s.add(4, 7));
  
          r.shutdown();
  
          try
          {
              s.add(9, 5);
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertExceptionSubstring(ex, "The HiveMind Registry has been shutdown.");
          }
      }
  
      public void testRegistryShutdownUnrepeatable() throws Exception
      {
          Registry r = buildFrameworkRegistry("SimpleModule.xml");
  
          r.shutdown();
  
          try
          {
              r.getConfiguration("foo.bar");
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertExceptionSubstring(ex, "The HiveMind Registry has been shutdown.");
          }
  
          try
          {
              r.shutdown();
          }
          catch (NullPointerException ex)
          {
          }
      }
  
      public void testShutdownThreaded() throws Exception
      {
          Registry r = buildFrameworkRegistry("StringHolder.xml");
  
          StringHolder h =
              (StringHolder) r.getService("hivemind.test.services.StringHolder", StringHolder.class);
  
          assertNull(h.getValue());
  
          h.setValue("fred");
  
          assertEquals("fred", h.getValue());
  
          r.shutdown();
  
          try
          {
              h.getValue();
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertExceptionSubstring(ex, "The HiveMind Registry has been shutdown.");
          }
      }
  
      public void testDeferredCore() throws Exception
      {
          Registry r = buildFrameworkRegistry("Shutdown.xml");
  
          Runnable s = (Runnable) r.getService("hivemind.test.services.Deferred", Runnable.class);
  
          interceptLogging("hivemind.test");
  
          s.run();
  
          assertLoggedMessage("run -- Deferred");
  
          r.shutdown();
  
          assertLoggedMessage("registryDidShutdown -- Deferred");
      }
      
  	public void testSingletonCore() throws Exception
  	{
  		Registry r = buildFrameworkRegistry("Shutdown.xml");
  
  		Runnable s = (Runnable) r.getService("hivemind.test.services.Singleton", Runnable.class);
  
  		interceptLogging("hivemind.test");
  
  		s.run();
  
  		assertLoggedMessage("run -- Singleton");
  
  		r.shutdown();
  
  		assertLoggedMessage("registryDidShutdown -- Singleton");
  	}    
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/services/Shutdown.xml
  
  Index: Shutdown.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <!-- $Id: Shutdown.xml,v 1.1 2003/10/01 20:43:21 hlship Exp $ -->
  <module
  	id="hivemind.test.services" 
  	version="1.0.0">
  	<service-point id="Singleton" interface="java.lang.Runnable" model="singleton">
  		<invoke-factory service-id="hivemind.BuilderFactory">
  		  <construct class="hivemind.test.services.impl.RunnableImpl" log-property="log">
  		  	<set property="type" value="Singleton"/>	
  		  </construct>	
  		</invoke-factory>
  	</service-point>
  	
  	<service-point id="Deferred" interface="java.lang.Runnable" model="deferred">
  		<invoke-factory service-id="hivemind.BuilderFactory">
  		  <construct class="hivemind.test.services.impl.RunnableImpl" log-property="log">
  		  	<set property="type" value="Deferred"/>	
  		  </construct>	
  		</invoke-factory>
  	</service-point>	
  </module>
  
  
  1.3       +2 -2      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/schema/SchemaProcessor.java
  
  Index: SchemaProcessor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/schema/SchemaProcessor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SchemaProcessor.java	18 Sep 2003 19:01:00 -0000	1.2
  +++ SchemaProcessor.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -61,7 +61,7 @@
   
   /**
    * Object used when processing the elements contributed
  - * in an {@link org.apache.commons.hivemind.Configuration}.
  + * in an {@link org.apache.commons.hivemind.Contribution}.
    *
    * @author Howard Lewis Ship
    * @version $Id$
  
  
  
  1.6       +3 -3      jakarta-commons-sandbox/hivemind/xdocs/override.xml
  
  Index: override.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/override.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- override.xml	29 Sep 2003 16:16:35 -0000	1.5
  +++ override.xml	1 Oct 2003 20:43:21 -0000	1.6
  @@ -115,8 +115,8 @@
   <?xml version="1.0"?>
   <module id="ex.override" version="1.0.0">
     <service-point id="Provider" interface="ex.override.Provider">
  -    <service-point class="ex.override.impl.ProviderImpl"/>
  -  </service>
  +    <create-instance class="ex.override.impl.ProviderImpl"/>
  +  </service-point>
     
     <contribution configuration-id="hivemind.FactoryDefaults">
       <default symbol="ex.override.Provider" value="ex.override.Provider"/>
  
  
  
  1.27      +45 -1     jakarta-commons-sandbox/hivemind/xdocs/services.xml
  
  Index: services.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/services.xml,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- services.xml	29 Sep 2003 16:16:35 -0000	1.26
  +++ services.xml	1 Oct 2003 20:43:21 -0000	1.27
  @@ -382,6 +382,50 @@
   			
   		</section>
   		
  +<section name="Service Lifecycle">
  +
  +<p>
  +As discussed, the service model determines when a service is instantiated.  In many cases, the service needs to know when it
  +has been created (to perform any final initializations) or when the Registry has been shut down.	
  +</p>	
  +
  +<p>
  +The
  +	<a href="&apiroot;/Initializable.html">Initializable</a>
  +	interface may be implemented by the core service implementation.
  +	The <code>initializeService()</code> method is invoked after the service implementation is fully constructed, including
  +	any interceptors, and after all properties of the core service instance have been configured
  +	(including properties which are themselves other services).  The interface is optional.	
  +	</p>
  +	
  +<p>
  +A core service implementation may also implement the
  +<a href="&apiroot;/RegistryShutdownListener.html">RegistryShutdownListener</a>	
  +interface. When a Registry is 
  +<a href="&apiroot;/Registry.html#shutdown()">shutdown</a>, 
  +the <code>registryDidShutdown()</code> method is invoked
  +on all services (and many other objects, such as proxies). The order in which these notifications occur
  +is not defined.  A service may release any resources it may hold at this time. It should not invoke
  +methods on other service interfaces.
  +</p>
  +
  +<p>
  +<b>Note:</b> the threaded service model does <b>not</b> registry services for Registry shutdown notification.
  +It doesn't matter if the core service implementation implements the RegistryShutdownListener
  +interface or not.
  +</p>
  +
  +<p>
  +It is preferred that, whenever possible, services use the deferred service model (the default) and not
  +the singleton model.  The deferred service model (as well as the threaded service models) expose
  +a <b>proxy</b> object (implementing the service interface) to client code (included other services).
  +These proxies are aware of when the Registry is shutdown and will thrown an exception when a service method
  +is invoked on them.
  +</p>
  +	
  +</section>
  +		
  +		
   		<section name="Frequently Asked Questions">
   			<ul>
   				<li><strong>Why do I pass the interface class to getService()</strong>? 
  
  
  
  1.3       +35 -21    jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ConfigurationPointImpl.java
  
  Index: ConfigurationPointImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ConfigurationPointImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ConfigurationPointImpl.java	29 Sep 2003 15:36:52 -0000	1.2
  +++ ConfigurationPointImpl.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -62,7 +62,7 @@
   import java.util.List;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
  -import org.apache.commons.hivemind.Configuration;
  +import org.apache.commons.hivemind.Contribution;
   import org.apache.commons.hivemind.ConfigurationPoint;
   import org.apache.commons.hivemind.HiveMind;
   import org.apache.commons.hivemind.Occurances;
  @@ -73,7 +73,7 @@
   
   /**
    * Implementation of the {@link org.apache.commons.hivemind.ConfigurationPoint} interface; a container
  - * for {@link org.apache.commons.hivemind.Configuration}s.
  + * for {@link org.apache.commons.hivemind.Contribution}s.
    *
    * @author Howard Lewis Ship
    * @version $Id$
  @@ -88,47 +88,48 @@
       private List _elements;
       private List _elementsProxy;
       private Occurances _expectedCount;
  -    private List _configurations;
  +    private List _contributions;
       private boolean _building;
       private Schema _contributionsSchema;
  +    private ShutdownCoordinator _shutdownCoordinator;
   
       protected void extendDescription(ToStringBuilder builder)
       {
           builder.append("expectedCount", _expectedCount);
  -        builder.append("configurations", _configurations);
  +        builder.append("contributions", _contributions);
           builder.append("schema", _contributionsSchema);
       }
   
       /**
        * Returns the number of contributions; it is expected
        * that each top-level {@link org.apache.commons.hivemind.Element}
  -     * in each {@link Configuration} will convert to one element instance;
  +     * in each {@link Contribution} will convert to one element instance;
        * the value returned is the total number of top-level elements
        * in all contributed Extensions. 
        */
       public int getContributionCount()
       {
  -        if (_configurations == null)
  +        if (_contributions == null)
               return 0;
   
           int total = 0;
   
  -        int count = _configurations.size();
  +        int count = _contributions.size();
           for (int i = 0; i < count; i++)
           {
  -            Configuration c = (Configuration) _configurations.get(i);
  +            Contribution c = (Contribution) _contributions.get(i);
               total += c.getElements().size();
           }
   
           return total;
       }
   
  -    public void addConfiguration(Configuration c)
  +    public void addContribution(Contribution c)
       {
  -        if (_configurations == null)
  -            _configurations = new ArrayList();
  +        if (_contributions == null)
  +            _contributions = new ArrayList();
   
  -        _configurations.add(c);
  +        _contributions.add(c);
       }
   
       public Occurances getExpectedCount()
  @@ -142,7 +143,7 @@
       }
   
   	/**
  -	 * Returns the elements as an unmodifiable {@link List}.
  +	 * Returns the contributed elements as an unmodifiable {@link List}.
   	 * Internally, a proxy to the real list is returned, such that the
   	 * real list may not be constructed until actually needed.
   	 */
  @@ -152,15 +153,23 @@
               return _elements;
   
           if (_elementsProxy == null)
  -            _elementsProxy = new ElementsProxyList(this);
  +        {
  +			ElementsProxyList outerProxy = new ElementsProxyList();
  +			
  +			new ElementsInnerProxyList(this, outerProxy);
  +			
  +			_shutdownCoordinator.addRegistryShutdownListener(outerProxy);
  +			
  +			_elementsProxy = outerProxy;
  +        }
   
           return _elementsProxy;
       }
   
   	/**
  -	 * Invoked by {@link ElementsProxyList} when the actual list
  +	 * Invoked by {@link ElementsInnerProxyList} when the actual list
   	 * is needed.  Returns the List (which is modifiable, but
  -	 * that's OK because ElementsProxyList is unmodifiable) and,
  +	 * that's OK because ElementsInnerProxyList is unmodifiable) and,
   	 * as a side effect, keeps a reference to an unmodifiable
   	 * version of the result for future invocations
   	 * of {@link #getElements()}.
  @@ -192,7 +201,7 @@
               _elements = Collections.unmodifiableList(result);
               
               _contributionsSchema = null;
  -            _configurations = null;
  +            _contributions = null;
   		
   			// Now that we have the real list, we don't need the proxy
   			// anymore, either.
  @@ -218,18 +227,18 @@
           if (LOG.isDebugEnabled())
               LOG.debug("Constructing extension point " + getExtensionPointId());
   
  -        if (_configurations == null)
  +        if (_contributions == null)
               return Collections.EMPTY_LIST;
   
           SchemaProcessorImpl processor = new SchemaProcessorImpl(_contributionsSchema);
   
  -        int count = _configurations.size();
  +        int count = _contributions.size();
   
           try
           {
               for (int i = 0; i < count; i++)
               {
  -                Configuration extension = (Configuration) _configurations.get(i);
  +                Contribution extension = (Contribution) _contributions.get(i);
   
                   processor.process(extension.getElements(), extension.getContributingModule());
               }
  @@ -261,6 +270,11 @@
       public Schema getContributionsSchema()
       {
           return _contributionsSchema;
  +    }
  +
  +    public void setShutdownCoordinator(ShutdownCoordinator coordinator)
  +    {
  +        _shutdownCoordinator = coordinator;
       }
   
   }
  
  
  
  1.3       +4 -5      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ModuleImpl.java
  
  Index: ModuleImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ModuleImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ModuleImpl.java	18 Sep 2003 19:00:58 -0000	1.2
  +++ ModuleImpl.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -114,7 +114,7 @@
   
       public List getConfiguration(String extensionPointId)
       {
  -        ConfigurationPoint point = getExtensionPoint(extensionPointId);
  +        ConfigurationPoint point = getConfigurationPoint(extensionPointId);
   
           return point.getElements();
       }
  @@ -127,7 +127,7 @@
        * if this module does not contain the named configuration extension point.
        */
   
  -    private ConfigurationPoint getExtensionPoint(String configurationId)
  +    public ConfigurationPoint getConfigurationPoint(String configurationId)
       {
           ConfigurationPoint result = null;
   
  @@ -212,8 +212,7 @@
           ToStringBuilder builder = new ToStringBuilder(this);
   
           builder.append("moduleId", _moduleId);
  -
  -        builder.append("resourceResolver", _resolver);
  +        builder.append("classResolver", _resolver);
   
           return builder.toString();
       }
  
  
  
  1.2       +18 -3     jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/SingletonServiceModel.java
  
  Index: SingletonServiceModel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/SingletonServiceModel.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SingletonServiceModel.java	29 Sep 2003 15:32:25 -0000	1.1
  +++ SingletonServiceModel.java	1 Oct 2003 20:43:21 -0000	1.2
  @@ -57,7 +57,7 @@
   
   package org.apache.commons.hivemind.impl;
   
  -import org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
  +import org.apache.commons.hivemind.RegistryShutdownListener;
   
   /**
    * Implementation of {@link org.apache.commons.hivemind.ServiceExtensionPoint}.
  @@ -65,7 +65,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class SingletonServiceModel extends AbstractServiceModelImpl
  +public final class SingletonServiceModel extends AbstractServiceModelImpl
   {
       private Object _constructedService;
   
  @@ -84,6 +84,21 @@
               _constructedService = constructServiceImplementation();
   
           return _constructedService;
  +    }
  +
  +	/**
  +	 * Overrides the super implementation to see if the
  +	 * core service implementation implements {@link RegistryShutdownListener}.
  +	 */
  +    protected void initializeCoreServiceImplementation(Object core, Object intercepted)
  +    {
  +        super.initializeCoreServiceImplementation(core, intercepted);
  +
  +        if (core instanceof RegistryShutdownListener)
  +        {
  +            getServicePoint().getShutdownCoordinator().addRegistryShutdownListener(
  +                (RegistryShutdownListener) core);
  +        }
       }
   
   }
  
  
  
  1.2       +2 -2      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ProxyBuilder.java
  
  Index: ProxyBuilder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ProxyBuilder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProxyBuilder.java	22 Sep 2003 20:05:59 -0000	1.1
  +++ ProxyBuilder.java	1 Oct 2003 20:43:21 -0000	1.2
  @@ -74,7 +74,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class ProxyBuilder
  +public final class ProxyBuilder
   {
       private ServiceExtensionPoint _point;
       private Class _serviceInterface;
  
  
  
  1.2       +0 -1      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/AbstractServiceModelImpl.java
  
  Index: AbstractServiceModelImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/AbstractServiceModelImpl.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractServiceModelImpl.java	29 Sep 2003 15:32:25 -0000	1.1
  +++ AbstractServiceModelImpl.java	1 Oct 2003 20:43:21 -0000	1.2
  @@ -60,7 +60,6 @@
   import java.util.List;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
  -import org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
   import org.apache.commons.hivemind.HiveMind;
   import org.apache.commons.hivemind.Initializable;
   import org.apache.commons.hivemind.ServiceImplementationConstructor;
  
  
  
  1.8       +19 -7     jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java
  
  Index: RegistryBuilder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- RegistryBuilder.java	29 Sep 2003 15:36:52 -0000	1.7
  +++ RegistryBuilder.java	1 Oct 2003 20:43:21 -0000	1.8
  @@ -101,7 +101,7 @@
    * and runtime logic.  Runtime logic is synchronized and threadsafe.  Construction-time logic
    * is not threadsafe.  Methods such as {@link org.apache.commons.hivemind.impl.RegistryImpl#addModule(Module)},
    * {@link org.apache.commons.hivemind.impl.ModuleImpl#addConfigurationPoint(ConfigurationPoint)},
  - * {@link org.apache.commons.hivemind.impl.ConfigurationPointImpl#addConfiguration(Configuration)}
  + * {@link org.apache.commons.hivemind.impl.ConfigurationPointImpl#addConfiguration(Contribution)}
    * and the like are construction-time.  Once the registry is fully constructed, it is not
    * allowed to invoke those methods (though, at this time, no checks occur).
    * 
  @@ -155,6 +155,12 @@
        */
       private DescriptorParser _parser;
   
  +    /**
  +     * Shutdown coordinator shared by all objects.
  +     */
  +
  +    private ShutdownCoordinator _shutdownCoordinator = new ShutdownCoordinator();
  +
       private static class DefaultErrorHandler implements ErrorHandler
       {
   
  @@ -336,7 +342,7 @@
               point.setServiceInterfaceName(sd.getInterfaceClassName());
               point.setParametersSchema(sd.getParametersSchema());
   
  -             ServiceModelType modelType = sd.getModel();
  +            ServiceModelType modelType = sd.getModel();
               ServiceModel model = null;
   
               if (modelType == ServiceModelType.DEFERRED)
  @@ -349,12 +355,14 @@
   
               point.setServiceModel(model);
   
  -			module.addServicePoint(point);
  +            point.setShutdownCoordinator(_shutdownCoordinator);
  +
  +            module.addServicePoint(point);
   
               // Save this for the second phase, where contributions
               // from other modules are applied.
   
  -           _servicePoints.put(pointId, point);
  +            _servicePoints.put(pointId, point);
   
               addInternalImplementations(module, pointId, sd);
           }
  @@ -383,6 +391,8 @@
               point.setExpectedCount(cpd.getCount());
               point.setContributionsSchema(cpd.getContributionsSchema());
   
  +            point.setShutdownCoordinator(_shutdownCoordinator);
  +
               module.addConfigurationPoint(point);
   
               // Needed later when we reconcile the rest
  @@ -403,11 +413,11 @@
           if (LOG.isDebugEnabled())
               LOG.debug("Adding extensions to configuration point " + point.getExtensionPointId());
   
  -        ConfigurationImpl c = new ConfigurationImpl();
  +        ContributionImpl c = new ContributionImpl();
           c.setContributingModule(sourceModule);
           c.addElements(elements);
   
  -        point.addConfiguration(c);
  +        point.addContribution(c);
       }
   
       /**
  @@ -440,6 +450,8 @@
           checkContributionCounts();
   
           RegistryImpl result = new RegistryImpl(locale);
  +
  +        result.setShutdownCoordinator(_shutdownCoordinator);
   
           // Add each module to the registry.
   
  
  
  
  1.2       +57 -21    jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/DeferredServiceModel.java
  
  Index: DeferredServiceModel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/DeferredServiceModel.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeferredServiceModel.java	29 Sep 2003 15:32:25 -0000	1.1
  +++ DeferredServiceModel.java	1 Oct 2003 20:43:21 -0000	1.2
  @@ -61,8 +61,8 @@
   import java.lang.reflect.Modifier;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
  -import org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
   import org.apache.commons.hivemind.ServiceExtensionPoint;
  +import org.apache.commons.hivemind.RegistryShutdownListener;
   import org.apache.commons.hivemind.service.BodyBuilder;
   import org.apache.commons.hivemind.service.ClassFab;
   
  @@ -74,7 +74,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class DeferredServiceModel extends AbstractServiceModelImpl
  +public final class DeferredServiceModel extends AbstractServiceModelImpl
   {
       /**
        * Name of a method in the deferred proxy that is used to obtain
  @@ -92,10 +92,10 @@
   
       public synchronized Object getServiceImplementation()
       {
  -        if (_constructedService != null)
  -            return _constructedService;
  +		if (_serviceProxy == null)
  +			_serviceProxy = createDeferredProxy();
   
  -        return getServiceProxy();
  +		return _serviceProxy;
       }
   
       /**
  @@ -109,18 +109,21 @@
           return _constructedService;
       }
   
  -    /**
  -     * Returns the proxy, creating it if necessary.
  -     * 
  -     */
  -
  -    protected Object getServiceProxy()
  -    {
  -        if (_serviceProxy == null)
  -            _serviceProxy = createDeferredProxy();
  -
  -        return _serviceProxy;
  -    }
  +	/**
  +	 * Overrides the super implementation to see if the
  +	 * core service implementation implements {@link RegistryShutdownListener}.
  +	 */
  +	
  +	protected void initializeCoreServiceImplementation(Object core, Object intercepted)
  +	{
  +		super.initializeCoreServiceImplementation(core, intercepted);
  +
  +		if (core instanceof RegistryShutdownListener)
  +		{
  +			getServicePoint().getShutdownCoordinator().addRegistryShutdownListener(
  +				(RegistryShutdownListener) core);
  +		}
  +	}
   
       /**
        * Creates a proxy class for the service and then constructs the class itself.
  @@ -154,6 +157,8 @@
   
               c.newInstance(new Object[] { result, this });
   
  +			getServicePoint().getShutdownCoordinator().addRegistryShutdownListener((RegistryShutdownListener)result);
  +
               return result;
           }
           catch (Exception ex)
  @@ -177,9 +182,9 @@
       {
           ConstructableServiceExtensionPoint servicePoint = getServicePoint();
   
  -        ProxyBuilder builder = new ProxyBuilder("DeferredProxy", servicePoint);
  +        ProxyBuilder proxyBuilder = new ProxyBuilder("DeferredProxy", servicePoint);
   
  -        ClassFab classFab = builder.getClassFab();
  +        ClassFab classFab = proxyBuilder.getClassFab();
   
           Class serviceInterface = servicePoint.getServiceInterface();
   
  @@ -187,6 +192,17 @@
           // service implementation.
   
           classFab.addField("_inner", serviceInterface);
  +        classFab.addField("_shutdown", boolean.class);
  +
  +        classFab.addInterface(RegistryShutdownListener.class);
  +
  +        classFab.addMethod(
  +            Modifier.PUBLIC | Modifier.FINAL,
  +            "registryDidShutdown",
  +            Void.TYPE,
  +            null,
  +            null,
  +            "{ _shutdown = true; }");
   
           classFab.addMethod(
               Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.FINAL,
  @@ -196,7 +212,27 @@
               null,
               "{ _inner = $1; }");
   
  -        builder.addServiceMethods("_inner");
  +        BodyBuilder builder = new BodyBuilder();
  +        builder.begin();
  +        builder.addln("if (_shutdown)");
  +        builder.begin();
  +        builder.addln("_inner = null;");
  +        builder.addln(
  +            "throw org.apache.commons.hivemind.HiveMind#createRegistryShutdownException();");
  +        builder.end();
  +
  +        builder.addln("return _inner;");
  +        builder.end();
  +
  +        classFab.addMethod(
  +            Modifier.PRIVATE,
  +            "_getInner",
  +            serviceInterface,
  +            null,
  +            null,
  +            builder.toString());
  +
  +        proxyBuilder.addServiceMethods("_getInner()");
   
           return classFab.createClass();
       }
  
  
  
  1.4       +14 -14    jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ServiceExtensionPointImpl.java
  
  Index: ServiceExtensionPointImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ServiceExtensionPointImpl.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ServiceExtensionPointImpl.java	29 Sep 2003 15:32:25 -0000	1.3
  +++ ServiceExtensionPointImpl.java	1 Oct 2003 20:43:21 -0000	1.4
  @@ -62,7 +62,6 @@
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
   import org.apache.commons.hivemind.ClassResolver;
  -import org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
   import org.apache.commons.hivemind.HiveMind;
   import org.apache.commons.hivemind.ServiceImplementationConstructor;
   import org.apache.commons.hivemind.ServiceInterceptorContribution;
  @@ -81,7 +80,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class ServiceExtensionPointImpl
  +public final class ServiceExtensionPointImpl
       extends AbstractExtensionPoint
       implements ConstructableServiceExtensionPoint
   {
  @@ -95,6 +94,7 @@
       private boolean _interceptorsSorted;
       private Schema _parametersSchema;
       private ServiceModel _serviceModel;
  +    private ShutdownCoordinator _shutdownCoordinator;
   
       protected void extendDescription(ToStringBuilder builder)
       {
  @@ -113,11 +113,6 @@
           _interceptorContributions.add(contribution);
       }
   
  -    public String getServiceInterfaceName()
  -    {
  -        return _serviceInterfaceName;
  -    }
  -
       public synchronized Class getServiceInterface()
       {
           if (_serviceInterface == null)
  @@ -173,11 +168,6 @@
           _parametersSchema = schema;
       }
   
  -    public void setInterceptorContributions(List interceptorContributions)
  -    {
  -        _interceptorContributions = interceptorContributions;
  -    }
  -
       public Schema getParametersSchema()
       {
           return _parametersSchema;
  @@ -209,7 +199,7 @@
                       "BaseModule.service-wrong-interface",
                       getExtensionPointId(),
                       serviceInterface.getName(),
  -                    getServiceInterfaceName()),
  +                    _serviceInterfaceName),
                   getLocation(),
                   null);
           }
  @@ -245,6 +235,16 @@
           }
   
           return _interceptorContributions;
  +    }
  +
  +    public ShutdownCoordinator getShutdownCoordinator()
  +    {
  +        return _shutdownCoordinator;
  +    }
  +
  +    public void setShutdownCoordinator(ShutdownCoordinator coordinator)
  +    {
  +        _shutdownCoordinator = coordinator;
       }
   
   }
  
  
  
  1.3       +31 -28    jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ElementsProxyList.java
  
  Index: ElementsProxyList.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ElementsProxyList.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ElementsProxyList.java	18 Sep 2003 19:00:58 -0000	1.2
  +++ ElementsProxyList.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -60,60 +60,63 @@
   import java.util.AbstractList;
   import java.util.List;
   
  +import org.apache.commons.hivemind.HiveMind;
  +import org.apache.commons.hivemind.RegistryShutdownListener;
  +
   /**
  - * Implements a {@link java.util.List} as a proxy to an actual list of
  - * elements, provided by an extension point. The proxy is unmodifiable
  - * and will work with the extension point to generate the real list
  - * of elements in a just-in-time manner.
  + * The List implementation visible to the client code. It defers
  + * to another inner implementation of List; initially this is
  + * a {@link org.apache.commons.hivemind.impl.ElementsInnerProxyList}, but the
  + * inner proxy replaces itself with a real List implementation containing
  + * the actual configuration elements.
    *
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -final class ElementsProxyList extends AbstractList
  +public final class ElementsProxyList extends AbstractList implements RegistryShutdownListener
   {
       private List _inner;
  -    private ConfigurationPointImpl _point;
  +    private boolean _shutdown;
   
  -    ElementsProxyList(ConfigurationPointImpl point)
  +    public void registryDidShutdown()
       {
  -        _point = point;
  +        _shutdown = true;
  +        _inner = null;
       }
   
  -    private synchronized List inner()
  +    private void checkShutdown()
       {
  -        if (_inner == null)
  -            _inner = _point.constructElements();
  -
  -        return _inner;
  +        if (_shutdown)
  +            throw HiveMind.createRegistryShutdownException();
       }
   
       public Object get(int index)
       {
  -        return inner().get(index);
  +        checkShutdown();
  +
  +        return _inner.get(index);
       }
   
       public int size()
       {
  -        return inner().size();
  +        checkShutdown();
  +
  +        return _inner.size();
       }
   
  +    public String toString()
  +    {
  +        return _inner.toString();
  +    }
  +    
       public boolean equals(Object o)
       {
  -        if (this == o)
  -            return true;
  -
  -        if (o == null)
  -            return false;
  -
  -        return inner().equals(o);
  +    	return _inner.equals(o);
       }
   
  -    public String toString()
  +    public void setInner(List list)
       {
  -   		if (_inner != null)
  -   			return _inner.toString();
  -   			
  -   		return "<Element List Proxy for " + _point.getExtensionPointId() + ">";
  +        _inner = list;
       }
   
   }
  
  
  
  1.3       +24 -3     jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/RegistryImpl.java
  
  Index: RegistryImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/RegistryImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- RegistryImpl.java	18 Sep 2003 19:00:58 -0000	1.2
  +++ RegistryImpl.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -86,6 +86,7 @@
       private Map _modules = new HashMap();
       private SymbolSource[] _variableSources;
       private Locale _locale;
  +    private ShutdownCoordinator _shutdownCoordinator;
   
       public RegistryImpl(Locale locale)
       {
  @@ -109,6 +110,9 @@
   
       public Module getModule(String moduleId)
       {
  +        if (_modules == null)
  +            throw HiveMind.createRegistryShutdownException();
  +
           Module result = (Module) _modules.get(moduleId);
   
           if (result == null)
  @@ -329,8 +333,7 @@
           if (_variableSources != null)
               return _variableSources;
   
  -        List contributions =
  -            HiveMind.sortOrderables(getConfiguration("hivemind.SymbolSource"));
  +        List contributions = HiveMind.sortOrderables(getConfiguration("hivemind.SymbolSource"));
   
           int count = contributions.size();
   
  @@ -343,5 +346,23 @@
           }
   
           return _variableSources;
  +    }
  +
  +    public void setShutdownCoordinator(ShutdownCoordinator coordinator)
  +    {
  +        _shutdownCoordinator = coordinator;
  +    }
  +
  +    /**
  +     * Invokes {@link ShutdownCoordinator#shutdown()}, then releases
  +     * the coordinator, modules and variable sources.
  +     */
  +    public void shutdown()
  +    {
  +        _shutdownCoordinator.shutdown();
  +
  +        _modules = null;
  +        _shutdownCoordinator = null;
  +        _variableSources = null;
       }
   }
  
  
  
  1.3       +2 -2      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/SchemaProcessorImpl.java
  
  Index: SchemaProcessorImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/SchemaProcessorImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SchemaProcessorImpl.java	18 Sep 2003 19:00:58 -0000	1.2
  +++ SchemaProcessorImpl.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -72,7 +72,7 @@
   import org.apache.commons.logging.LogFactory;
   
   /**
  - * Used to assemble all the {@link org.apache.commons.hivemind.Configuration}s
  + * Used to assemble all the {@link org.apache.commons.hivemind.Contribution}s
    * contributed to an {@link org.apache.commons.hivemind.ConfigurationPoint} while
    * converting the XML (represented as {@link org.apache.commons.hivemind.Element}s
    * into Java objects.
  
  
  
  1.3       +30 -14    jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ThreadedServiceModel.java
  
  Index: ThreadedServiceModel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ThreadedServiceModel.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ThreadedServiceModel.java	29 Sep 2003 16:16:06 -0000	1.2
  +++ ThreadedServiceModel.java	1 Oct 2003 20:43:21 -0000	1.3
  @@ -61,8 +61,8 @@
   import java.lang.reflect.Modifier;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
  -import org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
   import org.apache.commons.hivemind.Registry;
  +import org.apache.commons.hivemind.RegistryShutdownListener;
   import org.apache.commons.hivemind.service.BodyBuilder;
   import org.apache.commons.hivemind.service.ClassFab;
   import org.apache.commons.hivemind.service.ThreadCleanupListener;
  @@ -79,7 +79,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class ThreadedServiceModel extends AbstractServiceModelImpl
  +public final class ThreadedServiceModel extends AbstractServiceModelImpl
   {
       /**
        * Name of a method in the deferred proxy that is used to obtain
  @@ -116,16 +116,6 @@
        */
       public synchronized Object getServiceImplementation()
       {
  -        return getServiceProxy();
  -    }
  -
  -    /**
  -     * Returns the proxy, creating it if necessary.
  -     * 
  -     */
  -
  -    protected Object getServiceProxy()
  -    {
           if (_serviceProxy == null)
               _serviceProxy = createServiceProxy();
   
  @@ -147,7 +137,12 @@
   
               Constructor c = proxyClass.getConstructor(new Class[] { getClass()});
   
  -            return c.newInstance(new Object[] { this });
  +            Object result = c.newInstance(new Object[] { this });
  +
  +            getServicePoint().getShutdownCoordinator().addRegistryShutdownListener(
  +                (RegistryShutdownListener) result);
  +
  +            return result;
           }
           catch (Exception ex)
           {
  @@ -206,13 +201,24 @@
           Class serviceInterface = getServicePoint().getServiceInterface();
   
           classFab.addField(SERVICE_ACCESSOR_METHOD_NAME, serviceInterface);
  +        classFab.addField("_shutdown", boolean.class);
   
           BodyBuilder builder = new BodyBuilder();
  +        builder.begin();
  +
  +        builder.addln("if (_shutdown)");
  +        builder.begin();
  +        builder.addln("_serviceModel = null;");
  +        builder.addln(
  +            "throw org.apache.commons.hivemind.HiveMind#createRegistryShutdownException();");
  +        builder.end();
   
           builder.add("return (");
           builder.add(serviceInterface.getName());
           builder.add(") _serviceModel.getServiceImplementationForCurrentThread();");
   
  +        builder.end();
  +
           classFab.addMethod(
               Modifier.PRIVATE | Modifier.FINAL,
               SERVICE_ACCESSOR_METHOD_NAME,
  @@ -220,6 +226,16 @@
               null,
               null,
               builder.toString());
  +
  +        classFab.addInterface(RegistryShutdownListener.class);
  +
  +        classFab.addMethod(
  +            Modifier.PUBLIC | Modifier.FINAL,
  +            "registryDidShutdown",
  +            Void.TYPE,
  +            null,
  +            null,
  +            "{ _shutdown = true; }");
       }
   
       /**
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ShutdownCoordinator.java
  
  Index: ShutdownCoordinator.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.impl;
  
  import java.util.Iterator;
  
  import org.apache.commons.hivemind.HiveMind;
  import org.apache.commons.hivemind.RegistryShutdownListener;
  import org.apache.commons.hivemind.util.EventListenerList;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   * Manages a list of objects that implement the
   * {@link org.apache.commons.hivemind.RegistryShutdownListener} interface.
   *
   * @author Howard Lewis Ship
   * @version $Id: ShutdownCoordinator.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public final class ShutdownCoordinator
  {
      private static final Log LOG = LogFactory.getLog(ShutdownCoordinator.class);
  
      private EventListenerList _listenerList;
  
      public synchronized void addRegistryShutdownListener(RegistryShutdownListener s)
      {
          if (_listenerList == null)
              _listenerList = new EventListenerList();
  
          _listenerList.addListener(s);
      }
  
      public synchronized void shutdown()
      {
          if (_listenerList == null)
              return;
  
          Iterator i = _listenerList.getListeners();
  
          _listenerList = null;
  
          while (i.hasNext())
          {
              RegistryShutdownListener s = (RegistryShutdownListener) i.next();
  
              shutdown(s);
          }
      }
  
      private void shutdown(RegistryShutdownListener s)
      {
          try
          {
              s.registryDidShutdown();
          }
          catch (RuntimeException ex)
          {
              LOG.error(HiveMind.format("ShutdownCoordinator.failure", s, ex.getMessage()), ex);
          }
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ConstructableServiceExtensionPoint.java
  
  Index: ConstructableServiceExtensionPoint.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.impl;
  
  import java.util.List;
  
  import org.apache.commons.hivemind.ServiceExtensionPoint;
  import org.apache.commons.hivemind.ServiceImplementationConstructor;
  
  /**
   * "Private" interface used by a {@link org.apache.commons.hivemind.ServiceModel}
   * to access non-public information about a 
   * {@link ConstructableServiceExtensionPoint}, such as
   * its instance builder and interceptors.
   *
   * @author Howard Lewis Ship
   * @version $Id: ConstructableServiceExtensionPoint.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public interface ConstructableServiceExtensionPoint extends ServiceExtensionPoint
  {
  	/**
  	 * Returns the constructor that can create the core service implementation.
  	 */
      public ServiceImplementationConstructor getServiceConstructor();
  
      /**
       * Returns a list of {@link ServiceInterceptorContribution}s, sorted
       * into ascending order. May return an empty list if there are no
       * interceptors, but won't return null.
       */
      public List getSortedInterceptors();
  
      /**
       * Invoked by the ServiceModel when constuction information
       * (the builder and interceptors) is no longer needed.
       */
      public void clearConstructorInformation();
      
      /**
       * Returns the {@link ShutdownCooordinator}, used by
       * the service model to inform proxies that the service
       * has shutdown.
       */
      
      public ShutdownCoordinator getShutdownCoordinator();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ElementsInnerProxyList.java
  
  Index: ElementsInnerProxyList.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.impl;
  
  import java.util.AbstractList;
  import java.util.List;
  
  /**
   * Implements a {@link java.util.List} as a proxy to an actual list of
   * elements, provided by an extension point. The proxy is unmodifiable
   * and will work with the extension point to generate the real list
   * of elements in a just-in-time manner.
   *
   * @author Howard Lewis Ship
   * @version $Id: ElementsInnerProxyList.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public final class ElementsInnerProxyList extends AbstractList
  {
      private List _inner;
      private ConfigurationPointImpl _point;
      private ElementsProxyList _outer;
  
      ElementsInnerProxyList(ConfigurationPointImpl point, ElementsProxyList outer)
      {
          _point = point;
          _outer = outer;
  
          _outer.setInner(this);
      }
  
      private synchronized List inner()
      {
          if (_inner == null)
          {
              _inner = _point.constructElements();
  
              // Replace ourselves in the outer proxy with the actual list.
              _outer.setInner(_inner);
          }
  
          return _inner;
      }
  
      public Object get(int index)
      {
          return inner().get(index);
      }
  
      public int size()
      {
          return inner().size();
      }
  
      public boolean equals(Object o)
      {
          if (this == o)
              return true;
  
          if (o == null)
              return false;
  
          return inner().equals(o);
      }
  
      public String toString()
      {
          if (_inner != null)
              return _inner.toString();
  
          return "<Element List Proxy for " + _point.getExtensionPointId() + ">";
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ContributionImpl.java
  
  Index: ContributionImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.impl;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  import org.apache.commons.hivemind.Contribution;
  import org.apache.commons.hivemind.Module;
  
  /**
   * Implements the {@link org.apache.commons.hivemind.Contribution} interface,
   * a wrapper around objects that can provide values that plug into an
   * extension point.
   *
   * @author Howard Lewis Ship
   * @version $Id: ContributionImpl.java,v 1.1 2003/10/01 20:43:21 hlship Exp $
   */
  public final class ContributionImpl implements Contribution
  {
      private Module _contributingModule;
      private List _elements;
  
      public Module getContributingModule()
      {
          return _contributingModule;
      }
  
      public void setContributingModule(Module module)
      {
          _contributingModule = module;
      }
  
      public void addElements(List elements)
      {
          if (_elements == null)
              _elements = new ArrayList(elements);
          else
              _elements.addAll(elements);
      }
  
      public List getElements()
      {
          if (_elements == null)
              return Collections.EMPTY_LIST;
  
          return _elements;
      }
  }
  
  
  
  1.3       +15 -8     jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/Module.java
  
  Index: Module.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/Module.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Module.java	18 Sep 2003 19:00:59 -0000	1.2
  +++ Module.java	1 Oct 2003 20:43:23 -0000	1.3
  @@ -59,7 +59,6 @@
   
   import java.util.List;
   
  -
   /**
    * The definition of a HiveMind Module.  A Module is
    * a container of service extension points and
  @@ -76,12 +75,11 @@
        */
       public String getModuleId();
   
  -   
  -   	/**
  -   	 * Looks up
  -   	 * the {@link ServiceExtensionPoint} (throwing an exception if not found)
  -   	 * and invokes {@link ServiceExtensionPoint#getService(Class)}.
  -   	 */
  +    /**
  +     * Looks up
  +     * the {@link ServiceExtensionPoint} (throwing an exception if not found)
  +     * and invokes {@link ServiceExtensionPoint#getService(Class)}.
  +     */
       public Object getService(String serviceId, Class serviceInterface);
   
       /**
  @@ -108,6 +106,15 @@
        * 
        */
       public List getConfiguration(String configurationPointId);
  +
  +    /**
  +     * Returns the identified configuration  point.
  +     * 
  +     * @param serviceId fully qualified id of the configuration point
  +     * @throws ApplicationRuntimeException if no such configuration point exists
  +     */
  +
  +    public ConfigurationPoint getConfigurationPoint(String configurationId);
   
       /**
        * Returns the registry which contains this module.
  
  
  
  1.4       +5 -1      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/HiveMindMessages.properties
  
  Index: HiveMindMessages.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/HiveMindMessages.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- HiveMindMessages.properties	23 Sep 2003 22:23:52 -0000	1.3
  +++ HiveMindMessages.properties	1 Oct 2003 20:43:23 -0000	1.4
  @@ -9,6 +9,7 @@
   wrong-factory-parameter-count=Service implementation factory {0} expects {1,choice,0#no parameters|1#one parameter|1<{1,number,integer} parameters} but received {2,choice,0#none|1#one|1<{2,number,integer}}.
   
   HiveMind.elements-not-orderable=Elements of list {0} do not implement the Orderable interface and can not be sorted.
  +HiveMind.registry-has-shutdown=The HiveMind Registry has been shutdown.
   
   # impl package
   
  @@ -20,6 +21,7 @@
   BaseRegistry.invalid-id=''{0}'' is not a valid extension point id.
   BaseRegistry.no-such-symbol=No value available for symbol ''{0}'' (at {1}).
   
  +
   BaseModule.service-wrong-interface=Service {0} does not implement the requested interface ({1}).  The declared service interface type is {2}.
   
   ConfigurationPointImpl.unable-to-construct-configuration=Unable to construct configuration {0}: {1}
  @@ -74,6 +76,8 @@
   SchemaElement.element-errors=Element {0} (at {1}) contains errors:
   
   SchemaProcessorImpl.unknown-element=Element {0} (at {1}) is not allowed here.
  +
  +ShutdownCoordinator.failure=Unable to shutdown {0}: {1}
   
   # javassist package
   
  
  
  
  1.4       +10 -1     jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/Registry.java
  
  Index: Registry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/Registry.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Registry.java	24 Sep 2003 16:07:52 -0000	1.3
  +++ Registry.java	1 Oct 2003 20:43:23 -0000	1.4
  @@ -135,4 +135,13 @@
        */
       
       public Locale getLocale();
  +    
  +    /**
  +     * Shuts down the registry; this notifies all
  +     * {@link RegistryShutdownListener} services and objects. Once the registry
  +     * is shutdown, it is no longer valid to obtain new services or configurations, or
  +     * even use existing services and configurations.
  +     */
  +    
  +    public void shutdown();
   }
  
  
  
  1.5       +6 -1      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/HiveMind.java
  
  Index: HiveMind.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/HiveMind.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- HiveMind.java	29 Sep 2003 15:32:25 -0000	1.4
  +++ HiveMind.java	1 Oct 2003 20:43:23 -0000	1.5
  @@ -163,6 +163,11 @@
                       new Integer(parameters.size())));
       }
   
  +    public static ApplicationRuntimeException createRegistryShutdownException()
  +    {
  +        return new ApplicationRuntimeException(getMessage("HiveMind.registry-has-shutdown"));
  +    }
  +
       /**
        * Used to sort elements of a list that implement the
        * {@link Orderable} interface.
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/Contribution.java
  
  Index: Contribution.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind;
  
  import java.util.List;
  
  /**
   * An Contribution is a contribution to an {@link org.apache.commons.hivemind.ConfigurationPoint}.
   *
   * @author Howard Lewis Ship
   * @version $Id: Contribution.java,v 1.1 2003/10/01 20:43:23 hlship Exp $
   */
  public interface Contribution
  {
      /**
       * Returns the module which made this contribution.
       */
      public Module getContributingModule();
  
      /**
       * Returns a List of {@link org.apache.commons.hivemind.Element}, the representation of
       * the XML elements in the extension.  The ConfigurationPoint
       * will use its {@link org.apache.commons.hivemind.schema.Schema} (if present)
       * to convert this XML representation into the object representation
       * returned by {@link ConfigurationPoint#getElements()}.
       */
      public List getElements();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/RegistryShutdownListener.java
  
  Index: RegistryShutdownListener.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind;
  
  /**
   * Lifecycle interface that may be implemented by objects
   * that need to know when the {@link org.apache.commons.hivemind.Registry}
   * has shutdown.  Typically, this is implemented by core service implementations
   * (as well as many proxies created by HiveMind).
   * 
   * <p>
   * A core service implementation that implements this interface will
   * automatically be registered for notifications (exception: not if the service
   * uses the threaded service model).
   * 
   * <p>Using this notification is
   * preferrable to implementing a <code>finalize()</code> since it will be invoked
   * at a known time.
   * 
   * <p>
   * The order in which listeners will be invoked is
   * not well known. In the future, some form of dependency system may
   * be instituted.
   * 
   *
   * @author Howard Lewis Ship
   * @version $Id: RegistryShutdownListener.java,v 1.1 2003/10/01 20:43:23 hlship Exp $
   */
  public interface RegistryShutdownListener
  {
  	/**
  	 * Invoked when a service is being shutdown, and should release any external resources.
  	 * A service should <em>not</em> attempt to use any resources or configurations, doing
  	 * so may result in a runtime exception.
  	 */
  	public void registryDidShutdown();
  }
  
  
  
  1.3       +7 -1      jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/rules/MockModule.java
  
  Index: MockModule.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/rules/MockModule.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MockModule.java	18 Sep 2003 19:00:58 -0000	1.2
  +++ MockModule.java	1 Oct 2003 20:43:23 -0000	1.3
  @@ -60,6 +60,7 @@
   import java.util.List;
   
   import org.apache.commons.hivemind.ClassResolver;
  +import org.apache.commons.hivemind.ConfigurationPoint;
   import org.apache.commons.hivemind.Messages;
   import org.apache.commons.hivemind.Location;
   import org.apache.commons.hivemind.Module;
  @@ -115,6 +116,11 @@
       }
   
       public Location getLocation()
  +    {
  +        return null;
  +    }
  +
  +    public ConfigurationPoint getConfigurationPoint(String configurationId)
       {
           return null;
       }
  
  
  
  1.6       +3 -3      jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/parse/TestToString.java
  
  Index: TestToString.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/parse/TestToString.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestToString.java	29 Sep 2003 15:32:26 -0000	1.5
  +++ TestToString.java	1 Oct 2003 20:43:23 -0000	1.6
  @@ -65,7 +65,7 @@
   import org.apache.commons.hivemind.Module;
   import org.apache.commons.hivemind.ServiceExtensionPoint;
   import org.apache.commons.hivemind.impl.AttributeImpl;
  -import org.apache.commons.hivemind.impl.ConfigurationImpl;
  +import org.apache.commons.hivemind.impl.ContributionImpl;
   import org.apache.commons.hivemind.impl.ConfigurationPointImpl;
   import org.apache.commons.hivemind.impl.ElementImpl;
   import org.apache.commons.hivemind.impl.InterceptorStackImpl;
  @@ -144,7 +144,7 @@
           new InterceptorDescriptor().toString();
           new ModuleImpl().toString();
           new RegistryImpl(Locale.ENGLISH).toString();
  -        new ConfigurationImpl().toString();
  +        new ContributionImpl().toString();
           new ConfigurationPointImpl().toString();
           new ElementImpl().toString();
           new AttributeImpl("foo", "bar").toString();
  
  
  
  1.6       +1 -8      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java
  
  Index: DescriptorParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- DescriptorParser.java	29 Sep 2003 15:36:52 -0000	1.5
  +++ DescriptorParser.java	1 Oct 2003 20:43:23 -0000	1.6
  @@ -60,7 +60,6 @@
   import java.lang.reflect.Constructor;
   import java.net.URL;
   import java.util.ArrayList;
  -import java.util.Collections;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.List;
  @@ -585,12 +584,6 @@
   
       private void checkAttributes(Map expectedAttributes)
       {
  -        // I generally avoid change parameter values within
  -        // a method, but I'm a little lazy here.
  -
  -        if (expectedAttributes == null)
  -            expectedAttributes = Collections.EMPTY_MAP;
  -
           Iterator i = _attributes.keySet().iterator();
   
           // First, check that each attribute is in the set of expected attributes.
  
  
  
  1.4       +32 -8     jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/TestConfigurationPoint.java
  
  Index: TestConfigurationPoint.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/config/TestConfigurationPoint.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestConfigurationPoint.java	20 Sep 2003 12:48:19 -0000	1.3
  +++ TestConfigurationPoint.java	1 Oct 2003 20:43:23 -0000	1.4
  @@ -381,11 +381,11 @@
   
           List l = r.getConfiguration("hivemind.test.config.Simple");
   
  +		assertEquals("<Element List Proxy for hivemind.test.config.Simple>", l.toString());
  +		
           assertEquals(true, l.equals(l));
           assertEquals(false, l.equals(null));
   
  -        assertEquals("<Element List Proxy for hivemind.test.config.Simple>", l.toString());
  -
           assertEquals(2, l.size());
   
           List l2 = r.getConfiguration("hivemind.test.config.Simple");
  @@ -462,10 +462,13 @@
           List l = r.getConfiguration("hivemind.test.config.CustomRule");
           Module m = r.getModule("hivemind.test.config");
   
  -        assertEquals(2, l.size());
  -
           Datum d = (Datum) l.get(0);
  -
  +		
  +		// Put this check second, just to get some code coverage
  +		// on ElementsInnerProxyList 
  +		
  +		assertEquals(2, l.size());
  +		
           assertSame(m, d.getContributingModule());
       }
   
  @@ -505,9 +508,9 @@
           Resource moduleResource =
               new ClasspathResource(_resolver, "/hivemind/test/config/ResourceTranslator.xml");
   
  -		builder.processModules(_resolver);
  +        builder.processModules(_resolver);
           builder.processModule(_resolver, moduleResource);
  - 
  +
           Registry r = builder.constructRegistry(Locale.FRENCH);
   
           List l = r.getConfiguration("hivemind.test.config.ResourceTranslator");
  @@ -535,5 +538,26 @@
           assertLoggedMessagePattern(
               "Unable to localize resource DoesNotExist.xml for module hivemind.test.config "
                   + "\\(at classpath:/hivemind/test/config/ResourceTranslator.xml, .*\\)\\.");
  +    }
  +
  +    public void testShutdown() throws Exception
  +    {
  +        Registry r = buildFrameworkRegistry("Simple.xml");
  +
  +        List l = r.getConfiguration("hivemind.test.config.Simple");
  +
  +        assertEquals(2, l.size());
  +
  +        r.shutdown();
  +
  +        try
  +        {
  +            l.size();
  +        }
  +        catch (ApplicationRuntimeException ex)
  +        {
  +            assertExceptionSubstring(ex, "The HiveMind Registry has been shutdown.");
  +        }
  +
       }
   }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/util/TestShutdownCoordinator.java
  
  Index: TestShutdownCoordinator.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package hivemind.test.util;
  
  import org.apache.commons.hivemind.ApplicationRuntimeException;
  import org.apache.commons.hivemind.RegistryShutdownListener;
  import org.apache.commons.hivemind.impl.ShutdownCoordinator;
  
  import hivemind.test.FrameworkTestCase;
  
  /**
   * Tests the {@link org.apache.commons.hivemind.impl.ShutdownCoordinator}.
   *
   * @author Howard Lewis Ship
   * @version $Id: TestShutdownCoordinator.java,v 1.1 2003/10/01 20:43:23 hlship Exp $
   */
  public class TestShutdownCoordinator extends FrameworkTestCase
  {
      private static class Fixture implements RegistryShutdownListener
      {
          private boolean _shutdown;
  
          public boolean isShutdown()
          {
              return _shutdown;
          }
  
          public void registryDidShutdown()
          {
              _shutdown = true;
          }
  
      }
      public TestShutdownCoordinator(String name)
      {
          super(name);
      }
  
      public void testShutdownCoordinator()
      {
          ShutdownCoordinator c = new ShutdownCoordinator();
  
          Fixture f = new Fixture();
  
          c.addRegistryShutdownListener(f);
  
          c.shutdown();
  
          assertEquals(true, f.isShutdown());
  
          // For good riddens; test no failure if already down.
  
          c.shutdown();
      }
  
      public void testShutdownFailure() throws Exception
      {
          ShutdownCoordinator c = new ShutdownCoordinator();
  
          c.addRegistryShutdownListener(new RegistryShutdownListener()
          {
              public void registryDidShutdown()
              {
                  throw new ApplicationRuntimeException("I'm just not in the mood.");
              }
          });
  
          interceptLogging();
  
          c.shutdown();
  
          assertLoggedMessagePattern("Unable to shutdown .*: I'm just not in the mood\\.");
  
      }
  
  }
  
  
  
  1.7       +3 -3      jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/TestMisc.java
  
  Index: TestMisc.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/test/hivemind/test/TestMisc.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- TestMisc.java	29 Sep 2003 15:32:26 -0000	1.6
  +++ TestMisc.java	1 Oct 2003 20:43:23 -0000	1.7
  @@ -69,7 +69,7 @@
   import org.apache.commons.hivemind.Module;
   import org.apache.commons.hivemind.ServiceExtensionPoint;
   import org.apache.commons.hivemind.SymbolSource;
  -import org.apache.commons.hivemind.impl.ConfigurationImpl;
  +import org.apache.commons.hivemind.impl.ContributionImpl;
   import org.apache.commons.hivemind.impl.CreateClassServiceConstructor;
   import org.apache.commons.hivemind.impl.InvokeFactoryServiceConstructor;
   import org.apache.commons.hivemind.impl.ModuleImpl;
  @@ -164,7 +164,7 @@
   
       public void testExtensionImplGetElementsEmpty()
       {
  -        ConfigurationImpl e = new ConfigurationImpl();
  +        ContributionImpl e = new ContributionImpl();
   
           assertSame(Collections.EMPTY_LIST, e.getElements());
       }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org