hivemind-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject cvs commit: jakarta-hivemind/library/src/java/org/apache/hivemind/lib ObjectFactory.java
Date Tue, 15 Jun 2004 00:33:59 GMT
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 {@link 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 {@link 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 {@link 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 {@link 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: hivemind-cvs-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-cvs-help@jakarta.apache.org


Mime
View raw message