hlship      2004/06/14 17:33:59

  Modified:    library/src/descriptor/META-INF hivemodule.sdl
               .        status.xml
               src/documentation/content/xdocs site.xml
  Added:       library/src/test/org/apache/hivemind/lib/factory
                        ObjectFactory.sdl TestObjectFactoryImpl.java
               library/src/java/org/apache/hivemind/lib/factory
                        ObjectFactoryContribution.java
                        FactoryStrings.properties ObjectFactoryBuilder.java
                        ObjectFactoryBuilderParameter.java
                        FactoryMessages.java ObjectFactoryImpl.java
               library/src/documentation/content/xdocs/hivemind-lib
                        ObjectFactoryBuilder.xml
               library/src/java/org/apache/hivemind/lib ObjectFactory.java
  Log:
  Add hivemind.lib.ObjectFactoryBuilder service and related classes, 
documentation and tests.
  
  Revision  Changes    Path
  1.1                  
jakarta-hivemind/library/src/test/org/apache/hivemind/lib/factory/ObjectFactory.sdl
  
  Index: ObjectFactory.sdl
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  module (id=hivemind.lib.test version="1.0.0")
  {
    service-point (id=NumberFactory 
interface=org.apache.hivemind.lib.ObjectFactory)
    {
      invoke-factory (service-id=hivemind.lib.ObjectFactoryBuilder)
      {
        factory (vend-class=java.lang.Number configuration-id=NumberFactory)
      }
    }
    
    configuration-point (id=NumberFactory 
schema-id=hivemind.lib.ObjectFactoryContribution)
    
    contribution (configuration-id=NumberFactory)
    {
      bean (name=double class=java.lang.Double)
      bean (name=int class=java.lang.Integer)
    }
  }
  
  
  1.1                  
jakarta-hivemind/library/src/test/org/apache/hivemind/lib/factory/TestObjectFactoryImpl.java
  
  Index: TestObjectFactoryImpl.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.ErrorHandler;
  import org.apache.hivemind.internal.RegistryInfrastructure;
  import org.apache.hivemind.lib.ObjectFactory;
  import org.apache.hivemind.test.HiveMindTestCase;
  import org.easymock.MockControl;
  
  public class TestObjectFactoryImpl extends HiveMindTestCase
  {
      private ObjectFactoryContribution build(String name, Class objectClass)
      {
          return build(name, objectClass, null);
      }
  
      private ObjectFactoryContribution build(String name, Class objectClass, 
Boolean cacheable)
      {
          ObjectFactoryContribution result = new ObjectFactoryContribution();
          result.setName(name);
          result.setBeanClass(objectClass);
          result.setCacheable(cacheable);
  
          return result;
      }
  
      private void executeNonClassContribution(String name, Class objectClass, 
String message)
      {
          List l = Collections.singletonList(build(name, objectClass));
  
          MockControl c = MockControl.createStrictControl(ErrorHandler.class);
          ErrorHandler eh = (ErrorHandler) c.getMock();
  
          eh.error(null, message, null, null);
  
          c.replay();
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, eh, Object.class, 
l, true);
  
          try
          {
              f.get(name);
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertEquals(FactoryMessages.unknownContribution(name), 
ex.getMessage());
          }
  
          c.verify();
      }
  
      public void testInterfaceContribution()
      {
          executeNonClassContribution(
              "serializable",
              Serializable.class,
              "Contribution 'serializable' is for java.io.Serializable which is 
inappropriate for an object factory. The contribution has been ignored.");
      }
  
      public void testArrayContribution()
      {
          executeNonClassContribution(
              "array",
              String[].class,
              "Contribution 'array' is for java.lang.String[] which is 
inappropriate for an object factory. The contribution has been ignored.");
      }
  
      public void testPrimitiveContribution()
      {
          executeNonClassContribution(
              "primitive",
              double.class,
              "Contribution 'primitive' is for double which is inappropriate 
for an object factory. The contribution has been ignored.");
      }
  
      public void testIncorrectType()
      {
          List l = Collections.singletonList(build("array-list", 
ArrayList.class));
  
          MockControl c = MockControl.createStrictControl(ErrorHandler.class);
          ErrorHandler eh = (ErrorHandler) c.getMock();
  
          eh.error(
              null,
              "Contribution 'array-list' (class java.util.ArrayList) is not 
assignable to interface java.util.Map and has been ignored.",
              null,
              null);
  
          c.replay();
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, eh, Map.class, l, 
true);
  
          try
          {
              f.get("array-list");
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertEquals(FactoryMessages.unknownContribution("array-list"), 
ex.getMessage());
          }
  
          c.verify();
      }
  
      public void testDupeName()
      {
          List l = new ArrayList();
          l.add(build("list", ArrayList.class));
          l.add(build("list", LinkedList.class));
  
          MockControl c = MockControl.createStrictControl(ErrorHandler.class);
          ErrorHandler eh = (ErrorHandler) c.getMock();
  
          eh.error(
              null,
              "Contribution 'list' duplicates a previous contribution (at 
unknown location) and has been ignored.",
              null,
              null);
  
          c.replay();
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, eh, 
Collection.class, l, true);
  
          Object o = f.get("list");
  
          assertTrue(o instanceof ArrayList);
  
          c.verify();
      }
  
      public void testTranslator()
      {
          List l = Collections.singletonList(build("string", String.class));
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, null, Object.class, 
l, true);
  
          String s = (String) f.get("string,locator");
  
          assertEquals("locator", s);
      }
  
      public void testPlain()
      {
          List l = Collections.singletonList(build("string", String.class));
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, null, Object.class, 
l, true);
  
          String s1 = (String) f.get("string");
          String s2 = (String) f.get("string");
  
          assertSame(s1, s2);
      }
  
      public void testNonCache()
      {
          List l = Collections.singletonList(build("buffer", 
StringBuffer.class, Boolean.FALSE));
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, null, Object.class, 
l, true);
  
          StringBuffer s1 = (StringBuffer) f.get("buffer");
          StringBuffer s2 = (StringBuffer) f.get("buffer");
  
          assertNotSame(s1, s2);
      }
  
      public void testConstructFailure()
      {
          List l = Collections.singletonList(build("integer", Integer.class));
  
          ObjectFactoryImpl f = new ObjectFactoryImpl(null, null, Number.class, 
l, true);
  
          try
          {
              f.get("integer");
              unreachable();
          }
          catch (ApplicationRuntimeException ex)
          {
              assertEquals(
                  "Unable to instantiate instance of class java.lang.Integer: 
java.lang.Integer",
                  ex.getMessage());
          }
  
      }
  
      public void testBuilder()
      {
          List l = Collections.singletonList(build("integer", Integer.class));
  
          ObjectFactoryBuilderParameter p = new ObjectFactoryBuilderParameter();
          p.setContributions(l);
  
          ObjectFactoryBuilder b = new ObjectFactoryBuilder();
  
          ObjectFactory f =
              (ObjectFactory) b.createCoreServiceImplementation(
                  "foo.bar",
                  ObjectFactory.class,
                  null,
                  Collections.singletonList(p));
  
          Integer i = (Integer) f.get("integer,5");
  
          assertEquals(new Integer(5), i);
      }
  
      /**
       * Test integration; i.e., a service and configuration in a descriptor.
       */
      public void testIntegration() throws Exception
      {
          RegistryInfrastructure r = 
buildFrameworkRegistry("ObjectFactory.sdl");
  
          ObjectFactory f =
              (ObjectFactory) r.getService("hivemind.lib.test.NumberFactory", 
ObjectFactory.class);
  
          assertEquals(new Integer(27), f.get("int,27"));
          assertEquals(new Double(-22.5), f.get("double,-22.5"));
      }
  }
  
  
  
  1.9       +89 -0     
jakarta-hivemind/library/src/descriptor/META-INF/hivemodule.sdl
  
  Index: hivemodule.sdl
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/library/src/descriptor/META-INF/hivemodule.sdl,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- hivemodule.sdl    10 Jun 2004 19:49:39 -0000      1.8
  +++ hivemodule.sdl    15 Jun 2004 00:33:59 -0000      1.9
  @@ -167,6 +167,95 @@
          create-instance 
(class=org.apache.hivemind.lib.impl.SpringBeanFactoryHolderImpl)
        }
        
  +     schema (id=ObjectFactoryContribution)
  +     {
  +       description
  +       {
  +         "Schema used with the hivemind.lib.ObjectFactoryBuilder service, to 
define configuration that accepts "
  +         "definitions of classes that may be vended by the generated 
ObjectFactory."
  +       }
  +       
  +       element (name=bean)
  +       {
  +         description 
  +         {
  +           "Define one class of bean that may be vended.  Beans must have 
either a public constructor that takes "
  +           "no arguments, or a public constructor that takes a single string 
argument (or both). "
  +         }
  +         
  +         attribute (name=name required=true)
  +         {
  +           description { "A unique name for the bean." }
  +         }
  +         
  +         attribute (name=class required=true translator=class)
  +         {
  +           description { "The bean class that will be instantiated by the 
factory." }
  +         }
  +         
  +         attribute (name=cacheable translator=boolean)
  +         {
  +           description { "Defines whether instances of the bean may be 
cached; the default is specified by the factory." }
  +         }
  +         
  +         conversion 
(class=org.apache.hivemind.lib.factory.ObjectFactoryContribution)
  +         {
  +           map (attribute=class property=beanClass)
  +         }
  +       }
  +     }
  +     
  +     service-point (id=ObjectFactoryBuilder 
interface=org.apache.hivemind.ServiceImplementationFactory)
  +     {
  +       description
  +       {
  +         "A service which builds Object Factories.  Factories are driven by 
a configuration that conforms to the "
  +         "hivemind.lib.ObjectFactoryContribution schema."
  +       }
  +       
  +       parameters-schema
  +       {
  +         element (name=factory)
  +         {
  +           attribute (name=vend-class translator=class)
  +           {
  +             description
  +             {
  +               "The class (or interface) vended by this factory. 
Contributions must be assignable to this type, or will be ignored. "
  +               "The default value is java.lang.Object."
  +             }
  +           }
  +           
  +           attribute (name=default-cacheable translator=boolean)
  +           {
  +             description
  +             {
  +               "The default value for cacheable for any contributions that 
are not more specific. The default value is true."
  +             }
  +           }
  +           
  +           attribute (name=configuration-id translator=configuration 
required=true)
  +           {
  +             description
  +             {
  +               "The configuration containing the contributions that define 
what classes are actually vended. The configuration must use the "
  +               "hivemind.lib.ObjectFactoryContribution schema."
  +             }
  +           }
  +           
  +           conversion 
(class=org.apache.hivemind.lib.factory.ObjectFactoryBuilderParameter)
  +           {
  +              map (attribute=configuration-id property=contributions)
  +           }
  +         }  // element
  +       } // parameters-schema
  +       
  +       invoke-factory (service-id=hivemind.BuilderFactory)
  +       {
  +         construct 
(class=org.apache.hivemind.lib.factory.ObjectFactoryBuilder 
service-id-property=serviceId error-handler-property=errorHandler)
  +       }
  +     }
  +     
        service-point (id=DefaultImplementationBuilder 
interface=org.apache.hivemind.lib.DefaultImplementationBuilder)
        {
          description
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/ObjectFactoryContribution.java
  
  Index: ObjectFactoryContribution.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import org.apache.hivemind.impl.BaseLocatable;
  
  /**
   * A contribution used with an [EMAIL PROTECTED] 
org.apache.hivemind.lib.ObjectFactory}
   * to define one class of objects that may be returned from the factory.
   *
   * @author Howard Lewis Ship
   */
  public class ObjectFactoryContribution extends BaseLocatable
  {
      private String _name;
      private Class _beanClass;
      
      // Stored as a boolean, so that null means 'as defined by the factory'
      private Boolean _cacheable;
  
      public Boolean getCacheable()
      {
          return _cacheable;
      }
  
      public String getName()
      {
          return _name;
      }
  
      public Class getBeanClass()
      {
          return _beanClass;
      }
  
      public void setCacheable(Boolean cacheable)
      {
          _cacheable = cacheable;
      }
  
      public void setName(String string)
      {
          _name = string;
      }
  
      public void setBeanClass(Class objectClass)
      {
          _beanClass = objectClass;
      }
  
      public boolean getStoreResultInCache(boolean defaultCacheable)
      {
          return _cacheable == null ? defaultCacheable : 
_cacheable.booleanValue();
      }
  }
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/FactoryStrings.properties
  
  Index: FactoryStrings.properties
  ===================================================================
  #
  # Copyright 2004 The Apache Software Foundation
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in liance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  wrong-contribution-type=Contribution ''{0}'' (class {1}) is not assignable to 
{2} and has been ignored.
  invalid-contribution-class=Contribution ''{0}'' is for {1} which is 
inappropriate for an object factory. The contribution has been ignored.
  dupe-contribution=Contribution ''{0}'' duplicates a previous contribution (at 
{1}) and has been ignored.
  unknown-contribution=No object factory contribution named ''{0}''.
  unable-to-instantiate=Unable to instantiate instance of class {0}: {1}
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/ObjectFactoryBuilder.java
  
  Index: ObjectFactoryBuilder.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import java.util.List;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.hivemind.ErrorHandler;
  import org.apache.hivemind.HiveMind;
  import org.apache.hivemind.ServiceImplementationFactory;
  import org.apache.hivemind.impl.BaseLocatable;
  import org.apache.hivemind.internal.Module;
  
  /**
   * Service implementation factory that builds [EMAIL PROTECTED] 
org.apache.hivemind.lib.ObjectFactory}
   * instances.
   *
   * @author Howard Lewis Ship
   */
  public class ObjectFactoryBuilder extends BaseLocatable implements 
ServiceImplementationFactory
  {
      private String _serviceId;
      private ErrorHandler _errorHandler;
  
      public Object createCoreServiceImplementation(
          String serviceId,
          Class serviceInterface,
          Module invokingModule,
          List parameters)
      {
          HiveMind.checkFactoryParameterCount(_serviceId, parameters, 1);
  
          ObjectFactoryBuilderParameter p = (ObjectFactoryBuilderParameter) 
parameters.get(0);
  
          Log log = LogFactory.getLog(serviceId);
  
          return new ObjectFactoryImpl(
              log,
              _errorHandler,
              p.getVendClass(),
              p.getContributions(),
              p.getDefaultCacheable());
      }
  
      public void setErrorHandler(ErrorHandler handler)
      {
          _errorHandler = handler;
      }
  
      public void setServiceId(String string)
      {
          _serviceId = string;
      }
  
  }
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/ObjectFactoryBuilderParameter.java
  
  Index: ObjectFactoryBuilderParameter.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import java.util.List;
  
  /**
   * Parameter object passed to [EMAIL PROTECTED] 
javax.naming.spi.ObjectFactoryBuilder}.
   *
   * @author Howard Lewis Ship
   */
  public class ObjectFactoryBuilderParameter
  {
      private Class _vendClass = Object.class;
      private boolean _defaultCacheable = true;
      private List _contributions;
  
      /**
       * The contributions to the list (assigned from the companion
       * configuration point).
       */
      public List getContributions()
      {
          return _contributions;
      }
  
      /**
       * Default value for cacheable in contributions that do not explicitly
       * set a value.  Default is <code>true</code>.
       */
  
      public boolean getDefaultCacheable()
      {
          return _defaultCacheable;
      }
  
      /**
       * The class or interface to be vended by the factory (all contributed
       * classes must be assigneble). Defaults to <code>Object</code>. 
       */
      public Class getVendClass()
      {
          return _vendClass;
      }
  
      public void setContributions(List list)
      {
          _contributions = list;
      }
  
      public void setDefaultCacheable(boolean b)
      {
          _defaultCacheable = b;
      }
  
      public void setVendClass(Class class1)
      {
          _vendClass = class1;
      }
  
  }
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/FactoryMessages.java
  
  Index: FactoryMessages.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.hivemind.HiveMind;
  import org.apache.hivemind.impl.MessageFormatter;
  import org.apache.hivemind.service.ClassFabUtils;
  
  final class FactoryMessages
  {
      private static final Log LOG = LogFactory.getLog(FactoryMessages.class);
      private static final MessageFormatter _formatter =
          new MessageFormatter(LOG, FactoryMessages.class, "FactoryStrings");
  
      public static String wrongContributionType(ObjectFactoryContribution c, 
Class vendType)
      {
          return _formatter.format(
              "wrong-contribution-type",
              c.getName(),
              c.getBeanClass().getName(),
              vendType);
      }
  
      public static String invalidContributionClass(ObjectFactoryContribution c)
      {
          return _formatter.format(
              "invalid-contribution-class",
              c.getName(),
              ClassFabUtils.getJavaClassName(c.getBeanClass()));
      }
  
      public static String dupeContribution(ObjectFactoryContribution existing)
      {
          return _formatter.format(
              "dupe-contribution",
              existing.getName(),
              HiveMind.getLocationString(existing));
      }
  
      public static String unknownContribution(String name)
      {
          return _formatter.format("unknown-contribution", name);
      }
  
      public static String unableToInstantiate(Class objectClass, Throwable 
cause)
      {
          return _formatter.format(
              "unable-to-instantiate",
              objectClass.getName(),
              _formatter.extractMessage(cause));
      }
  }
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/factory/ObjectFactoryImpl.java
  
  Index: ObjectFactoryImpl.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib.factory;
  
  import java.lang.reflect.Constructor;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.commons.logging.Log;
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.ErrorHandler;
  import org.apache.hivemind.HiveMind;
  import org.apache.hivemind.impl.BaseLocatable;
  import org.apache.hivemind.lib.ObjectFactory;
  
  /**
   * Implementation of [EMAIL PROTECTED] org.apache.hivemind.lib.ObjectFactory}.
   *
   * @author Howard Lewis Ship
   */
  public class ObjectFactoryImpl extends BaseLocatable implements ObjectFactory
  {
      private Log _log;
      private ErrorHandler _errorHandler;
      private Class _vendType;
      private Map _contributions = new HashMap();
      private Map _cache = new HashMap();
      private boolean _defaultCacheable;
  
      public ObjectFactoryImpl(
          Log log,
          ErrorHandler errorHandler,
          Class vendType,
          List contributions,
          boolean defaultCacheable)
      {
          _log = log;
          _errorHandler = errorHandler;
          _vendType = vendType;
          _defaultCacheable = defaultCacheable;
  
          processContributions(contributions);
      }
  
      private void processContributions(List list)
      {
          Iterator i = list.iterator();
  
          while (i.hasNext())
          {
              ObjectFactoryContribution c = (ObjectFactoryContribution) 
i.next();
  
              Class beanClass = c.getBeanClass();
  
              if (beanClass.isInterface() || beanClass.isArray() || 
beanClass.isPrimitive())
              {
                  _errorHandler.error(
                      _log,
                      FactoryMessages.invalidContributionClass(c),
                      c.getLocation(),
                      null);
                  continue;
              }
  
              if (!_vendType.isAssignableFrom(beanClass))
              {
                  _errorHandler.error(
                      _log,
                      FactoryMessages.wrongContributionType(c, _vendType),
                      c.getLocation(),
                      null);
                  continue;
              }
  
              String name = c.getName();
  
              ObjectFactoryContribution existing =
                  (ObjectFactoryContribution) _contributions.get(name);
  
              if (existing != null)
              {
                  _errorHandler.error(
                      _log,
                      FactoryMessages.dupeContribution(existing),
                      existing.getLocation(),
                      null);
                  continue;
              }
  
              // Passed the checks, good to go.
  
              _contributions.put(name, c);
          }
      }
  
      public synchronized Object get(String locator)
      {
          Object result = _cache.get(locator);
  
          if (result == null)
              result = create(locator);
  
          return result;
      }
  
      // Implicitly synchronized by get()
  
      private Object create(String locator)
      {
          int commax = locator.indexOf(',');
  
          String name = commax < 0 ? locator.trim() : locator.substring(0, 
commax);
          String initializer = commax < 0 ? null : locator.substring(commax + 
1).trim();
  
          ObjectFactoryContribution c = (ObjectFactoryContribution) 
_contributions.get(name);
  
          if (c == null)
              throw new 
ApplicationRuntimeException(FactoryMessages.unknownContribution(name));
  
          Object result = construct(c, initializer);
  
          if (c.getStoreResultInCache(_defaultCacheable))
              _cache.put(locator, result);
  
          return result;
      }
  
      private Object construct(ObjectFactoryContribution contribution, String 
initializer)
      {
          Class beanClass = contribution.getBeanClass();
  
          try
          {
              if (HiveMind.isBlank(initializer))
                  return beanClass.newInstance();
  
              Constructor c = beanClass.getConstructor(new Class[] { 
String.class });
  
              return c.newInstance(new Object[] { initializer });
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  FactoryMessages.unableToInstantiate(beanClass, ex),
                  contribution.getLocation(),
                  ex);
  
          }
      }
  
  }
  
  
  
  1.1                  
jakarta-hivemind/library/src/documentation/content/xdocs/hivemind-lib/ObjectFactoryBuilder.xml
  
  Index: ObjectFactoryBuilder.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
     Copyright 2004 The Apache Software Foundation
  
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
         http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
  -->
  <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.2//EN" 
    "./dtd/document-v12.dtd" [
    <!ENTITY projectroot '../'>
    <!ENTITY % common-links SYSTEM "../links.ent">
    %common-links;
    ]>
  <document>
    <header>
      <title>hivemind.lib.ObjectFactoryBuilder Service</title>
    </header>
    <body>
      <p>The <link 
        href="&hivedoc;/service/hivemind.lib.ObjectFactoryBuilder.html"> 
        ObjectFactoryBuilder</link> services is used to construct an <link 
        href="&apiroot-lib;/ObjectFactory.html">ObjectFactory</link> instance. 
An 
        ObjectFactory will <em>vend out</em> instances of classes. A logical 
name 
        is mapped to a particular Java class to be instantiated. </p>
      <p> Client code can retrieve beans via the factory's <code>get()</code> 
        method. Beans may be retrieved simply by name, or the name and an 
        initializer may be specified, seperated by commas. The initializer is 
        provided to the bean via an alternate constructor that takes a single 
        string parameter. Initializers are used, typically, to initialize 
        properties of the bean, but the actual implementation is internal to 
the 
        bean class. </p>
      <section>
        <title>Usage</title>
        <p> The general usage is as follows: </p>
        <source><![CDATA[
  invoke-factory (service-id=hivemind.lib.ObjectFactoryBuilder)
  {
    factory (vend-class=... configuration-id=... default-cacheable=...)
  }
  ]]></source>
        <p> The <code>vend-class</code> attribute is the name of a class all 
          vended objects must be assignable to (as a class or interface). This 
is 
          used to validate contributed bean definitions. By default it is 
          <code>java.lang.Object</code>.</p>
        <p>The <code>configuration-id</code> is the id of the companion 
          configuration (used to define object classes).</p>
        <p>The optional <code>default-cacheable</code> attribute sets the 
default 
          for whether instantiated beans should be cached for reuse. By default 
          this is true, which is appropriate for most use cases where the 
vended 
          objects are immutable.</p>
      </section>
      <section>
        <title>Configuration</title>
        <p>Each ObjectFactory service must have a configuration, into which 
beans 
          are contributed:</p>
        <source><![CDATA[
  configuration-point (id=... 
schema-id=hivemind.lib.ObjectFactoryContribution)]]>
           </source>
        <p>Contributions into the configuration are used to specify the bean 
          classes to instantiate, as:</p>
        <source><![CDATA[
  bean (name=... class=... cacheable=...) 
  ]]> </source>
        <p> <code>name</code> is a unique name used to reference an instance of 
          the class. </p>
        <p><code>class</code> is the Java class to instantiate.</p>
        <p><code>cacheable</code> determines whether instances of the class are 
          cacheable (that is, have immutable internal state and should be 
          reused), or non-cacheable (presumably, because of mutable internal 
          state).</p>
      </section>
    </body>
  </document>
  
  
  1.6       +7 -3      jakarta-hivemind/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/status.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- status.xml        10 Jun 2004 14:20:50 -0000      1.5
  +++ status.xml        15 Jun 2004 00:33:59 -0000      1.6
  @@ -36,8 +36,9 @@
           related to ClassFab.</action>
         <action type="add" dev="HLS">Created two new services in hivemind-lib 
           for creating default implementations of arbitrary interfaces 
  -        (DefaultImplementationBuilder) and for using that to create 
placeholder 
  -        services (PlaceholderFactory).</action>
  +        (<link 
href="site:hivemind.lib.DefaultImplementationBuilder">DefaultImplementationBuilder</link>)
 
  +        and for using that to create placeholder 
  +        services (<link 
href="site:hivemind.lib.PlaceholderFactory">PlaceholderFactory</link>).</action>
         <action type="add" dev="HLS">Created MessageFormatter class as a 
wrapper 
           around ResourceBundle and an easy way for individual packages to 
gain 
           access to runtime messages. </action>
  @@ -47,10 +48,13 @@
         <action type="add" dev="HLS">Added the <code>qualified-id</code> and 
           <code>id-list</code> translators.</action>
         <action type="add" dev="HLS">Added the 
  -        <code>hivemind.lib.PipelineFactory</code> and related code, schemas, 
  +        <link 
href="site:hivemind.lib.PipelineFactory">hivemind.lib.PipelineFactory</link> 
and related code, schemas, 
           tests and documentation. </action>
         <action type="fix" dev="HLS" fixes-bug="HIVEMIND-4">
           Enhance logging of exceptions when setting a service property to a 
contribution
  +      </action>
  +      <action type="add" dev="HLS">
  +        Added service <link 
href="site:hivemind.lib.ObjectFactoryBuilder">hivemind.lib.ObjectFactoryBuilder</link>.
     
         </action>
       </release>
        </changes>
  
  
  
  1.15      +1 -0      jakarta-hivemind/src/documentation/content/xdocs/site.xml
  
  Index: site.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-hivemind/src/documentation/content/xdocs/site.xml,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- site.xml  9 Jun 2004 14:58:16 -0000       1.14
  +++ site.xml  15 Jun 2004 00:33:59 -0000      1.15
  @@ -108,6 +108,7 @@
         <hivemind.lib.DefaultImplementationBuilder 
label="DefaultImplementationBuilder" href="DefaultImplementationBuilder.html"/>
                        <hivemind.lib.EJBProxyFactory label="EJBProxyFactory" 
href="EJBProxyFactory.html"/>
                        <hivemind.lib.NameLookup label="NameLookup" 
href="NameLookup.html"/>
  +      <hivemind.lib.ObjectFactoryBuilder label="ObjectFactoryBuilder" 
href="ObjectFactoryBuilder.html"/>
         <hivemind.lib.PlaceholderFactory label="PlaceholderFactory" 
href="PlaceholderFactory.html"/> 
         <hivemind.lib.PipelineFactory label="PipelineFactory" 
href="PipelineFactory.html"/>     
                        <hivemind.lib.RemoteExceptionCoordinator 
label="RemoteExceptionCoordinator" href="RemoteExceptionCoordinator.html"/>
  
  
  
  1.1                  
jakarta-hivemind/library/src/java/org/apache/hivemind/lib/ObjectFactory.java
  
  Index: ObjectFactory.java
  ===================================================================
  //  Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.hivemind.lib;
  
  /**
   * Service interface for a source of beans of a particular type.
   * Bean instances are retrieved using a <em>locator string</em> which is of 
the form:
   * <code><em>name</em>[,<em>initializer</em>]</code>.  That is, an optional 
initializer is
   * may be specified, separated by a comma.
   * 
   * <p>
   * Beans may be cached or not.
   * 
   * <p>
   * The <code>hivemind.lib.ObjectFactoryBuilder</code> service is used to 
create services
   * implementing this interface (driven from a configuration).
   *
   * @author Howard Lewis Ship
   */
  public interface ObjectFactory
  {
      /**
       * Gets a bean via its locator (it's name plus, optionally, an 
initializer).
       * 
       * @param locator the name or name and initializer
       * @return a bean instance
       * @throws org.apache.hivemind.ApplicationRuntimeException if no bean 
matching the provided 
       * name has been defined.
       */
      public Object get(String locator);
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to