You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hivemind.apache.org by hl...@apache.org on 2005/03/30 17:19:32 UTC

cvs commit: jakarta-hivemind/library/src/descriptor/META-INF hivemodule.xml

hlship      2005/03/30 07:19:32

  Modified:    .        version.properties status.xml
               library/src/java/org/apache/hivemind/lib/util
                        UtilMessages.java UtilStrings.properties
               src/documentation/content/xdocs site.xml
               library/src/descriptor/META-INF hivemodule.xml
  Added:       library/src/test/org/apache/hivemind/lib/util
                        TestStrategyRegistry.java
               library/src/documentation/content/xdocs/hivemind-lib
                        StrategyFactory.xml
               library/src/java/org/apache/hivemind/lib/strategy
                        StrategyParameter.java StrategyMessages.java
                        StrategyFactory.java StrategyContribution.java
                        StrategyStrings.properties
               library/src/java/org/apache/hivemind/lib/util
                        StrategyRegistry.java StrategyRegistryImpl.java
               library/src/test/org/apache/hivemind/lib/strategy
                        CatchAllToStringStrategy.java ToStringStrategy.java
                        AdapterFactoryIntegration.xml
                        TestStrategyFactory.java
  Removed:     library/src/test/org/apache/hivemind/lib/util
                        TestAdaptorRegistry.java
               library/src/documentation/content/xdocs/hivemind-lib
                        AdapterRegistryFactory.xml
               library/src/java/org/apache/hivemind/lib/adapter
                        AdapterStrings.properties AdapterMessages.java
                        AdapterRegistryFactory.java
                        AdapterRegistryContribution.java
                        AdapterRegistryParameter.java
               library/src/java/org/apache/hivemind/lib/util
                        AdapterRegistry.java AdapterRegistryImpl.java
               library/src/test/org/apache/hivemind/lib/adapter
                        AdapterFactoryIntegration.xml
                        CatchAllToStringAdapter.java ToStringAdapter.java
                        TestAdapterRegistryFactory.java
  Log:
  Rename AdapterRegistry to StrategyRegistry, and AdapterRegistryFactory to StrategyFactory, to better reflect the relationship to the Gang-of-Four Strategy pattern.
  
  Revision  Changes    Path
  1.1                  jakarta-hivemind/library/src/test/org/apache/hivemind/lib/util/TestStrategyRegistry.java
  
  Index: TestStrategyRegistry.java
  ===================================================================
  // Copyright 2004, 2005 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.util;
  
  import java.io.Serializable;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.hivemind.lib.util.StrategyRegistry;
  import org.apache.hivemind.lib.util.StrategyRegistryImpl;
  import org.apache.hivemind.test.HiveMindTestCase;
  
  /**
   * Tests the {@link org.apache.hivemind.lib.util.StrategyRegistryImpl} class.
   * 
   * @author Howard Lewis Ship
   * @since 1.1
   */
  
  public class TestStrategyRegistry extends HiveMindTestCase
  {
  
      private StrategyRegistry build()
      {
          StrategyRegistry result = new StrategyRegistryImpl();
  
          result.register(Object.class, "OBJECT");
          result.register(Object[].class, "OBJECT[]");
          result.register(String.class, "STRING");
          result.register(List.class, "LIST");
          result.register(Map.class, "MAP");
          result.register(Serializable.class, "SERIALIZABLE");
          result.register(int[].class, "INT[]");
          result.register(double.class, "DOUBLE");
          result.register(Number[].class, "NUMBER[]");
  
          return result;
      }
  
      private void expect(String expected, Class subjectClass)
      {
          Object actual = build().getStrategy(subjectClass);
  
          assertEquals(expected, actual);
      }
  
      public void testDefaultMatch()
      {
          expect("OBJECT", TestStrategyRegistry.class);
      }
  
      public void testClassBeforeInterface()
      {
          expect("STRING", String.class);
      }
  
      public void testInterfaceMatch()
      {
          expect("SERIALIZABLE", Boolean.class);
      }
  
      public void testObjectArrayMatch()
      {
          expect("OBJECT[]", Object[].class);
      }
  
      public void testObjectSubclassArray()
      {
          expect("OBJECT[]", String[].class);
      }
  
      public void testRegisteredSubclassArray()
      {
          expect("NUMBER[]", Number[].class);
      }
  
      public void testScalarArrayMatch()
      {
          expect("INT[]", int[].class);
      }
  
      public void testScalarArrayDefault()
      {
          // This won't change, scalar arrays can't be cast to Object[].
  
          expect("SERIALIZABLE", short[].class);
      }
  
      public void testScalar()
      {
          expect("DOUBLE", double.class);
      }
  
      public void testScalarDefault()
      {
          expect("OBJECT", float.class);
      }
  
      public void testSearchNoInterfaces()
      {
          expect("OBJECT", Object.class);
      }
  
      public void testNoMatch()
      {
          StrategyRegistry r = new StrategyRegistryImpl();
  
          r.register(String.class, "STRING");
  
          try
          {
              r.getStrategy(Boolean.class);
  
              unreachable();
          }
          catch (IllegalArgumentException ex)
          {
              assertEquals(UtilMessages.strategyNotFound(Boolean.class), ex.getMessage());
          }
      }
  
      public void testToString()
      {
          StrategyRegistry r = new StrategyRegistryImpl();
  
          r.register(String.class, "STRING");
  
          assertEquals("AdaptorRegistry[java.lang.String=STRING]", r.toString());
      }
  
      public void testDuplicateRegistration()
      {
          StrategyRegistry r = new StrategyRegistryImpl();
  
          r.register(String.class, "STRING");
  
          try
          {
              r.register(String.class, "STRING2");
  
              unreachable();
          }
          catch (IllegalArgumentException ex)
          {
              assertEquals(UtilMessages.duplicateRegistration(String.class), ex.getMessage());
          }
      }
  }
  
  
  1.1                  jakarta-hivemind/library/src/documentation/content/xdocs/hivemind-lib/StrategyFactory.xml
  
  Index: StrategyFactory.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
     Copyright 2004, 2005 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.3//EN" 
    "http://xml.apache.org/forrest/dtd/document-v13.dtd" [
    <!ENTITY projectroot '../'>
    <!ENTITY % common-links SYSTEM "../links.ent">
    %common-links;
    ]>
  <document>
    <header>
      <title>hivemind.lib.StrategyFactory Service</title>
    </header>
    <body>
      <p>The <link href="&hivedoc;/service/hivemind.lib.StrategyFactory.html"> 
        StrategyFactory</link> service is used to create a service implementation
        based on a service interface and a number of <em>strategies</em> implementing that interface.</p>
        <p>
          The class of the first parameter of each method is used to select the correct strategy instance to
          delegate the method invocation to.  
        </p>
        <p>
          The class-to-strategy lookup understands inheritance. If an exact match for a class is not found,
          then the search works up the inheritance chain.  First, it checks all the super-classes, working upwards,
          but skipping java.lang.Object. It then searches all the interfaces directly or indirectly implemented by
          the search class.  Finally, java.lang.Object is checked.  It is an exception if no match is found (so you should
          almost always include a strategy for java.lang.Object).
        </p>
        
        
      <section>
        <title>Usage</title>
        <p> The factory expects a single parameter element: </p>
        <source><![CDATA[
  <construct configuration-id="..."/>]]></source>
        <p>The <code>configuration-id</code> is the id of the companion 
          configuration (used to define classes and strategies).</p>
      </section>
      <section>
        <title>Configuration</title>
        <p>Each srevice constructed by StrategyFactory must have a configuration, into which strategies 
          are contributed:</p>
        <source><![CDATA[
  <configuration-point id="..." schema-id="hivemind.lib.StrategyRegistry"/>]]></source>
      </section>
      <section>
        <title>Contributions</title>
        <p>Contributions into the configuration are used to specify classes to match, and the corresponding strategy to use.</p>
        <section>
          <title>strategy</title>
          <source><![CDATA[
  <strategy class="..." object="..."/>]]> </source>
          <p>Contributes a strategy. The <code>class</code> attribute defines the class to match against, the 
            <code>object</code> attribute provides the actual strategy object (which must implement the service 
            interface). </p>
        </section>
      </section>
    </body>
  </document>
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/strategy/StrategyParameter.java
  
  Index: StrategyParameter.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  import java.util.List;
  
  import org.apache.hivemind.impl.BaseLocatable;
  
  /**
   * Parameter value passed to the <code>hivemind.lib.StrategyFactory</code> service factory.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class StrategyParameter extends BaseLocatable
  {
      private List _contributions;
  
      /**
       * List of {@link org.apache.hivemind.lib.strategy.StrategyContribution}.
       */
      public List getContributions()
      {
          return _contributions;
      }
  
      public void setContributions(List configuration)
      {
          _contributions = configuration;
      }
  }
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/strategy/StrategyMessages.java
  
  Index: StrategyMessages.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  import org.apache.hivemind.impl.MessageFormatter;
  import org.apache.hivemind.service.ClassFabUtils;
  import org.apache.hivemind.service.MethodSignature;
  
  /**
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class StrategyMessages
  {
      private static final MessageFormatter _formatter = new MessageFormatter(StrategyMessages.class,
              "StrategyStrings");
  
      static String strategyWrongInterface(Object adaptor, Class registerClass,
              Class serviceInterface)
      {
          return _formatter.format("strategy-wrong-interface", adaptor, ClassFabUtils
                  .getJavaClassName(registerClass), serviceInterface.getName());
      }
  
      static String improperServiceMethod(MethodSignature sig)
      {
          return _formatter.format("improper-service-method", sig);
      }
  
      static String toString(String serviceId, Class serviceInterface)
      {
          return _formatter.format("to-string", serviceId, serviceInterface.getName());
      }
  }
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/strategy/StrategyFactory.java
  
  Index: StrategyFactory.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Modifier;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.hivemind.ApplicationRuntimeException;
  import org.apache.hivemind.HiveMind;
  import org.apache.hivemind.ServiceImplementationFactory;
  import org.apache.hivemind.ServiceImplementationFactoryParameters;
  import org.apache.hivemind.lib.util.StrategyRegistry;
  import org.apache.hivemind.lib.util.StrategyRegistryImpl;
  import org.apache.hivemind.service.ClassFab;
  import org.apache.hivemind.service.ClassFabUtils;
  import org.apache.hivemind.service.ClassFactory;
  import org.apache.hivemind.service.MethodIterator;
  import org.apache.hivemind.service.MethodSignature;
  
  /**
   * Implementation of the <code>hivemind.lib.StrategyFactory</code> service that constructs a
   * service where the first parameter of each method is used to selecte a strategy from an
   * {@link org.apache.hivemind.lib.util.StrategyRegistry}. The method invocation is then delegated
   * to the strategy instance.
   * <p>
   * The service factory parameter defines a configuration (of
   * {@link org.apache.hivemind.lib.strategy.StrategyContribution}s) that provide the mapping from
   * Java classes (or interfaces) to adapter instances.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class StrategyFactory implements ServiceImplementationFactory
  {
      private ClassFactory _classFactory;
  
      public Object createCoreServiceImplementation(
              ServiceImplementationFactoryParameters factoryParameters)
      {
          StrategyRegistry ar = new StrategyRegistryImpl();
  
          buildRegistry(factoryParameters, ar);
  
          Class implClass = buildImplementationClass(factoryParameters);
  
          try
          {
              Constructor c = implClass.getConstructors()[0];
  
              return c.newInstance(new Object[]
              { ar });
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(ex.getMessage(), HiveMind
                      .getLocation(factoryParameters.getFirstParameter()), ex);
          }
  
      }
  
      // package private for testing purposes
  
      void buildRegistry(ServiceImplementationFactoryParameters factoryParameters, StrategyRegistry ar)
      {
          Class serviceInterface = factoryParameters.getServiceInterface();
  
          StrategyParameter p = (StrategyParameter) factoryParameters.getFirstParameter();
  
          List contributions = p.getContributions();
  
          Iterator i = contributions.iterator();
  
          while (i.hasNext())
          {
              StrategyContribution c = (StrategyContribution) i.next();
  
              try
              {
                  Object adapter = c.getStrategy();
  
                  if (!serviceInterface.isAssignableFrom(adapter.getClass()))
                      throw new ClassCastException(StrategyMessages.strategyWrongInterface(adapter, c
                              .getRegisterClass(), serviceInterface));
  
                  ar.register(c.getRegisterClass(), adapter);
              }
              catch (Exception ex)
              {
                  factoryParameters.getErrorLog().error(ex.getMessage(), c.getLocation(), ex);
              }
  
          }
  
      }
  
      // package private for testing purposes
  
      private Class buildImplementationClass(ServiceImplementationFactoryParameters factoryParameters)
      {
          String name = ClassFabUtils.generateClassName(factoryParameters.getServiceInterface());
  
          return buildImplementationClass(factoryParameters, name);
      }
  
      // package private for testing purposes
  
      Class buildImplementationClass(ServiceImplementationFactoryParameters factoryParameters,
              String name)
      {
          Class serviceInterface = factoryParameters.getServiceInterface();
  
          ClassFab cf = _classFactory.newClass(name, Object.class);
  
          cf.addInterface(serviceInterface);
  
          cf.addField("_registry", StrategyRegistry.class);
  
          cf.addConstructor(new Class[]
          { StrategyRegistry.class }, null, "_registry = $1;");
  
          // TODO: Should we add a check for $1 == null?
  
          cf.addMethod(Modifier.PRIVATE, new MethodSignature(serviceInterface, "_getStrategy",
                  new Class[]
                  { Object.class }, null), "return (" + serviceInterface.getName()
                  + ") _registry.getStrategy($1.getClass());");
  
          MethodIterator i = new MethodIterator(serviceInterface);
  
          while (i.hasNext())
          {
              MethodSignature sig = i.next();
  
              if (proper(sig))
              {
                  addAdaptedMethod(cf, sig);
              }
              else
              {
                  ClassFabUtils.addNoOpMethod(cf, sig);
  
                  factoryParameters.getErrorLog().error(
                          StrategyMessages.improperServiceMethod(sig),
                          HiveMind.getLocation(factoryParameters.getFirstParameter()),
                          null);
              }
  
          }
  
          if (!i.getToString())
              ClassFabUtils.addToStringMethod(cf, StrategyMessages.toString(factoryParameters
                      .getServiceId(), serviceInterface));
  
          return cf.createClass();
      }
  
      private void addAdaptedMethod(ClassFab cf, MethodSignature sig)
      {
          String body = "return ($r) _getStrategy($1)." + sig.getName() + "($$);";
  
          cf.addMethod(Modifier.PUBLIC, sig, body);
      }
  
      /**
       * A "proper" method is one with at least one parameter and whose first parameter is an object
       * (not primitive) type.
       */
  
      private boolean proper(MethodSignature sig)
      {
          Class[] parameterTypes = sig.getParameterTypes();
  
          return parameterTypes != null && parameterTypes.length > 0
                  && !parameterTypes[0].isPrimitive();
      }
  
      public void setClassFactory(ClassFactory classFactory)
      {
          _classFactory = classFactory;
      }
  }
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/strategy/StrategyContribution.java
  
  Index: StrategyContribution.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  import org.apache.hivemind.impl.BaseLocatable;
  
  /**
   * Provides a mapping of subject class to strategy instance, used by
   * {@link org.apache.hivemind.lib.strategy.StrategyFactory}&nbsp; when building a service.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class StrategyContribution extends BaseLocatable
  {
      private Class _registerClass;
  
      private Object _strategy;
  
      public Object getStrategy()
      {
          return _strategy;
      }
  
      public void setStrategy(Object adaptor)
      {
          _strategy = adaptor;
      }
  
      public Class getRegisterClass()
      {
          return _registerClass;
      }
  
      public void setRegisterClass(Class registerClass)
      {
          _registerClass = registerClass;
      }
  }
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/strategy/StrategyStrings.properties
  
  Index: StrategyStrings.properties
  ===================================================================
  # Copyright 2004, 2005 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.
  
  strategy-wrong-interface=Strategy {0} (for class {1}) does not implement the {2} interface.
  improper-service-method=Method ''{0}'' is not suitable for use with the StrategyFactory; the first parameter should be an object type (used to select the strategy).
  to-string=<StrategyProxy for service {0}({1})>
  
  
  
  
  1.12      +1 -1      jakarta-hivemind/version.properties
  
  Index: version.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/version.properties,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- version.properties	22 Mar 2005 14:06:24 -0000	1.11
  +++ version.properties	30 Mar 2005 15:19:32 -0000	1.12
  @@ -12,4 +12,4 @@
   # See the License for the specific language governing permissions and
   # limitations under the License.
   
  -project.version=1.1-alpha-3
  \ No newline at end of file
  +project.version=1.1-alpha-4-snapshot
  \ No newline at end of file
  
  
  
  1.115     +2 -1      jakarta-hivemind/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/status.xml,v
  retrieving revision 1.114
  retrieving revision 1.115
  diff -u -r1.114 -r1.115
  --- status.xml	28 Mar 2005 01:10:34 -0000	1.114
  +++ status.xml	30 Mar 2005 15:19:32 -0000	1.115
  @@ -30,9 +30,10 @@
       </actions>
     </todo>
     <changes>
  -    <release version="1.1-alpha-4?" date="unreleased">
  +    <release version="1.1-alpha-4" date="unreleased">
         <action type="fix" dev="JC" fixes-bug="HIVEMIND-102" >Multiple interceptors with different names for the same interceptor factory id were treated as duplicates.</action>
         <action type="fix" dev="JC" fixes-bug="HIVEMIND-103" >Core service implementations which implement RegistryShutdownListener are not notified for primitive and singleton service models.</action>
  +      <action type="update" dev="HLS"> Rename AdapterRegistry to StrategyRegistry, and AdapterRegistryFactory to StrategyFactory, to better reflect the relationship to the Gang-of-Four Strategy pattern.</action>
       </release>
       <release version="1.1-alpha-3" date="Mar 22 2005">
         <action type="fix" dev="JC" fixes-bug="HIVEMIND-96" >Interceptors can now be ordered by name rather than interceptor factory id.</action>
  
  
  
  1.4       +2 -2      jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/UtilMessages.java
  
  Index: UtilMessages.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/UtilMessages.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- UtilMessages.java	5 Jan 2005 18:05:45 -0000	1.3
  +++ UtilMessages.java	30 Mar 2005 15:19:32 -0000	1.4
  @@ -32,8 +32,8 @@
                   .getJavaClassName(subjectClass));
       }
   
  -    public static String adapterNotFound(Class subjectClass)
  +    public static String strategyNotFound(Class subjectClass)
       {
  -        return _formatter.format("adapter-not-found", ClassFabUtils.getJavaClassName(subjectClass));
  +        return _formatter.format("strategy-not-found", ClassFabUtils.getJavaClassName(subjectClass));
       }
   }
  \ No newline at end of file
  
  
  
  1.4       +1 -1      jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/UtilStrings.properties
  
  Index: UtilStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/UtilStrings.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- UtilStrings.properties	6 Jan 2005 01:45:15 -0000	1.3
  +++ UtilStrings.properties	30 Mar 2005 15:19:32 -0000	1.4
  @@ -13,4 +13,4 @@
   # limitations under the License.
   
   duplicate-registration=A registration for class {0} already exists.
  -adapter-not-found=Could not find an adapter for class {0}.
  \ No newline at end of file
  +strategy-not-found=Could not find a strategy instance for class {0}.
  \ No newline at end of file
  
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/StrategyRegistry.java
  
  Index: StrategyRegistry.java
  ===================================================================
  // Copyright 2004, 2005 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.util;
  
  /**
   * An implementation of the <b>strategy </b> pattern. The strategy pattern allows new functionality
   * to be assigned to an existing class. As implemented here, this is a smart lookup between a
   * particular class (called the <em>subject class</em>) and some object instance that can provide
   * the extra functionality (called the <em>strategy</em>). The implementation of the strategy is
   * not relevant to the StrategyRegistry class.
   * <p>
   * Strategies are registered before they can be used; the registration maps a particular class to a
   * strategy instance. The strategy instance will be used when the subject class matches the
   * registered class, or the subject class inherits from the registered class.
   * <p>
   * This means that a search must be made that walks the inheritance tree (upwards from the subject
   * class) to find a registered mapping.
   * <p>
   * In addition, strategies can be registered against <em>interfaces</em>. Searching of interfaces
   * occurs after searching of classes. The exact order is:
   * <ul>
   * <li>Search for the subject class, then each super-class of the subject class (excluding
   * java.lang.Object)
   * <li>Search interfaces, starting with interfaces implemented by the subject class, continuing
   * with interfaces implemented by the super-classes, then interfaces extended by earlier interfaces
   * (the exact order is a bit fuzzy)
   * <li>Search for a match for java.lang.Object, if any
   * </ul>
   * <p>
   * The first match terminates the search.
   * <p>
   * The StrategyRegistry caches the results of search; a subsequent search for the same subject class
   * will be resolved immediately.
   * <p>
   * StrategyRegistry does a minor tweak of the "natural" inheritance. Normally, the parent class of
   * an object array (i.e., <code>Foo[]</code>) is simply <code>Object</code>, even though you
   * may assign <code>Foo[]</code> to a variable of type <code>Object[]</code>. StrategyRegistry
   * "fixes" this by searching for <code>Object[]</code> as if it was the superclass of any object
   * array. This means that the search path for <code>Foo[]</code> is <code>Foo[]</code>,
   * <code>Object[]</code>, then a couple of interfaces {@link java.lang.Cloneable},
   * {@link java.io.Serializable}, etc. that are implicitily implemented by arrays), and then,
   * finally, <code>Object</code>
   * <p>
   * This tweak doesn't apply to arrays of primitives, since such arrays may <em>not</em> be
   * assigned to <code>Object[]</code>.
   * 
   * @author Howard M. Lewis Ship
   * @see org.apache.hivemind.lib.util.StrategyRegistryImpl
   * @since 1.1
   */
  public interface StrategyRegistry
  {
      /**
       * Registers an adapter for a registration class.
       * 
       * @throws IllegalArgumentException
       *             if a strategy has already been registered for the given class.
       */
      public void register(Class registrationClass, Object strategy);
  
      /**
       * Gets the stategy object for the specified subjectClass.
       * 
       * @throws IllegalArgumentException
       *             if no strategy could be found.
       */
      public Object getStrategy(Class subjectClass);
  }
  
  
  1.1                  jakarta-hivemind/library/src/java/org/apache/hivemind/lib/util/StrategyRegistryImpl.java
  
  Index: StrategyRegistryImpl.java
  ===================================================================
  // Copyright 2004, 2005 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.util;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.Map;
  import java.util.WeakHashMap;
  
  import org.apache.hivemind.service.ClassFabUtils;
  import org.apache.hivemind.util.Defense;
  
  /**
   * Thread-safe implementation of {@link org.apache.hivemind.lib.util.StrategyRegistry}.
   * 
   * @author Howard Lewis Ship
   * @since 1.1
   */
  
  public class StrategyRegistryImpl implements StrategyRegistry
  {
      /**
       * A Map of adaptor objects, keyed on registration Class.
       */
  
      private Map _registrations = new HashMap();
  
      /**
       * A Map of adaptor objects, keyed on subject Class.
       */
  
      private Map _cache = new WeakHashMap();
  
      public synchronized void register(Class registrationClass, Object adaptor)
      {
          Defense.notNull(registrationClass, "registrationClass");
          Defense.notNull(adaptor, "adaptor");
  
          if (_registrations.containsKey(registrationClass))
              throw new IllegalArgumentException(UtilMessages
                      .duplicateRegistration(registrationClass));
  
          _registrations.put(registrationClass, adaptor);
  
          // Can't tell what is and isn't valid in the cache.
          // Also, normally all registrations occur before any adaptors
          // are searched for, so this is not a big deal.
  
          _cache.clear();
      }
  
      public synchronized Object getStrategy(Class subjectClass)
      {
          Defense.notNull(subjectClass, "subjectClass");
  
          Object result = _cache.get(subjectClass);
  
          if (result != null)
              return result;
  
          result = searchForAdaptor(subjectClass);
  
          // Record the result in the cache
  
          _cache.put(subjectClass, result);
  
          return result;
      }
  
      /**
       * Searches the registration Map for a match, based on inheritance.
       * <p>
       * Searches class inheritance first, then interfaces (in a rather vague order). Really should
       * match the order from the JVM spec.
       * <p>
       * There's a degenerate case where we may check the same interface more than once:
       * <ul>
       * <li>Two interfaces, I1 and I2
       * <li>Two classes, C1 and C2
       * <li>I2 extends I1
       * <li>C2 extends C1
       * <li>C1 implements I1
       * <li>C2 implements I2
       * <li>The search will be: C2, C1, I2, I1, I1
       * <li>I1 is searched twice, because C1 implements it, and I2 extends it
       * <li>There are other such cases, but none of them cause infinite loops and most are rare (we
       * could guard against it, but its relatively expensive).
       * <li>Multiple checks only occur if we don't find a registration
       * </ul>
       * <p>
       * This method is only called from a synchronized block, so it is implicitly synchronized.
       */
  
      private Object searchForAdaptor(Class subjectClass)
      {
          LinkedList queue = null;
          Object result = null;
  
          // Step one: work up through the class inheritance.
  
          Class searchClass = subjectClass;
  
          // Primitive types have null, not Object, as their parent
          // class.
  
          while (searchClass != Object.class && searchClass != null)
          {
              result = _registrations.get(searchClass);
              if (result != null)
                  return result;
  
              // Not an exact match. If the search class
              // implements any interfaces, add them to the queue.
  
              Class[] interfaces = searchClass.getInterfaces();
              int length = interfaces.length;
  
              if (queue == null && length > 0)
                  queue = new LinkedList();
  
              for (int i = 0; i < length; i++)
                  queue.addLast(interfaces[i]);
  
              // Advance up to the next superclass
  
              searchClass = getSuperclass(searchClass);
  
          }
  
          // Ok, the easy part failed, lets start searching
          // interfaces.
  
          if (queue != null)
          {
              while (!queue.isEmpty())
              {
                  searchClass = (Class) queue.removeFirst();
  
                  result = _registrations.get(searchClass);
                  if (result != null)
                      return result;
  
                  // Interfaces can extend other interfaces; add them
                  // to the queue.
  
                  Class[] interfaces = searchClass.getInterfaces();
                  int length = interfaces.length;
  
                  for (int i = 0; i < length; i++)
                      queue.addLast(interfaces[i]);
              }
          }
  
          // Not a match on interface; our last gasp is to check
          // for a registration for java.lang.Object
  
          result = _registrations.get(Object.class);
          if (result != null)
              return result;
  
          // No match? That's rare ... and an error.
  
          throw new IllegalArgumentException(UtilMessages.strategyNotFound(subjectClass));
      }
  
      /**
       * Returns the superclass of the given class, with a single tweak: If the search class is an
       * array class, and the component type is an object class (but not Object), then the simple
       * Object array class is returned. This reflects the fact that an array of any class may be
       * assignable to <code>Object[]</code>, even though the superclass of an array is always
       * simply <code>Object</code>.
       */
  
      private Class getSuperclass(Class searchClass)
      {
          if (searchClass.isArray())
          {
              Class componentType = searchClass.getComponentType();
  
              if (!componentType.isPrimitive() && componentType != Object.class)
                  return Object[].class;
          }
  
          return searchClass.getSuperclass();
      }
  
      public synchronized String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append("AdaptorRegistry[");
  
          Iterator i = _registrations.entrySet().iterator();
          boolean showSep = false;
  
          while (i.hasNext())
          {
              if (showSep)
                  buffer.append(' ');
  
              Map.Entry entry = (Map.Entry) i.next();
  
              Class registeredClass = (Class) entry.getKey();
  
              buffer.append(ClassFabUtils.getJavaClassName(registeredClass));
              buffer.append("=");
              buffer.append(entry.getValue());
  
              showSep = true;
          }
  
          buffer.append("]");
  
          return buffer.toString();
      }
  }
  
  
  1.44      +2 -2      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.43
  retrieving revision 1.44
  diff -u -r1.43 -r1.44
  --- site.xml	28 Feb 2005 12:42:01 -0000	1.43
  +++ site.xml	30 Mar 2005 15:19:32 -0000	1.44
  @@ -117,7 +117,6 @@
   		<index href="index.html"/>
   		
   		<services label="Services">
  -      <hivemind.lib.AdapterRegistryFactory label="AdapterRegistryFactory" href="AdapterRegistryFactory.html"/>
         <hivemind.lib.BeanFactoryBuilder label="BeanFactoryBuilder" href="BeanFactoryBuilder.html"/>
         <hivemind.lib.ChainBuilder label="ChainBuilder" href="ChainBuilder.html"/>
         <hivemind.lib.ChainFactory label="ChainFactory" href="ChainFactory.html"/>
  @@ -130,7 +129,8 @@
   			<hivemind.lib.RemoteExceptionCoordinator label="RemoteExceptionCoordinator" href="RemoteExceptionCoordinator.html"/>
         <hivemind.lib.ServicePropertyFactory label="ServicePropertyFactory" href="ServicePropertyFactory.html"/>
   			<hivemind.lib.SpringLookupFactory label="SpringLookupFactory" href="SpringLookupFactory.html"/>
  -		</services>	
  +      <hivemind.lib.StrategyFactory label="StrategyFactory" href="StrategyFactory.html"/>
  +  	</services>	
   		
   		<reports label="Reports">
   		&hivemind-lib-report-menu.ent;
  
  
  
  1.1                  jakarta-hivemind/library/src/test/org/apache/hivemind/lib/strategy/CatchAllToStringStrategy.java
  
  Index: CatchAllToStringStrategy.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  /**
   * Used by {@link org.apache.hivemind.lib.util.TestStrategyRegistry}'s integration test.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class CatchAllToStringStrategy implements ToStringStrategy
  {
  
      /**
       * Invokes {@link java.lang.Object#toString()}.
       */
  
      public String toString(Object o)
      {
          return o.toString();
      }
  
  }
  
  
  1.1                  jakarta-hivemind/library/src/test/org/apache/hivemind/lib/strategy/ToStringStrategy.java
  
  Index: ToStringStrategy.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  /**
   * Used by {@link org.apache.hivemind.lib.strategy.TestStrategyFactory}.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public interface ToStringStrategy
  {
      public String toString(Object o);
  }
  
  
  1.1                  jakarta-hivemind/library/src/test/org/apache/hivemind/lib/strategy/AdapterFactoryIntegration.xml
  
  Index: AdapterFactoryIntegration.xml
  ===================================================================
  <?xml version="1.0"?>
  <!-- 
     Copyright 2004, 2005 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" package="org.apache.hivemind.lib.strategy">
    
    <configuration-point id="ToStringStrategies" schema-id="hivemind.lib.StrategyRegistry"/>
    
    <contribution configuration-id="ToStringStrategies">
      
      <strategy class="java.lang.Object" object="instance:CatchAllToStringStrategy"/>
      
    </contribution>
    
    <service-point id="ToStringStrategy" interface="ToStringStrategy">
      <invoke-factory service-id="hivemind.lib.StrategyFactory">
        <construct configuration-id="ToStringStrategies"/>
      </invoke-factory>
    </service-point>
    
  </module>
  
  
  1.1                  jakarta-hivemind/library/src/test/org/apache/hivemind/lib/strategy/TestStrategyFactory.java
  
  Index: TestStrategyFactory.java
  ===================================================================
  // Copyright 2004, 2005 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.strategy;
  
  import java.lang.reflect.Modifier;
  import java.util.Collections;
  import java.util.List;
  
  import org.apache.hivemind.ErrorLog;
  import org.apache.hivemind.Location;
  import org.apache.hivemind.Registry;
  import org.apache.hivemind.ServiceImplementationFactoryParameters;
  import org.apache.hivemind.lib.strategy.StrategyContribution;
  import org.apache.hivemind.lib.strategy.StrategyMessages;
  import org.apache.hivemind.lib.strategy.StrategyParameter;
  import org.apache.hivemind.lib.strategy.StrategyFactory;
  import org.apache.hivemind.lib.util.StrategyRegistry;
  import org.apache.hivemind.service.ClassFab;
  import org.apache.hivemind.service.ClassFabUtils;
  import org.apache.hivemind.service.ClassFactory;
  import org.apache.hivemind.service.MethodFab;
  import org.apache.hivemind.service.MethodSignature;
  import org.apache.hivemind.test.AggregateArgumentsMatcher;
  import org.apache.hivemind.test.ArgumentMatcher;
  import org.apache.hivemind.test.ArrayMatcher;
  import org.apache.hivemind.test.HiveMindTestCase;
  import org.apache.hivemind.test.TypeMatcher;
  import org.easymock.MockControl;
  
  /**
   * Test for the {@link org.apache.hivemind.lib.strategy.StrategyFactory}service
   * implementation factory.
   * 
   * @author Howard M. Lewis Ship
   * @since 1.1
   */
  public class TestStrategyFactory extends HiveMindTestCase
  {
      private List buildContributions(Class registerClass, Object adapter, Location location)
      {
          StrategyContribution c = new StrategyContribution();
  
          c.setRegisterClass(registerClass);
          c.setStrategy(adapter);
          c.setLocation(location);
  
          return Collections.singletonList(c);
      }
  
      private StrategyParameter buildParameter(Class registerClass, Object adapter,
              Location contributionLocation, Location parameterLocation)
      {
          StrategyParameter result = new StrategyParameter();
  
          result.setContributions(buildContributions(registerClass, adapter, contributionLocation));
          result.setLocation(parameterLocation);
  
          return result;
      }
  
      private StrategyParameter buildParameter(Class registerClass, Object adapter)
      {
          return buildParameter(registerClass, adapter, null, null);
      }
  
      public void testBuildRegistry()
      {
          StrategyRegistry ar = (StrategyRegistry) newMock(StrategyRegistry.class);
          ToStringStrategy adapter = (ToStringStrategy) newMock(ToStringStrategy.class);
  
          MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
          ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters) fpc
                  .getMock();
  
          fp.getServiceInterface();
          fpc.setReturnValue(ToStringStrategy.class);
  
          StrategyParameter p = buildParameter(Number.class, adapter);
  
          fp.getFirstParameter();
          fpc.setReturnValue(p);
  
          ar.register(Number.class, adapter);
  
          replayControls();
  
          new StrategyFactory().buildRegistry(fp, ar);
  
          verifyControls();
      }
  
      public void testBuildRegistryWrongAdapterType()
      {
          Location l = fabricateLocation(3);
  
          StrategyRegistry ar = (StrategyRegistry) newMock(StrategyRegistry.class);
          ToStringStrategy adapter = (ToStringStrategy) newMock(ToStringStrategy.class);
  
          MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
          ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters) fpc
                  .getMock();
  
          MockControl logc = newControl(ErrorLog.class);
          ErrorLog log = (ErrorLog) logc.getMock();
  
          fp.getServiceInterface();
          fpc.setReturnValue(Runnable.class);
  
          StrategyParameter p = buildParameter(Number.class, adapter, l, null);
  
          fp.getFirstParameter();
          fpc.setReturnValue(p);
  
          fp.getErrorLog();
          fpc.setReturnValue(log);
  
          log.error(
                  StrategyMessages.strategyWrongInterface(adapter, Number.class, Runnable.class),
                  l,
                  new ClassCastException());
          logc.setMatcher(new AggregateArgumentsMatcher(new ArgumentMatcher[]
          { null, null, new TypeMatcher() }));
  
          replayControls();
  
          new StrategyFactory().buildRegistry(fp, ar);
  
          verifyControls();
      }
  
      public void testBuildImplementationClass()
      {
          MockControl factoryControl = newControl(ClassFactory.class);
          ClassFactory factory = (ClassFactory) factoryControl.getMock();
  
          MockControl cfc = newControl(ClassFab.class);
          ClassFab cf = (ClassFab) cfc.getMock();
  
          MethodFab mf = (MethodFab) newMock(MethodFab.class);
  
          MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
          ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters) fpc
                  .getMock();
  
          fp.getServiceInterface();
          fpc.setReturnValue(ToStringStrategy.class);
  
          factory.newClass("NewClass", Object.class);
          factoryControl.setReturnValue(cf);
  
          cf.addInterface(ToStringStrategy.class);
          cf.addField("_registry", StrategyRegistry.class);
  
          cf.addConstructor(new Class[]
          { StrategyRegistry.class }, null, "_registry = $1;");
          cfc.setMatcher(new AggregateArgumentsMatcher(new ArrayMatcher()));
  
          cf
                  .addMethod(
                          Modifier.PRIVATE,
                          new MethodSignature(ToStringStrategy.class, "_getStrategy", new Class[]
                          { Object.class }, null),
                          "return (org.apache.hivemind.lib.strategy.ToStringStrategy) _registry.getStrategy($1.getClass());");
          cfc.setReturnValue(mf);
  
          cf.addMethod(Modifier.PUBLIC, new MethodSignature(String.class, "toString", new Class[]
          { Object.class }, null), "return ($r) _getStrategy($1).toString($$);");
          cfc.setReturnValue(mf);
  
          fp.getServiceId();
          fpc.setReturnValue("foo.Bar");
  
          ClassFabUtils.addToStringMethod(cf, StrategyMessages.toString(
                  "foo.Bar",
                  ToStringStrategy.class));
          cfc.setReturnValue(mf);
  
          cf.createClass();
          cfc.setReturnValue(String.class);
  
          replayControls();
  
          StrategyFactory f = new StrategyFactory();
          f.setClassFactory(factory);
  
          f.buildImplementationClass(fp, "NewClass");
  
          verifyControls();
      }
  
      public void testBuildImplementationClassImproperMethod()
      {
          Location l = fabricateLocation(31);
  
          MockControl factoryControl = newControl(ClassFactory.class);
          ClassFactory factory = (ClassFactory) factoryControl.getMock();
  
          MockControl cfc = newControl(ClassFab.class);
          ClassFab cf = (ClassFab) cfc.getMock();
  
          MethodFab mf = (MethodFab) newMock(MethodFab.class);
  
          MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
          ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters) fpc
                  .getMock();
  
          ErrorLog log = (ErrorLog) newMock(ErrorLog.class);
  
          fp.getServiceInterface();
          fpc.setReturnValue(Runnable.class);
  
          factory.newClass("NewClass", Object.class);
          factoryControl.setReturnValue(cf);
  
          cf.addInterface(Runnable.class);
          cf.addField("_registry", StrategyRegistry.class);
  
          cf.addConstructor(new Class[]
          { StrategyRegistry.class }, null, "_registry = $1;");
          cfc.setMatcher(new AggregateArgumentsMatcher(new ArrayMatcher()));
  
          cf.addMethod(
                  Modifier.PRIVATE,
                  new MethodSignature(Runnable.class, "_getStrategy", new Class[]
                  { Object.class }, null),
                  "return (java.lang.Runnable) _registry.getStrategy($1.getClass());");
          cfc.setReturnValue(mf);
  
          MethodSignature sig = new MethodSignature(void.class, "run", null, null);
  
          cf.addMethod(Modifier.PUBLIC, sig, "{  }");
          cfc.setReturnValue(mf);
  
          fp.getErrorLog();
          fpc.setReturnValue(log);
  
          fp.getFirstParameter();
          // Slight fudge: we return the location itself when we should return
          // an object with this location.
          fpc.setReturnValue(l);
  
          log.error(StrategyMessages.improperServiceMethod(sig), l, null);
  
          fp.getServiceId();
          fpc.setReturnValue("foo.Bar");
  
          ClassFabUtils.addToStringMethod(cf, StrategyMessages.toString("foo.Bar", Runnable.class));
          cfc.setReturnValue(mf);
  
          cf.createClass();
  
          cfc.setReturnValue(String.class);
  
          replayControls();
  
          StrategyFactory f = new StrategyFactory();
          f.setClassFactory(factory);
  
          f.buildImplementationClass(fp, "NewClass");
  
          verifyControls();
      }
  
      public void testIntegration() throws Exception
      {
          Registry r = buildFrameworkRegistry("AdapterFactoryIntegration.xml");
  
          ToStringStrategy ts = (ToStringStrategy) r.getService(ToStringStrategy.class);
  
          assertEquals("5150", ts.toString(new Integer(5150)));
      }
  }
  
  
  1.24      +16 -16    jakarta-hivemind/library/src/descriptor/META-INF/hivemodule.xml
  
  Index: hivemodule.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/library/src/descriptor/META-INF/hivemodule.xml,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- hivemodule.xml	28 Feb 2005 12:42:33 -0000	1.23
  +++ hivemodule.xml	30 Mar 2005 15:19:32 -0000	1.24
  @@ -323,38 +323,38 @@
     </service-point>
     
     
  -  <schema id="AdapterRegistry">
  +  <schema id="StrategyRegistry">
       
  -    Used with the hivemind.lib.AdapterRegistryFactory to define a set of classes and corresponding
  -    adapters.
  +    Used with the hivemind.lib.StrategyFactory to define a set of classes and corresponding
  +    strategies
       
  -    <element name="adapter">
  +    <element name="strategy">
         
         <attribute name="class" translator="class" required="true">
  -        The class (or interface) to register the adapter against.
  +        The class (or interface) to register the stategy against.
         </attribute>
         
         <attribute name="object" translator="object" required="true">
  -        The adapter that corresponds to objects of the given class.
  +        The stategy instance that corresponds to objects of the given class.
         </attribute>
         
  -      <conversion class="adapter.AdapterRegistryContribution">
  +      <conversion class="strategy.StrategyContribution">
           <map attribute="class" property="registerClass"/>
  -        <map attribute="object" property="adapter"/>
  +        <map attribute="object" property="strategy"/>
         </conversion>
         
       </element>
       
     </schema>
     
  -  <service-point id="AdapterRegistryFactory" interface="org.apache.hivemind.ServiceImplementationFactory">
  +  <service-point id="StrategyFactory" interface="org.apache.hivemind.ServiceImplementationFactory">
       
  -    Creates a service as a wrapper around an AdapterRegistry.  The first parameter to
  -    each method of the service interface is used to select an adapter, and then
  -    the method implementation delegates to that adapter.
  +    Creates a service as a wrapper around a StrategyRegistry.  The first parameter to
  +    each method of the service interface is used to select a strategy instance, and then
  +    the method implementation delegates to that instance.
       
       <invoke-factory>
  -      <construct class="adapter.AdapterRegistryFactory">
  +      <construct class="strategy.StrategyFactory">
           <set-service property="classFactory" service-id="hivemind.ClassFactory"/>
         </construct>
       </invoke-factory>
  @@ -362,11 +362,11 @@
       <parameters-schema>
         <element name="construct">
           <attribute name="configuration-id" translator="configuration" required="true">
  -          A configuration utilizing the hivemind.lib.AdapterRegistry schema, which
  -          defines the classes and matching adapters.
  +          A configuration utilizing the hivemind.lib.StrategyRegistry schema, which
  +          defines the classes and matching strategies.
           </attribute>
           
  -        <conversion class="adapter.AdapterRegistryParameter">
  +        <conversion class="strategy.StrategyParameter">
             <map attribute="configuration-id" property="contributions"/>
           </conversion>
         </element>
  
  
  

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