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/09/29 17:32:26 UTC

cvs commit: jakarta-commons-sandbox/hivemind/framework/xdocs SymbolSource.xml

hlship      2003/09/29 08:32:26

  Modified:    hivemind/xdocs index.xml ioc.xml
               hivemind/framework/src/java/org/apache/commons/hivemind
                        HiveMind.java
               hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        RegistryBuilder.java
               hivemind/framework/src/java/org/apache/commons/hivemind/parse
                        ServicePointDescriptor.java DescriptorParser.java
               hivemind/framework/src/test/hivemind/test TestMisc.java
               hivemind/framework/src/test/hivemind/test/parse
                        TestToString.java
               hivemind/framework/xdocs SymbolSource.xml
  Added:       hivemind/framework/src/java/org/apache/commons/hivemind
                        ServiceModel.java
                        ConstructableServiceExtensionPoint.java
               hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        AbstractServiceModelImpl.java
                        DeferredServiceModel.java
                        ServiceExtensionPointImpl.java
                        ServiceModelType.java SingletonServiceModel.java
                        ThreadedServiceModel.java
  Removed:     hivemind/framework/src/java/org/apache/commons/hivemind/impl
                        DeferredServiceExtensionPointImpl.java
                        SingletonServiceExtensionPointImpl.java
                        ServiceModel.java
                        AbstractServiceExtensionPoint.java
                        ThreadedServiceExtensionPointImpl.java
  Log:
  Refactor the service extension point implementations into a single ServiceExtensionPointImpl and multiple implementations of the new ServiceModel interface.
  
  Revision  Changes    Path
  1.16      +10 -12    jakarta-commons-sandbox/hivemind/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/index.xml,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- index.xml	24 Sep 2003 16:07:52 -0000	1.15
  +++ index.xml	29 Sep 2003 15:32:25 -0000	1.16
  @@ -56,8 +56,7 @@
     	
     	
     	<p>
  -  	HiveMind does a limited amount (reading descriptors, instantiating services and managing singletons) but
  -  	does it well.  HiveMind is exhaustively tested and focused entirely on developer productivity.
  +  	HiveMind is exhaustively tested and focused entirely on developer productivity.
     	HiveMind uses <em>line precise error reporting</em>: this means that when errors occur,
     	even runtime errors long after module deployment descriptors have been parsed, HiveMind will report the 
     	exact location of the source of an error (simply put, each runtime object is "tagged" with
  @@ -98,11 +97,11 @@
       <section name="Services and Extension Points">
       	
       	<p>
  -    	HiveMind is a centralized registry of services and extension points.
  +    	HiveMind is a centralized registry of services and configuration points.
       	</p>
       	
       	<p>
  -    	Services are represented as an Java interface accessible
  +    	Services are represented as a Java interface accessible
       	within a <em>registry</em> using
       	a unique id.  Services are usually singletons, though
       	other service models are available.
  @@ -112,7 +111,7 @@
       	Configuration points are used for configuration information. Each configuration point is a list of elements, 
       	also accessible
       	using a unique id.	The elements of an configuration point
  -    	are provided by configurations
  +    	are provided by contributions
       	that appear in many modules, which is the basis for
       	allowing multiple modules to work together to form
       	the application.
  @@ -120,15 +119,15 @@
       	
       	<p>
       	Frequently, services and configuration points are used together; modules contribute to a configuration
  -    	point and a related services makes use of the data contributed from many modules.
  +    	point and a related service makes use of the data.
       	</p>
       	
       </section>
       
       <section name="Modules">
       <p>
  -    HiveMind doesn't have any particular purpose; it isn't an application, it's more
  -    of an environment for supporting an application.  	
  +    HiveMind doesn't have any particular purpose; it isn't an application, it's 
  +    an environment for supporting an application.  	
       </p>
       	
       	
  @@ -150,8 +149,7 @@
       <p>
       Each module has a 
       <a href="descriptor.html">HiveMind deployment descriptor</a>, <code>hivemodule.xml</code>.  This
  -    defines the services and configurations defined by the module, its contributions,
  -    and its dependencies on other modules.
  +    defines the services and configurations defined by the module and its contributions to other modules.
       </p>
       	
       </section>
  @@ -238,7 +236,7 @@
       the application.
       </p>
       
  -    <p>The <a href="sample-registry/index.html">HiveMind module descriptor documentation</a>
  +    <p>The <a href="commons-hivemind/sample-registry/index.html">HiveMind module descriptor documentation</a>
       gives a general idea of what the documentation looks like, using a hypothetical
       collection of module descriptors.
       </p>
  
  
  
  1.13      +2 -2      jakarta-commons-sandbox/hivemind/xdocs/ioc.xml
  
  Index: ioc.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/ioc.xml,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ioc.xml	24 Sep 2003 16:07:52 -0000	1.12
  +++ ioc.xml	29 Sep 2003 15:32:25 -0000	1.13
  @@ -35,7 +35,7 @@
   all the modules it can find at runtime. HiveMind is responsible for creating services (including core implementations
   and interceptors).  It is quite possible to create service factories that do very container-like things,
   including connecting services together.  
  -<a href="common-hivemind/BuilderFactory.html">BuilderFactory</a>	
  +<a href="commons-hivemind/BuilderFactory.html">BuilderFactory</a>	
   does just that, instantiating an object to act as the core service implementation, then setting
   properties of the object, some of which are references to services and  configuration point element data.
   </p>
  
  
  
  1.4       +2 -2      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.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- HiveMind.java	18 Sep 2003 20:08:59 -0000	1.3
  +++ HiveMind.java	29 Sep 2003 15:32:25 -0000	1.4
  @@ -188,7 +188,7 @@
        */
       public static List sortOrderables(List list)
       {
  -        if (list.isEmpty())
  +        if (list == null || list.isEmpty())
               return Collections.EMPTY_LIST;
   
           List sorted = new ArrayList(list);
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/ServiceModel.java
  
  Index: ServiceModel.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;
  
  /**
   * A service model is associated with a {@link org.apache.commons.hivemind.ServiceExtensionPoint}
   * to supply rules for the lifecycle of the service. This concerns when the service is
   * first created and whether it is pooled, etc. Each service extension point
   * will have a unique instance of ServiceModel.
   *
   * @author Howard Lewis Ship
   * @version $Id: ServiceModel.java,v 1.1 2003/09/29 15:32:25 hlship Exp $
   */
  public interface ServiceModel
  {
      /**
       * Invoked by the service to obtain the service implementation. The model
       * may return the actual service implementation or some form of proxy.
       */
  
      public Object getServiceImplementation();
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/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;
  
  import java.util.List;
  
  /**
   * "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/09/29 15:32:25 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();
  }
  
  
  
  1.6       +22 -20    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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- RegistryBuilder.java	24 Sep 2003 16:07:52 -0000	1.5
  +++ RegistryBuilder.java	29 Sep 2003 15:32:25 -0000	1.6
  @@ -75,6 +75,7 @@
   import org.apache.commons.hivemind.Occurances;
   import org.apache.commons.hivemind.Registry;
   import org.apache.commons.hivemind.Resource;
  +import org.apache.commons.hivemind.ServiceModel;
   import org.apache.commons.hivemind.parse.ConfigurationPointDescriptor;
   import org.apache.commons.hivemind.parse.ContributionDescriptor;
   import org.apache.commons.hivemind.parse.DescriptorParser;
  @@ -132,7 +133,7 @@
       private Map _modules = new HashMap();
   
       /**
  -     * Map of {@link SingletonServiceExtensionPointImpl} (or subclass) keyed on fully qualified id.
  +     * Map of {@link SingletonServiceModel} (or subclass) keyed on fully qualified id.
        */
   
       private Map _servicePoints = new HashMap();
  @@ -326,17 +327,7 @@
               // whether the service is create-on-first-reference
               // or create-on-first-use (deferred).
   
  -            AbstractServiceExtensionPoint point = null;
  -
  -            ServiceModel model = sd.getModel();
  -
  -            if (model == ServiceModel.DEFERRED)
  -                point = new DeferredServiceExtensionPointImpl();
  -            else
  -                if (model == ServiceModel.THREADED)
  -                    point = new ThreadedServiceExtensionPointImpl();
  -                else
  -                    point = new SingletonServiceExtensionPointImpl();
  +            ServiceExtensionPointImpl point = new ServiceExtensionPointImpl();
   
               point.setExtensionPointId(pointId);
               point.setLocation(sd.getLocation());
  @@ -345,12 +336,25 @@
               point.setServiceInterfaceName(sd.getInterfaceClassName());
               point.setParametersSchema(sd.getParametersSchema());
   
  -            module.addServicePoint(point);
  +             ServiceModelType modelType = sd.getModel();
  +            ServiceModel model = null;
  +
  +            if (modelType == ServiceModelType.DEFERRED)
  +                model = new DeferredServiceModel(point);
  +            else
  +                if (modelType == ServiceModelType.THREADED)
  +                    model = new ThreadedServiceModel(point);
  +                else
  +                    model = new SingletonServiceModel(point);
  +
  +            point.setServiceModel(model);
  +
  +			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);
           }
  @@ -592,8 +596,7 @@
           if (LOG.isDebugEnabled())
               LOG.debug("Adding " + builder + " to service extension point " + pointId);
   
  -        AbstractServiceExtensionPoint sep =
  -            (AbstractServiceExtensionPoint) _servicePoints.get(pointId);
  +        ServiceExtensionPointImpl sep = (ServiceExtensionPointImpl) _servicePoints.get(pointId);
   
           if (sep == null)
           {
  @@ -625,8 +628,7 @@
           if (LOG.isDebugEnabled())
               LOG.debug("Adding " + id + " to service extension point " + pointId);
   
  -        AbstractServiceExtensionPoint sep =
  -            (AbstractServiceExtensionPoint) _servicePoints.get(pointId);
  +        ServiceExtensionPointImpl sep = (ServiceExtensionPointImpl) _servicePoints.get(pointId);
   
           if (sep == null)
           {
  @@ -661,7 +663,7 @@
           Iterator i = _servicePoints.values().iterator();
           while (i.hasNext())
           {
  -            AbstractServiceExtensionPoint point = (AbstractServiceExtensionPoint) i.next();
  +            ServiceExtensionPointImpl point = (ServiceExtensionPointImpl) i.next();
   
               if (point.getServiceConstructor() != null)
                   continue;
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/AbstractServiceModelImpl.java
  
  Index: AbstractServiceModelImpl.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.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;
  import org.apache.commons.hivemind.ServiceInterceptorContribution;
  import org.apache.commons.hivemind.ServiceModel;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  public abstract class AbstractServiceModelImpl implements ServiceModel
  {
      private static final Log LOG = LogFactory.getLog(AbstractServiceModelImpl.class);
  
      private ConstructableServiceExtensionPoint _servicePoint;
  
      public AbstractServiceModelImpl(ConstructableServiceExtensionPoint servicePoint)
      {
          _servicePoint = servicePoint;
      }
  
      private boolean _building;
  
      /**
       * Checks the building flag, throwing an exception
       * if true; this is used to detect unresolvable build cycles (which are
       * now very rare, since most services use deferred service model).
       */
      protected void checkBuilding()
      {
          if (_building)
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ServiceExtensionPoint.recursive-service-build",
                      _servicePoint.getExtensionPointId()));
      }
  
      protected Object addInterceptors(Object core)
      {
          List interceptors = _servicePoint.getSortedInterceptors();
  
          int count = interceptors.size();
  
          if (count == 0)
              return core;
  
          InterceptorStackImpl stack = new InterceptorStackImpl(_servicePoint, core);
  
          for (int i = 0; i < count; i++)
          {
              ServiceInterceptorContribution ic =
                  (ServiceInterceptorContribution) interceptors.get(i);
  
              stack.process(ic);
          }
  
          // Whatever's on top is the final service.
  
          return stack.peek();
      }
  
      protected void setBuilding(boolean building)
      {
          _building = building;
      }
  
      /**
         * Constructs the core service implementation (by invoking the
         * {@link ServiceImplementationConstructor}), and checks
         * that the result is non-null and assignable
         * to the service interface.
         */
      protected Object constructCoreServiceImplementation()
      {
          Class serviceType = _servicePoint.getServiceInterface();
          ServiceImplementationConstructor constructor = _servicePoint.getServiceConstructor();
          Object result = constructor.constructCoreServiceImplementation();
  
          if (result == null)
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ServiceExtensionPoint.factory-returned-null",
                      _servicePoint.getExtensionPointId()),
                  constructor.getLocation(),
                  null);
  
          if (!serviceType.isAssignableFrom(result.getClass()))
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ServiceExtensionPoint.factory-wrong-interface",
                      _servicePoint.getExtensionPointId(),
                      result,
                      serviceType.getName()),
                  constructor.getLocation(),
                  null);
  
          return result;
      }
  
      /**
       * Invoked after the service has been constructed to utilize
       * the {@link Initializable} call back interface, if the
       * core implementation implements it.
       */
      protected void initializeCoreServiceImplementation(Object core, Object intercepted)
      {
          if (core instanceof Initializable)
          {
              Initializable initializeCore = (Initializable) core;
              initializeCore.initializeService(intercepted);
          }
      }
  
      /**
       * Constructs the service implementation; this is invoked
       * from {@link #getService(Class)} and from the generated 
       * deferrable proxy.  Primarily, invokes
       * {@link #constructNewServiceImplementation()} from
       * within a block that checks for recursive builds.
       */
  
      protected Object constructServiceImplementation()
      {
          checkBuilding();
  
          Object result = null;
  
          try
          {
              setBuilding(true);
  
              result = constructNewServiceImplementation();
  
              // After succesfully building, we don't need 
              // some of the definition stuff again.
  
              _servicePoint.clearConstructorInformation();
          }
          finally
          {
              setBuilding(false);
          }
  
          return result;
      }
  
      /**
       * Constructs a new implementation of the service, starting with
       * a core implementation, then adding any interceptors.
       */
      protected Object constructNewServiceImplementation()
      {
          try
          {
              if (LOG.isDebugEnabled())
                  LOG.debug(
                      "Constructing core instance for service "
                          + _servicePoint.getExtensionPointId());
  
              Object core = constructCoreServiceImplementation();
  
              Object intercepted = addInterceptors(core);
  
              initializeCoreServiceImplementation(core, intercepted);
  
              return intercepted;
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ServiceExtensionPoint.unable-to-construct-service",
                      _servicePoint.getExtensionPointId(),
                      ex.getMessage()),
                  ex);
          }
  
      }
  
      public ConstructableServiceExtensionPoint getServicePoint()
      {
          return _servicePoint;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/DeferredServiceModel.java
  
  Index: DeferredServiceModel.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.lang.reflect.Constructor;
  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.service.BodyBuilder;
  import org.apache.commons.hivemind.service.ClassFab;
  
  /**
   * Subclass of {@link org.apache.commons.hivemind.impl.SingletonServiceModel}
   * which supports creation of a deferred service proxy (deferring the actual
   * construction of the service until absolutely necessary).
   *
   * @author Howard Lewis Ship
   * @version $Id: DeferredServiceModel.java,v 1.1 2003/09/29 15:32:25 hlship Exp $
   */
  public class DeferredServiceModel extends AbstractServiceModelImpl
  {
      /**
       * Name of a method in the deferred proxy that is used to obtain
       * the constructed service.
       */
      protected static final String SERVICE_ACCESSOR_METHOD_NAME = "_service";
  
      private Object _serviceProxy;
      private Object _constructedService;
  
      public DeferredServiceModel(ConstructableServiceExtensionPoint servicePoint)
      {
          super(servicePoint);
      }
  
      public synchronized Object getServiceImplementation()
      {
          if (_constructedService != null)
              return _constructedService;
  
          return getServiceProxy();
      }
  
      /**
       * This is invoked by the proxy to create the actual implementation.
       */
      public synchronized Object getActualServiceImplementation()
      {
          if (_constructedService == null)
              _constructedService = constructServiceImplementation();
  
          return _constructedService;
      }
  
      /**
       * Returns the proxy, creating it if necessary.
       * 
       */
  
      protected Object getServiceProxy()
      {
          if (_serviceProxy == null)
              _serviceProxy = createDeferredProxy();
  
          return _serviceProxy;
      }
  
      /**
       * Creates a proxy class for the service and then constructs the class itself.
       */
      private Object createDeferredProxy()
      {
          checkBuilding();
  
          try
          {
              setBuilding(true);
  
              // Create the outer proxy, the one visible to client code (including
              // other services).  It is dependent on an inner proxy.
  
              Class proxyClass = createDeferredProxyClass();
  
              // Create the inner proxy, whose job is to replace itself
              // when the first service method is invoked.
  
              Class innerProxyClass = createInnerProxyClass(proxyClass);
  
              // Create the outer proxy.
  
              Object result = proxyClass.newInstance();
  
              // The inner proxy's construct invokes a method on the
              // outer proxy to connect the two.
  
              Constructor c = innerProxyClass.getConstructor(new Class[] { proxyClass, getClass()});
  
              c.newInstance(new Object[] { result, this });
  
              return result;
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(ex);
          }
          finally
          {
              setBuilding(false);
          }
  
      }
  
      /**
       * Creates a class that implements the service interface. Implements
       * a private synchronized method, _service(), that constructs the service
       * as needed, and has each service interface method re-invoke on _service().
       * Adds a toString() method if the service interface does not define toString().
       */
      private Class createDeferredProxyClass()
      {
          ConstructableServiceExtensionPoint servicePoint = getServicePoint();
  
          ProxyBuilder builder = new ProxyBuilder("DeferredProxy", servicePoint);
  
          ClassFab classFab = builder.getClassFab();
  
          Class serviceInterface = servicePoint.getServiceInterface();
  
          // This will initally be the inner proxy, then switch over to the
          // service implementation.
  
          classFab.addField("_inner", serviceInterface);
  
          classFab.addMethod(
              Modifier.PUBLIC | Modifier.SYNCHRONIZED | Modifier.FINAL,
              "_setInner",
              Void.TYPE,
              new Class[] { serviceInterface },
              null,
              "{ _inner = $1; }");
  
          builder.addServiceMethods("_inner");
  
          return classFab.createClass();
      }
  
      private Class createInnerProxyClass(Class deferredProxyClass)
      {
          ServiceExtensionPoint servicePoint = getServicePoint();
  
          Class serviceInterface = servicePoint.getServiceInterface();
          ProxyBuilder builder = new ProxyBuilder("InnerProxy", servicePoint);
  
          ClassFab classFab = builder.getClassFab();
  
          classFab.addField("_deferredProxy", deferredProxyClass);
          classFab.addField("_service", serviceInterface);
          classFab.addField("_serviceModel", getClass());
  
          BodyBuilder body = new BodyBuilder();
  
          // The constructor remembers the outer proxy and registers itself
          // with the outer proxy.
  
          body.begin();
          body.addln("super();");
          body.addln("_deferredProxy = $1;");
          body.addln("_serviceModel = $2;");
          body.addln("_deferredProxy._setInner(this);");
          body.end();
  
          classFab.addConstructor(
              new Class[] { deferredProxyClass, getClass()},
              null,
              body.toString());
  
          // Method _service() will look up the service implementation,
          // then update the deferred proxy to go directly to the
          // service implementation, bypassing itself!
  
          body.clear();
          body.begin();
          body.add("if (_service == null)");
          body.begin();
          body.add("_service = (");
          body.add(serviceInterface.getName());
          body.addln(") _serviceModel.getActualServiceImplementation();");
  
          body.add("_deferredProxy._setInner(_service);");
          body.end();
  
          body.add("return _service;");
          body.end();
  
          classFab.addMethod(
              Modifier.PRIVATE | Modifier.FINAL | Modifier.SYNCHRONIZED,
              "_service",
              serviceInterface,
              null,
              null,
              body.toString());
  
          builder.addServiceMethods("_service()");
  
          return classFab.createClass();
      }
  
  }
  
  
  
  1.3       +58 -155   jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ServiceExtensionPointImpl.java
  
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ServiceModelType.java
  
  Index: ServiceModelType.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 org.apache.commons.lang.enum.Enum;
  
  /**
   * Defines the models under which service may operate.
   *
   * @author Howard Lewis Ship
   * @version $Id: ServiceModelType.java,v 1.1 2003/09/29 15:32:25 hlship Exp $
   */
  public final class ServiceModelType extends Enum
  {
      /**
       * Basic model; service is a singleton and is created when first referenced.
       */
      public static final ServiceModelType SINGLETON = new ServiceModelType("SINGLETON");
  
      /**
       * Default model; creation of service is deferred until a service method is invoked.
       * Requires a proxy that takes the place of the service (until the service
       * is actually constructed).
       */
      public static final ServiceModelType DEFERRED = new ServiceModelType("DEFERRED");
  
      /**
       * More powerful model; when a thread first invokes a service method, an
       * instance of the service is constructed and bound to the thread. Requires a proxy
       * to take the place of the service (and redirect method invocations
       * to the thread-local service).  The service stays bound
       * until {@link org.apache.commons.hivemind.service.ThreadEventNotifier#fireThreadCleanup()},
       * at which point it is discarded.
       */
      public static final ServiceModelType THREADED = new ServiceModelType("THREADED");
  
      private ServiceModelType(String name)
      {
          super(name);
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/SingletonServiceModel.java
  
  Index: SingletonServiceModel.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 org.apache.commons.hivemind.ConstructableServiceExtensionPoint;
  
  /**
   * Implementation of {@link org.apache.commons.hivemind.ServiceExtensionPoint}.
   *
   * @author Howard Lewis Ship
   * @version $Id: SingletonServiceModel.java,v 1.1 2003/09/29 15:32:25 hlship Exp $
   */
  public class SingletonServiceModel extends AbstractServiceModelImpl
  {
      private Object _constructedService;
  
      public SingletonServiceModel(ConstructableServiceExtensionPoint servicePoint)
      {
          super(servicePoint);
      }
  
      /**
       * Constructs the service (the first time this is invoked)
       * and returns it.
       */
      public synchronized Object getServiceImplementation()
      {
          if (_constructedService == null)
              _constructedService = constructServiceImplementation();
  
          return _constructedService;
      }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/impl/ThreadedServiceModel.java
  
  Index: ThreadedServiceModel.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.lang.reflect.Constructor;
  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.service.BodyBuilder;
  import org.apache.commons.hivemind.service.ClassFab;
  import org.apache.commons.hivemind.service.ThreadCleanupListener;
  import org.apache.commons.hivemind.service.ThreadEventNotifier;
  
  /**
   * Like
   * {@link org.apache.commons.hivemind.impl.DeferredServiceModel}, 
   * this method returns a proxy (implementing the service interface); unlike
   * DeferredServiceModel, it <em>always</em> returns the proxy.
   * Invoking a service method on the proxy binds constructs a service implementation
   * and binds it to the current thread. 
   *
   * @author Howard Lewis Ship
   * @version $Id: ThreadedServiceModel.java,v 1.1 2003/09/29 15:32:25 hlship Exp $
   */
  public class ThreadedServiceModel extends AbstractServiceModelImpl
  {
      /**
       * Name of a method in the deferred proxy that is used to obtain
       * the constructed service.
       */
      protected static final String SERVICE_ACCESSOR_METHOD_NAME = "_service";
  
      private Object _constructedService;
      private Object _serviceProxy;
      private ThreadEventNotifier _notifier;
  
      public ThreadedServiceModel(ConstructableServiceExtensionPoint servicePoint)
      {
          super(servicePoint);
      }
  
      class CleanupListener implements ThreadCleanupListener
      {
          public void threadDidCleanup()
          {
              _notifier.removeThreadCleanupListener(this);
  
              discardActiveService();
          }
      }
  
      /**
       * Used to store the active service for the current thread.
       */
      private ThreadLocal _activeService;
  
      /**
       * Always returns {@link ThreadedServiceExtensionPointImpl#getServiceProxy() the service proxy}.
       */
      public synchronized Object getServiceImplementation()
      {
          return getServiceProxy();
      }
  
      /**
       * Returns the proxy, creating it if necessary.
       * 
       */
  
      protected Object getServiceProxy()
      {
          if (_serviceProxy == null)
              _serviceProxy = createServiceProxy();
  
          return _serviceProxy;
      }
  
      /**
       * Creates a proxy class for the service and then constructs the class itself.
       */
      private Object createServiceProxy()
      {
          checkBuilding();
  
          try
          {
              setBuilding(true);
  
              Class proxyClass = createDeferredProxyClass();
  
              Constructor c = proxyClass.getConstructor(new Class[] { getClass()});
  
              return c.newInstance(new Object[] { this });
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(ex);
          }
          finally
          {
              setBuilding(false);
          }
  
      }
  
      /**
       * Creates a class that implements the service interface. Implements
       * a private synchronized method, _service(), that constructs the service
       * as needed, and has each service interface method re-invoke on _service().
       * Adds a toString() method if the service interface does not define toString().
       */
      private Class createDeferredProxyClass()
      {
          ProxyBuilder builder = new ProxyBuilder("ThreadedProxy", getServicePoint());
  
          ClassFab classFab = builder.getClassFab();
  
          addConstructor(classFab);
  
          addServiceAccessor(classFab);
  
          builder.addServiceMethods(SERVICE_ACCESSOR_METHOD_NAME + "()");
  
          return classFab.createClass();
      }
  
      /**
       * Adds a field, _serviceExtensionPoint, whose type
       * matches this class, and a constructor which sets
       * the field.
       */
      protected void addConstructor(ClassFab classFab)
      {
          classFab.addField("_serviceModel", getClass());
  
          classFab.addConstructor(
              new Class[] { getClass()},
              null,
              "{ super(); _serviceModel = $1; }");
      }
  
      /**
       * We
       * construct a method that always goes through this service model's
       * {@link #getServiceImplementationForCurrentThread())} method.
       */
      protected void addServiceAccessor(ClassFab classFab)
      {
          Class serviceInterface = getServicePoint().getServiceInterface();
  
          classFab.addField(SERVICE_ACCESSOR_METHOD_NAME, serviceInterface);
  
          BodyBuilder builder = new BodyBuilder();
  
          builder.add("return (");
          builder.add(serviceInterface.getName());
          builder.add(") _serviceModel.getServiceImplementationForCurrentThread();");
  
          classFab.addMethod(
              Modifier.PRIVATE | Modifier.FINAL,
              SERVICE_ACCESSOR_METHOD_NAME,
              serviceInterface,
              null,
              null,
              builder.toString());
      }
  
      /**
       * Invoked by the proxy to return 
       * the active service impl for this thread,
       * constructing it as necessary.
       */
      public synchronized Object getServiceImplementationForCurrentThread()
      {
          if (_activeService == null)
              _activeService = new ThreadLocal();
  
          Object result = _activeService.get();
  
          if (result == null)
              result = constructServiceForCurrentThread();
  
          return result;
      }
  
      private Object constructServiceForCurrentThread()
      {
          // Note: don't call constructServiceImplementation since that discards the
          // service instance constructor and interceptor contributions; we need
          // to be able to build new instances of the service again and again.
  
          Object result = constructNewServiceImplementation();
  
          if (_notifier == null)
          {
              Registry registry = getServicePoint().getModule().getRegistry();
              _notifier =
                  (ThreadEventNotifier) registry.getService(
                      "hivemind.ThreadEventNotifier",
                      ThreadEventNotifier.class);
          }
  
          _notifier.addThreadCleanupListener(new CleanupListener());
          _activeService.set(result);
  
          return result;
      }
  
      private void discardActiveService()
      {
          _activeService.set(null);
      }
  
  }
  
  
  
  1.2       +5 -5      jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/parse/ServicePointDescriptor.java
  
  Index: ServicePointDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/src/java/org/apache/commons/hivemind/parse/ServicePointDescriptor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ServicePointDescriptor.java	18 Sep 2003 19:01:00 -0000	1.1
  +++ ServicePointDescriptor.java	29 Sep 2003 15:32:26 -0000	1.2
  @@ -57,7 +57,7 @@
   
   package org.apache.commons.hivemind.parse;
   
  -import org.apache.commons.hivemind.impl.ServiceModel;
  +import org.apache.commons.hivemind.impl.ServiceModelType;
   import org.apache.commons.hivemind.schema.Schema;
   import org.apache.commons.lang.builder.ToStringBuilder;
   
  @@ -73,7 +73,7 @@
       private String _id;
       private String _interfaceClassName;
       private Schema _parametersSchema;
  -    private ServiceModel _model = ServiceModel.DEFERRED;
  +    private ServiceModelType _model = ServiceModelType.DEFERRED;
   
       public String getId()
       {
  @@ -113,12 +113,12 @@
           _parametersSchema = schema;
       }
   
  -    public ServiceModel getModel()
  +    public ServiceModelType getModel()
       {
           return _model;
       }
   
  -    public void setModel(ServiceModel model)
  +    public void setModel(ServiceModelType model)
       {
           _model = model;
       }
  
  
  
  1.4       +6 -6      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.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DescriptorParser.java	23 Sep 2003 22:23:52 -0000	1.3
  +++ DescriptorParser.java	29 Sep 2003 15:32:26 -0000	1.4
  @@ -82,7 +82,7 @@
   import org.apache.commons.hivemind.impl.AttributeImpl;
   import org.apache.commons.hivemind.impl.ElementImpl;
   import org.apache.commons.hivemind.impl.LocationImpl;
  -import org.apache.commons.hivemind.impl.ServiceModel;
  +import org.apache.commons.hivemind.impl.ServiceModelType;
   import org.apache.commons.hivemind.schema.ElementModel;
   import org.apache.commons.hivemind.schema.Rule;
   import org.apache.commons.hivemind.schema.Translator;
  @@ -324,9 +324,9 @@
       private final Map MODEL_MAP = new HashMap();
   
       {
  -        MODEL_MAP.put("singleton", ServiceModel.SINGLETON);
  -        MODEL_MAP.put("deferred", ServiceModel.DEFERRED);
  -        MODEL_MAP.put("threaded", ServiceModel.THREADED);
  +        MODEL_MAP.put("singleton", ServiceModelType.SINGLETON);
  +        MODEL_MAP.put("deferred", ServiceModelType.DEFERRED);
  +        MODEL_MAP.put("threaded", ServiceModelType.THREADED);
       }
   
       /**
  @@ -911,7 +911,7 @@
               spd.setId(getAttribute("id"));
               spd.setInterfaceClassName(getAttribute("interface"));
   
  -            ServiceModel model = (ServiceModel) getEnumAttribute("model", MODEL_MAP);
  +            ServiceModelType model = (ServiceModelType) getEnumAttribute("model", MODEL_MAP);
   
               if (model != null)
                   spd.setModel(model);
  
  
  
  1.6       +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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- TestMisc.java	22 Sep 2003 20:06:00 -0000	1.5
  +++ TestMisc.java	29 Sep 2003 15:32:26 -0000	1.6
  @@ -73,7 +73,7 @@
   import org.apache.commons.hivemind.impl.CreateClassServiceConstructor;
   import org.apache.commons.hivemind.impl.InvokeFactoryServiceConstructor;
   import org.apache.commons.hivemind.impl.ModuleImpl;
  -import org.apache.commons.hivemind.impl.SingletonServiceExtensionPointImpl;
  +import org.apache.commons.hivemind.impl.ServiceExtensionPointImpl;
   import org.apache.commons.hivemind.impl.SystemPropertiesSymbolSource;
   
   /**
  @@ -172,7 +172,7 @@
       public void testInvokeFactoryServiceConstructorAccessors()
       {
           Module m = new ModuleImpl();
  -        ServiceExtensionPoint sep = new SingletonServiceExtensionPointImpl();
  +        ServiceExtensionPoint sep = new ServiceExtensionPointImpl();
           List p = new ArrayList();
           InvokeFactoryServiceConstructor c = new InvokeFactoryServiceConstructor();
   
  
  
  
  1.5       +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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TestToString.java	22 Sep 2003 20:06:00 -0000	1.4
  +++ TestToString.java	29 Sep 2003 15:32:26 -0000	1.5
  @@ -71,8 +71,8 @@
   import org.apache.commons.hivemind.impl.InterceptorStackImpl;
   import org.apache.commons.hivemind.impl.ModuleImpl;
   import org.apache.commons.hivemind.impl.RegistryImpl;
  +import org.apache.commons.hivemind.impl.ServiceExtensionPointImpl;
   import org.apache.commons.hivemind.impl.ServiceInterceptorContributionImpl;
  -import org.apache.commons.hivemind.impl.SingletonServiceExtensionPointImpl;
   import org.apache.commons.hivemind.parse.ConfigurationPointDescriptor;
   import org.apache.commons.hivemind.parse.ContributionDescriptor;
   import org.apache.commons.hivemind.parse.CreateInstanceDescriptor;
  @@ -149,7 +149,7 @@
           new ElementImpl().toString();
           new AttributeImpl("foo", "bar").toString();
           new ServiceInterceptorContributionImpl().toString();
  -        new SingletonServiceExtensionPointImpl().toString();
  +        new ServiceExtensionPointImpl().toString();
           new InterceptorStackImpl(new MockServiceExtensionPoint(), null).toString();
       }
   }
  
  
  
  1.2       +2 -2      jakarta-commons-sandbox/hivemind/framework/xdocs/SymbolSource.xml
  
  Index: SymbolSource.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/framework/xdocs/SymbolSource.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SymbolSource.xml	26 Sep 2003 18:19:35 -0000	1.1
  +++ SymbolSource.xml	29 Sep 2003 15:32:26 -0000	1.2
  @@ -36,7 +36,7 @@
   The <b>order</b>	 attribute is used to sort the sources into a search order; lower values for order
   will be searched first.  The <a href="ApplicationDefaults.html">ApplicationDefaults</a> have
   an order of 900000.  The <a href="FactoryDefaults.html">FactoryDefaults</a> have an order of 1000000.  Generally,
  -your contributions should have an order value less than 90000.
  +your contributions should have an order value less than 900000.
   </p>
   
   <p>