hivemind-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From k...@apache.org
Subject cvs commit: jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl ServiceMessages.java BuilderFactory.java BuilderFactoryLogic.java ServiceStrings.properties
Date Tue, 09 Nov 2004 11:24:30 GMT
knut        2004/11/09 03:24:30

  Modified:    framework/src/test/hivemind/test/services
                        TestBuilderFactory.java ConstructorFactory.xml
               framework/src/documentation/content/xdocs/hivemind
                        BuilderFactory.xml
               .        status.xml
               framework/src/java/org/apache/hivemind/util
                        ConstructorUtils.java
               framework/src/java/org/apache/hivemind/service/impl
                        ServiceMessages.java BuilderFactory.java
                        BuilderFactoryLogic.java ServiceStrings.properties
  Added:       framework/src/test/hivemind/test/services
                        ConstructorAutowireTarget.java
  Log:
  added support for autowiring through constructor based dependency injection
  
  Revision  Changes    Path
  1.19      +111 -6    jakarta-hivemind/framework/src/test/hivemind/test/services/TestBuilderFactory.java
  
  Index: TestBuilderFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/services/TestBuilderFactory.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- TestBuilderFactory.java	2 Nov 2004 17:46:10 -0000	1.18
  +++ TestBuilderFactory.java	9 Nov 2004 11:24:29 -0000	1.19
  @@ -16,10 +16,7 @@
   
   import hivemind.test.services.impl.StringHolderImpl;
   
  -import java.util.Collections;
  -
   import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
   import org.apache.hivemind.ApplicationRuntimeException;
   import org.apache.hivemind.ClassResolver;
   import org.apache.hivemind.ErrorHandler;
  @@ -28,13 +25,11 @@
   import org.apache.hivemind.Registry;
   import org.apache.hivemind.ServiceImplementationFactoryParameters;
   import org.apache.hivemind.impl.DefaultClassResolver;
  -import org.apache.hivemind.impl.DefaultErrorHandler;
   import org.apache.hivemind.internal.Module;
   import org.apache.hivemind.service.impl.BuilderClassResolverFacet;
   import org.apache.hivemind.service.impl.BuilderErrorHandlerFacet;
   import org.apache.hivemind.service.impl.BuilderErrorLogFacet;
   import org.apache.hivemind.service.impl.BuilderFacet;
  -import org.apache.hivemind.service.impl.BuilderFactory;
   import org.apache.hivemind.service.impl.BuilderFactoryLogic;
   import org.apache.hivemind.service.impl.BuilderLogFacet;
   import org.apache.hivemind.service.impl.BuilderMessagesFacet;
  @@ -42,8 +37,8 @@
   import org.apache.hivemind.service.impl.BuilderServiceIdFacet;
   import org.apache.hivemind.test.AggregateArgumentsMatcher;
   import org.apache.hivemind.test.ArgumentMatcher;
  -import org.apache.hivemind.test.TypeMatcher;
   import org.apache.hivemind.test.HiveMindTestCase;
  +import org.apache.hivemind.test.TypeMatcher;
   import org.easymock.MockControl;
   
   /**
  @@ -474,6 +469,116 @@
           ServiceAutowireTarget service = (ServiceAutowireTarget) execute(fp, parameter);
   
           assertNull(service.getStringHolder());
  +
  +        verifyControls();
  +    }
  +
  +    public void testAutowireConstructor() throws Exception
  +    {
  +        MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
  +        ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters)
fpc
  +                .getMock();
  +
  +        MockControl mc = newControl(Module.class);
  +        Module module = (Module) mc.getMock();
  +
  +        MockControl lc = newControl(Log.class);
  +        Log log = (Log) lc.getMock();
  +
  +        fp.getLog();
  +        fpc.setReturnValue(log);
  +
  +        fp.getServiceId();
  +        fpc.setReturnValue("foo");
  +
  +        fp.getInvokingModule();
  +        fpc.setReturnValue(module, MockControl.ONE_OR_MORE);
  +
  +        ClassResolver classResolver = new DefaultClassResolver();
  +
  +        module.getClassResolver();
  +        mc.setReturnValue(classResolver);
  +
  +        StringHolder h = new StringHolderImpl();
  +
  +        module.getService(Comparable.class);
  +        mc.setThrowable(new ApplicationRuntimeException("Failure."));
  +
  +        module.getService(StringHolder.class);
  +        mc.setReturnValue(h);
  +
  +        module.getClassResolver();
  +        mc.setReturnValue(classResolver);
  +
  +        replayControls();
  +
  +        BuilderParameter parameter = new BuilderParameter();
  +
  +        parameter.setClassName(ConstructorAutowireTarget.class.getName());
  +        parameter.setAutowireServices(true);
  +
  +        ConstructorAutowireTarget service = (ConstructorAutowireTarget) execute(fp, parameter);
  +
  +        assertSame(h, service.getStringHolder());
  +        assertSame(classResolver, service.getClassResolver());
  +
  +        verifyControls();
  +    }
  +
  +    public void testAutowireConstructorFailure() throws Exception
  +    {
  +        MockControl fpc = newControl(ServiceImplementationFactoryParameters.class);
  +        ServiceImplementationFactoryParameters fp = (ServiceImplementationFactoryParameters)
fpc
  +                .getMock();
  +
  +        MockControl mc = newControl(Module.class);
  +        Module module = (Module) mc.getMock();
  +
  +        MockControl elc = newControl(ErrorLog.class);
  +        ErrorLog el = (ErrorLog) elc.getMock();
  +
  +        MockControl lc = newControl(Log.class);
  +        Log log = (Log) lc.getMock();
  +
  +        fp.getLog();
  +        fpc.setReturnValue(log);
  +
  +        fp.getServiceId();
  +        fpc.setReturnValue("foo");
  +
  +        fp.getInvokingModule();
  +        fpc.setReturnValue(module, MockControl.ONE_OR_MORE);
  +
  +        ClassResolver classResolver = new DefaultClassResolver();
  +
  +        module.getClassResolver();
  +        mc.setReturnValue(classResolver);
  +
  +        module.getService(Comparable.class);
  +        mc.setThrowable(new ApplicationRuntimeException("Failure."));
  +
  +        module.getService(StringHolder.class);
  +        mc.setThrowable(new ApplicationRuntimeException("Failure."), 2);
  +
  +        fp.getErrorLog();
  +        fpc.setReturnValue(el);
  +
  +        el.error(
  +                "Error building service foo: Unable to find constructor applicable for
autowiring. "
  +                        + "Use explicit constructor parameters.",
  +                null,
  +                new ApplicationRuntimeException(""));
  +        elc.setMatcher(new AggregateArgumentsMatcher(new ArgumentMatcher[]
  +        { null, null, new TypeMatcher() }));
  +
  +        replayControls();
  +
  +        BuilderParameter parameter = new BuilderParameter();
  +
  +        parameter.setClassName(ConstructorAutowireTarget.class.getName());
  +        parameter.setAutowireServices(true);
  +
  +        ConstructorAutowireTarget service = (ConstructorAutowireTarget) execute(fp, parameter);
   
           verifyControls();
       }
  
  
  
  1.4       +1 -1      jakarta-hivemind/framework/src/test/hivemind/test/services/ConstructorFactory.xml
  
  Index: ConstructorFactory.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/test/hivemind/test/services/ConstructorFactory.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ConstructorFactory.xml	1 Oct 2004 21:34:05 -0000	1.3
  +++ ConstructorFactory.xml	9 Nov 2004 11:24:29 -0000	1.4
  @@ -3,7 +3,7 @@
   
     <service-point id="DefaultConstructor" interface="hivemind.test.services.ConstructorAccess">
     	<invoke-factory>
  -  		<construct class="hivemind.test.services.impl.ConstructorAccessImpl">
  +  		<construct class="hivemind.test.services.impl.ConstructorAccessImpl" autowire-services="false">
     			<set property="expectedConstructorMessage" value="()"/>
     		</construct>
     	</invoke-factory>	
  
  
  
  1.1                  jakarta-hivemind/framework/src/test/hivemind/test/services/ConstructorAutowireTarget.java
  
  Index: ConstructorAutowireTarget.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 hivemind.test.services;
  
  import java.io.Serializable;
  import java.util.List;
  import java.util.Set;
  
  import org.apache.hivemind.ClassResolver;
  import org.apache.hivemind.impl.DefaultClassResolver;
  
  /**
   * Used to test autowiring of constructor parameters by the BuilderFactory.
   * 
   * @author Knut Wannheden
   */
  public class ConstructorAutowireTarget
  {
      private StringHolder _stringHolder;
  
      private ClassResolver _classResolver;
  
      public ConstructorAutowireTarget(StringHolder holder)
      {
          this(holder, new DefaultClassResolver());
      }
  
      public ConstructorAutowireTarget(StringHolder holder, ClassResolver classResolver)
      {
          _stringHolder = holder;
          _classResolver = classResolver;
      }
  
      public ConstructorAutowireTarget(int dummy)
      {
      }
  
      public ConstructorAutowireTarget(Serializable dummy1, Serializable dummy2, Serializable
dummy3)
      {
      }
  
      public ConstructorAutowireTarget(Comparable dummy1, List dummy2, Set dummy3)
      {
      }
  
      public StringHolder getStringHolder()
      {
          return _stringHolder;
      }
  
      public ClassResolver getClassResolver()
      {
          return _classResolver;
      }
  }
  
  
  1.14      +56 -24    jakarta-hivemind/framework/src/documentation/content/xdocs/hivemind/BuilderFactory.xml
  
  Index: BuilderFactory.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/documentation/content/xdocs/hivemind/BuilderFactory.xml,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- BuilderFactory.xml	2 Nov 2004 17:46:08 -0000	1.13
  +++ BuilderFactory.xml	9 Nov 2004 11:24:29 -0000	1.14
  @@ -68,7 +68,7 @@
        property dependency injection. Many of the options are rarely used; the most general
purpose
        and most frequently used are <link href="#set">set</link>, <link href="#set-object">set-object</link>
        and <link href="#event-listener">event-listener</link> (along with
  -     <link href="#Autowiring">autowiring of certain properties</link>).
  +     <link href="#Autowiring">autowiring</link>).
         </note>
         
   		<section>
  @@ -83,7 +83,8 @@
             <td>autowire-services</td>
             <td>no</td>
             <td>If true (the default), then the BuilderFactory will attempt to
  -            automatically wire any services that are not otherwise set (see notes below).
  +            automatically wire services and some common properties to constructor parameters

  +            and to properties of the constructed implementation with a setter methods (see
notes below).
               </td>
           </tr>
   				<tr>
  @@ -120,7 +121,7 @@
   					<td>The name of a property which will be assigned a <code>
   						org.apache.commons.logging.Log</code> instance for the service. The
   						Log is created from the complete service id (not the name of the
  -						class). If ommitted, no Log will be assigned.</td>
  +						class). If ommitted (and autowiring is disabled), no Log will be assigned.</td>
   				</tr>
   				<tr>
   					<td>messages-property</td>
  @@ -144,17 +145,18 @@
         <title>Autowiring</title>
         
         <p>
  -        BuilderFactory will automatically set certain common properties of the service
implementation.
  -        By using standard names (and standard types), the need to specify
  -        attributes <code>log-property</code>, <code>error-handler-property</code>,
etc. is avoided.
  -        Simply by having a writable property with the correct name and type is sufficient:
  -        
  +        With <code>autowire-services</code> set to true the BuilderFactory
can automatically both perform
  +        constructor based and setter based dependency injection.  It will not only attempt
to inject 
  +        services but also certain common properties.  By using standard names (and standard
types), 
  +        the need to specify attributes <code>log-property</code>, <code>error-handler-property</code>,

  +        etc. is avoided.  Simply declaring a constructor parameter with the correct type
<em>or</em> a 
  +        writable property with the correct name <em>and</em> type is sufficient:
         </p>
         
         <table>
           <tr>
             <th>Property name</th>
  -          <th>Property Type</th>
  +          <th>Property / parameter type</th>
           </tr>
           <tr>
             <td>classResolver</td>
  @@ -177,6 +179,7 @@
           <tr>
             <td>messages</td>
             <td>&api.Messages;</td>
  +          <td/>
           </tr>
           <tr>
             <td>serviceId</td>
  @@ -184,29 +187,58 @@
           </tr>
         </table>
         
  +      <note>
  +        The service id (last entry in above table) will <em>only</em> be automatically
injected through a writable property
  +        (i.e. <code>setServiceId(String)</code>).  This because a constructor
parameter of type String
  +        is far too common.
  +      </note>
  +      
         <p>
  -        After wiring the above properties, and processing all the service property configuring
elements, BuilderFactory may
  -        autowire service properties. For each writable property, whose property type is
an interface, and which has not otherwise been set,
  -        HiveMind will search for a service which implements the exact interface. If one
and only one service implements the interface,
  -        then BuilderFactory will inject that service into the property.
  +        As noted the BuilderFactory will also inject services into the constructed service
implementation. 
  +        Through every constructor parameter and writable property whose type is an interface
(with the exception 
  +        of the common parameters / properties listed above) and hasn't been set otherwise
the BuilderFactory will 
  +        attempt to inject a service.  This attempt may fail if there is <em>no</em>
visible service or <em>more than 
  +        one</em> visible service implementing the given interface.  (Visibility is
checked with respect to the module 
  +        declaring the constructed service's implementation.)
         </p>
         
         <p>
  -       If no services implement the interface, or more than one does, then an error will
be logged.  BuilderFactory
  -       accounts for <em>visibility</em> of the other services relative to the
module that contains the service's core implementation.
  +        The action taken if the service injection fails (due to one of the reasons given
above) depends on the type 
  +        of dependency injection.  For constructor based dependency injection the BuilderFactory
will try using a 
  +        different constructor (see selection details below).  If no &quot;working&quot;
constructor is found an error 
  +        is logged.  For setter based dependency injection the BuilderFactory will log an
error imedeately upon failed injection.
         </p>
         
         <p>
  +        Constructor based dependency injection is enabled with the <code>autowire-services</code>
attribute but can be 
  +        overridden by declaring any constructor parameter elements (see next section).
 The constructor being used for
  +        the constructor based dependency injection has to meet all of the following criteria:
  +      </p>
  +
  +      <ul>
  +        <li>the constructor is declared as <code>public</code></li>
  +        <li>all parameter types are interfaces (including the common types listed
above)</li>
  +        <li>no two parameters are of the same type</li>
  +      </ul>
  +
  +      <p>
  +        All constructors of the service implementation class meeting these criteria (the
default constructor is 
  +        considered as one of these) are ordered by length (given by the number of parameters)
and the first of these for which 
  +        every parameter type either has a matching common property or there is exactly
one corresponding visible service 
  +        available will be invoked.  If no such constructor can be found an error is logged.
  +      </p>
  +
  +      <p>
           Autowiring may be  complicated by the fact that one module may define a service
point that will tangentially affect the
  -        construction of a service in
  -        another module (simply by implementing the same service interface).  In this situation,
service autowiring can be turned off, by setting the
  -        <code>autowire-services</code> attribute to false.
  +        construction of a service in another module (simply by implementing the same service
interface).  In this situation, 
  +        service autowiring can be turned off, by setting the <code>autowire-services</code>
attribute to false.
         </p>
         
         <p>
  -       Once all properties have been set (possibly by autowiring), an initializer method
will be invoked.  If the <code>initialize-method</code> attribute is <em>not</em>
specified,
  -        and the service implementation includes a public method <code>initializeService()</code>
(no parameters,
  -        returns void), then <code>initializeService()</code> will be invoked
as the initializer.
  +       Once all properties have been set (possibly by autowiring), an initializer method
will be invoked.  If the 
  +       <code>initialize-method</code> attribute is <em>not</em>
specified, and the service implementation includes a 
  +       public method <code>initializeService()</code> (no parameters, returns
void), then <code>initializeService()</code> 
  +       will be invoked as the initializer.
         </p>
         
       </section>
  @@ -398,9 +430,9 @@
               </tr>
               <tr>
                 <td>value</td>
  -              <td>The <em>selector</em> used to find an object value.
 The selector consists of a prefix (such as "service" or "configuration"), a colon,
  -                and a <em>locator</em> whose interpretation is defined by the
prefix.  For example,
  -                <code>service:MyService</code>.  See &hivemind.ObjectProviders;.</td>
  +              <td>The <em>selector</em> used to find an object value.
 The selector consists of a prefix (such as 
  +                "service" or "configuration"), a colon, and a <em>locator</em>
whose interpretation is defined by 
  +                the prefix.  For example, <code>service:MyService</code>. 
See &hivemind.ObjectProviders;.</td>
               </tr>
             </table>
         </section>
  
  
  
  1.78      +5 -1      jakarta-hivemind/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/status.xml,v
  retrieving revision 1.77
  retrieving revision 1.78
  diff -u -r1.77 -r1.78
  --- status.xml	8 Nov 2004 14:14:25 -0000	1.77
  +++ status.xml	9 Nov 2004 11:24:29 -0000	1.78
  @@ -89,7 +89,11 @@
           Add the hivemind.lib.AdapterRegistryFactory service implementation factory.
         </action>
         <action type="update" dev="HLS"> Removed the module parameter from ClassFactory.newClass()
and from 
  -        DefaultImplementationBuilder.buildDefaultImplementation(). </action>
  +        DefaultImplementationBuilder.buildDefaultImplementation().
  +      </action>
  +      <action type="update" dev="KW">
  +        BuilderFactory now supports autowiring through constructor based dependency injection.
  +      </action>
       </release>
   
      <release version="1.0" date="Sep 22 2004">
  
  
  
  1.6       +1 -1      jakarta-hivemind/framework/src/java/org/apache/hivemind/util/ConstructorUtils.java
  
  Index: ConstructorUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/util/ConstructorUtils.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ConstructorUtils.java	1 Oct 2004 21:34:05 -0000	1.5
  +++ ConstructorUtils.java	9 Nov 2004 11:24:29 -0000	1.6
  @@ -129,7 +129,7 @@
           return false;
       }
   
  -    private static Object invoke(Constructor c, Object[] parameters)
  +    public static Object invoke(Constructor c, Object[] parameters)
       {
           try
           {
  
  
  
  1.14      +5 -0      jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/ServiceMessages.java
  
  Index: ServiceMessages.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/ServiceMessages.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ServiceMessages.java	27 Sep 2004 14:36:50 -0000	1.13
  +++ ServiceMessages.java	9 Nov 2004 11:24:29 -0000	1.14
  @@ -190,4 +190,9 @@
       {
           return _formatter.format("autowire-property-failure", propertyName, serviceId,
cause);
       }
  +
  +    public static String unableToFindAutowireConstructor()
  +    {
  +        return _formatter.getMessage("unable-to-find-autowire-constructor");
  +    }
   }
  
  
  
  1.18      +1 -5      jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/BuilderFactory.java
  
  Index: BuilderFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/BuilderFactory.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- BuilderFactory.java	2 Nov 2004 17:46:09 -0000	1.17
  +++ BuilderFactory.java	9 Nov 2004 11:24:29 -0000	1.18
  @@ -14,12 +14,8 @@
   
   package org.apache.hivemind.service.impl;
   
  -import java.util.List;
  -
  -import org.apache.commons.logging.Log;
   import org.apache.hivemind.ServiceImplementationFactory;
   import org.apache.hivemind.ServiceImplementationFactoryParameters;
  -import org.apache.hivemind.internal.Module;
   
   /**
    * Implementation of {@link org.apache.hivemind.ServiceImplementationFactory}that can instantiate
  @@ -39,7 +35,7 @@
       public Object createCoreServiceImplementation(
               ServiceImplementationFactoryParameters factoryParameters)
       {
  -        BuilderParameter parameter = (BuilderParameter) factoryParameters.getParameters().get(0);
  +        BuilderParameter parameter = (BuilderParameter) factoryParameters.getFirstParameter();
   
           BuilderFactoryLogic logic = new BuilderFactoryLogic(factoryParameters, parameter);
   
  
  
  
  1.7       +103 -8    jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/BuilderFactoryLogic.java
  
  Index: BuilderFactoryLogic.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/BuilderFactoryLogic.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BuilderFactoryLogic.java	2 Nov 2004 17:46:09 -0000	1.6
  +++ BuilderFactoryLogic.java	9 Nov 2004 11:24:30 -0000	1.7
  @@ -14,20 +14,27 @@
   
   package org.apache.hivemind.service.impl;
   
  +import java.lang.reflect.Constructor;
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
  +import java.lang.reflect.Modifier;
  +import java.util.ArrayList;
   import java.util.Collection;
  +import java.util.Collections;
  +import java.util.Comparator;
   import java.util.HashSet;
   import java.util.Iterator;
   import java.util.List;
   import java.util.Set;
   
   import org.apache.commons.logging.Log;
  +import org.apache.hivemind.ApplicationRuntimeException;
   import org.apache.hivemind.ClassResolver;
  -import org.apache.hivemind.Defense;
   import org.apache.hivemind.ErrorHandler;
  +import org.apache.hivemind.ErrorLog;
   import org.apache.hivemind.HiveMind;
   import org.apache.hivemind.Location;
  +import org.apache.hivemind.Messages;
   import org.apache.hivemind.ServiceImplementationFactoryParameters;
   import org.apache.hivemind.internal.Module;
   import org.apache.hivemind.service.EventLinker;
  @@ -99,19 +106,24 @@
           ClassResolver resolver = _contributingModule.getClassResolver();
           Class serviceClass = resolver.findClass(_parameter.getClassName());
   
  -        Object[] constructorParameters = buildConstructorParameters();
  +        List parameters = _parameter.getParameters();
  +
  +        if (_parameter.getAutowireServices() && parameters.isEmpty())
  +        {
  +            return instantiateConstructorAutowiredInstance(serviceClass);
  +        }
  +        else
  +        {
  +            Object[] constructorParameters = buildConstructorParameters(parameters);
   
  -        return ConstructorUtils.invokeConstructor(serviceClass, constructorParameters);
  +            return ConstructorUtils.invokeConstructor(serviceClass, constructorParameters);
  +        }
       }
   
  -    private Object[] buildConstructorParameters()
  +    private Object[] buildConstructorParameters(List parameters)
       {
  -        List parameters = _parameter.getParameters();
           int count = parameters.size();
   
  -        if (count == 0)
  -            return null;
  -
           Object[] result = new Object[count];
   
           for (int i = 0; i < count; i++)
  @@ -131,6 +143,89 @@
           }
   
           return result;
  +    }
  +
  +    private Object instantiateConstructorAutowiredInstance(Class serviceClass)
  +    {
  +        List serviceConstructorCandidates = getOrderedServiceConstructors(serviceClass);
  +
  +        outer: for (Iterator candidates = serviceConstructorCandidates.iterator(); candidates
  +                .hasNext();)
  +        {
  +            Constructor candidate = (Constructor) candidates.next();
  +
  +            Class[] parameterTypes = candidate.getParameterTypes();
  +
  +            Object[] parameters = new Object[parameterTypes.length];
  +
  +            for (int i = 0; i < parameters.length; i++)
  +                if (parameterTypes[i] == ClassResolver.class)
  +                    parameters[i] = _factoryParameters.getInvokingModule().getClassResolver();
  +                else if (parameterTypes[i] == ErrorHandler.class)
  +                    parameters[i] = _factoryParameters.getInvokingModule().getErrorHandler();
  +                else if (parameterTypes[i] == ErrorLog.class)
  +                    parameters[i] = _factoryParameters.getErrorLog();
  +                else if (parameterTypes[i] == Log.class)
  +                    parameters[i] = _factoryParameters.getLog();
  +                else if (parameterTypes[i] == Messages.class)
  +                    parameters[i] = _factoryParameters.getInvokingModule().getMessages();
  +                else
  +                    try
  +                    {
  +                        parameters[i] = _factoryParameters.getInvokingModule().getService(
  +                                parameterTypes[i]);
  +                    }
  +                    catch (ApplicationRuntimeException e)
  +                    {
  +                        continue outer;
  +                    }
  +
  +            return ConstructorUtils.invoke(candidate, parameters);
  +        }
  +
  +        throw new ApplicationRuntimeException(ServiceMessages.unableToFindAutowireConstructor(),
  +                _parameter.getLocation(), null);
  +    }
  +
  +    private List getOrderedServiceConstructors(Class serviceClass)
  +    {
  +        List orderedInterfaceConstructors = new ArrayList();
  +
  +        Constructor[] constructors = serviceClass.getDeclaredConstructors();
  +
  +        outer: for (int i = 0; i < constructors.length; i++)
  +        {
  +            if (!Modifier.isPublic(constructors[i].getModifiers()))
  +                continue;
  +
  +            Class[] parameterTypes = constructors[i].getParameterTypes();
  +
  +            if (parameterTypes.length > 0)
  +            {
  +                Set seenTypes = new HashSet();
  +
  +                for (int j = 0; j < parameterTypes.length; j++)
  +                {
  +                    if (!parameterTypes[j].isInterface() || seenTypes.contains(parameterTypes[j]))
  +                        continue outer;
  +
  +                    seenTypes.add(parameterTypes[j]);
  +                }
  +            }
  +
  +            orderedInterfaceConstructors.add(constructors[i]);
  +        }
  +
  +        Collections.sort(orderedInterfaceConstructors, new Comparator()
  +        {
  +            public int compare(Object o1, Object o2)
  +            {
  +                return ((Constructor) o2).getParameterTypes().length
  +                        - ((Constructor) o1).getParameterTypes().length;
  +            }
  +        });
  +
  +        return orderedInterfaceConstructors;
       }
   
       private void invokeInitializer(Object service)
  
  
  
  1.10      +1 -0      jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/ServiceStrings.properties
  
  Index: ServiceStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/ServiceStrings.properties,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ServiceStrings.properties	27 Sep 2004 14:36:50 -0000	1.9
  +++ ServiceStrings.properties	9 Nov 2004 11:24:30 -0000	1.10
  @@ -36,3 +36,4 @@
   invalid-service-property-locator=''{0}'' is not a valid locator for use with the service-property
object provider. It should be the id of a service, a comma, and the name of a property provided
by that service.
   failure-building-service=Error building service {0}: {1}
   autowire-property-failure=Unable to autowire property {0} of service {1}: {2}
  +unable-to-find-autowire-constructor=Unable to find constructor applicable for autowiring.
Use explicit constructor parameters.
  \ No newline at end of file
  
  
  

---------------------------------------------------------------------
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