commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject cvs commit: jakarta-commons-sandbox/hivemind/src/test/hivemind/test/rules TestExtensionPointTranslator.java
Date Tue, 12 Aug 2003 17:31:55 GMT
hlship      2003/08/12 10:31:55

  Modified:    hivemind/src/test/hivemind/test/services
                        RecursiveService.xml TestServices.java
               hivemind/src/java/org/apache/commons/hivemind/parse
                        ServiceDescriptor.java DescriptorParser.java
               hivemind/xdocs descriptor.xml services.xml
               hivemind/src/java/org/apache/commons/hivemind/service/impl
                        ClassFabImpl.java ClassFabUtils.java
                        AbstractServiceInterceptorFactory.java
                        LoggingInterceptorFactory.java
               hivemind/src/java/org/apache/commons/hivemind/impl
                        ServiceExtensionPointImpl.java RegistryBuilder.java
               hivemind/src/xsl hivemind.xsl
               hivemind/src/test/hivemind/test/services/impl
                        CountFactory.java
               hivemind/src/test/hivemind/test TestMisc.java
               hivemind/src/META-INF hivemodule.xml
               hivemind/src/java/org/apache/commons/hivemind/service
                        ClassFab.java
               hivemind/src/test/hivemind/test/rules
                        TestExtensionPointTranslator.java
  Log:
  Add support for deferred service proxies; objects which force the creation of the service
implementation only when a service interface method is invoked.
  
  Revision  Changes    Path
  1.7       +4 -4      jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/RecursiveService.xml
  
  Index: RecursiveService.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/RecursiveService.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- RecursiveService.xml	5 Aug 2003 00:50:36 -0000	1.6
  +++ RecursiveService.xml	12 Aug 2003 17:31:54 -0000	1.7
  @@ -3,7 +3,7 @@
   <module
   	id="hivemind.test.services.tracker" 
   	version="0.0.1">
  -	<service id="Fred" interface="org.apache.commons.hivemind.ServiceInterceptorFactory">
  +	<service id="Fred" interface="org.apache.commons.hivemind.ServiceInterceptorFactory"
deferrable="false">
   		<invoke-factory service-id="hivemind.BuilderFactory">
   			<construct class="hivemind.test.services.impl.TrackerFactory">
   				<set property="name" value="Fred"/>
  @@ -12,7 +12,7 @@
   	  <interceptor service-id="Barney"/>
   	</service>
   	
  -	<service id="Barney" interface="org.apache.commons.hivemind.ServiceInterceptorFactory">
  +	<service id="Barney" interface="org.apache.commons.hivemind.ServiceInterceptorFactory"
deferrable="false">
   		<invoke-factory service-id="hivemind.BuilderFactory">
   			<construct class="hivemind.test.services.impl.TrackerFactory">
   				<set property="name" value="Barney"/>
  @@ -21,7 +21,7 @@
   	  <interceptor service-id="Wilma"/>	  
   	</service>
   	
  -	<service id="Wilma" interface="org.apache.commons.hivemind.ServiceInterceptorFactory">
  +	<service id="Wilma" interface="org.apache.commons.hivemind.ServiceInterceptorFactory"
deferrable="false">
   		<invoke-factory service-id="hivemind.BuilderFactory">
   			<construct class="hivemind.test.services.impl.TrackerFactory">
   				<set property="name" value="Wilma"/>
  
  
  
  1.20      +15 -2     jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/TestServices.java
  
  Index: TestServices.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/TestServices.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- TestServices.java	11 Aug 2003 17:45:27 -0000	1.19
  +++ TestServices.java	12 Aug 2003 17:31:54 -0000	1.20
  @@ -132,6 +132,10 @@
               (SimpleService) r.getService("hivemind.test.services.Simple", SimpleService.class);
           CountFactory.reset();
   
  +        assertEquals(
  +            "<Proxy for hivemind.test.services.Simple(hivemind.test.services.SimpleService)>",
  +            s.toString());
  +
           assertEquals(7, s.add(4, 3));
   
           assertEquals(1, CountFactory.getCount());
  @@ -140,9 +144,13 @@
   
           assertEquals(2, CountFactory.getCount());
   
  +        SimpleService s2 =
  +            (SimpleService) r.getService("hivemind.test.services.Simple", SimpleService.class);
  +        assertNotSame(s, s2);
  +
           assertEquals(
               "<Interceptor: hivemind.test.services.CountFactory for hivemind.test.services.Simple(hivemind.test.services.SimpleService)>",
  -            s.toString());
  +            s2.toString());
       }
   
       public void testInterceptorSort() throws Exception
  @@ -412,6 +420,11 @@
                   BuilderAccess.class);
   
           assertNotNull(s);
  +        
  +        // s is a proxy, invoke a service method to force the creation of the
  +        // service (and the error).
  +        
  +        s.getExtensionPointId();
   
           checkLoggingEvent(
               BuilderFactory.class.getName(),
  
  
  
  1.7       +13 -1     jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/ServiceDescriptor.java
  
  Index: ServiceDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/ServiceDescriptor.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ServiceDescriptor.java	30 Jul 2003 22:34:53 -0000	1.6
  +++ ServiceDescriptor.java	12 Aug 2003 17:31:54 -0000	1.7
  @@ -74,6 +74,7 @@
       private boolean _required = true;
       private boolean _overridable;
       private Schema _parametersSchema;
  +    private boolean _deferrable;
   
       public String getId()
       {
  @@ -110,6 +111,7 @@
           builder.append("id", _id);
           builder.append("interfaceClassName", _interfaceClassName);
           builder.append("required", _required);
  +        builder.append("deferrable", _deferrable);
           builder.append("parametersSchema", _parametersSchema);
       }
   
  @@ -131,6 +133,16 @@
       public void setParametersSchema(Schema schema)
       {
           _parametersSchema = schema;
  +    }
  +
  +    public boolean isDeferrable()
  +    {
  +        return _deferrable;
  +    }
  +
  +    public void setDeferrable(boolean b)
  +    {
  +        _deferrable = b;
       }
   
   }
  
  
  
  1.24      +3 -1      jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java
  
  Index: DescriptorParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/parse/DescriptorParser.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- DescriptorParser.java	8 Aug 2003 13:51:09 -0000	1.23
  +++ DescriptorParser.java	12 Aug 2003 17:31:54 -0000	1.24
  @@ -211,6 +211,7 @@
           SERVICE_ATTRIBUTES.put("interface", Boolean.TRUE);
           SERVICE_ATTRIBUTES.put("required", Boolean.FALSE);
           SERVICE_ATTRIBUTES.put("overridable", Boolean.FALSE);
  +        SERVICE_ATTRIBUTES.put("deferrable", Boolean.FALSE);
       }
   
       private static final Map EXTEND_SERVICE_ATTRIBUTES = new HashMap();
  @@ -860,6 +861,7 @@
               sd.setInterfaceClassName(getAttribute("interface"));
               sd.setRequired(getBooleanAttribute("required", true));
               sd.setOverridable(getBooleanAttribute("overridable", false));
  +            sd.setDeferrable(getBooleanAttribute("deferrable", true));
   
               md.addService(sd);
   
  
  
  
  1.18      +10 -1     jakarta-commons-sandbox/hivemind/xdocs/descriptor.xml
  
  Index: descriptor.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/descriptor.xml,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- descriptor.xml	5 Aug 2003 15:41:44 -0000	1.17
  +++ descriptor.xml	12 Aug 2003 17:31:54 -0000	1.18
  @@ -420,6 +420,15 @@
   					just a placeholder.  The default is false.	
   					</td>
   				</tr>
  +				
  +				<tr>
  +					<td>deferrable</td>	
  +					<td>boolean</td>
  +					<td>no</td>
  +					<td>If true (the default), then service creation is deferred until
  +						a method of the service interface is actually invoked.  If false,
  +						then the service will be created when first requested.</td>
  +				</tr>
   
   			</table>
   			
  
  
  
  1.14      +37 -1     jakarta-commons-sandbox/hivemind/xdocs/services.xml
  
  Index: services.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/services.xml,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- services.xml	6 Aug 2003 18:50:50 -0000	1.13
  +++ services.xml	12 Aug 2003 17:31:54 -0000	1.14
  @@ -268,6 +268,42 @@
   			
   		</section>
   		
  +		<section name="Deferring Service Creation">
  +			
  +		<p>
  +		Creating a service instance can be somewhat expensive; it involves instantiating an core
  +		service implementation, configuring its properties (some of which may also be services),
  +		and building the stack of interceptors for the service.  That last part is troublesome,
HiveMind
  +		encourages you to define your application in terms of a large number of small, simple,
testable
  +		services ... yet, creating the first service in such a network can cause an avalanche
of service
  +		creation.
  +		</p>
  +		
  +		<p>
  +		To resolve this, HiveMind defers the actual creation of services.  When a service is
first requested
  +		(using
  +		<a href="apidocs/org/apache/commons/hivemind/ServiceExtensionPoint.html#getService(java.lang.Class)">ServiceExtensionPoint.getService()</a>
  +		),
  +		a <em>proxy</em>	for the service is created. This proxy uses the same service
interface as the actual service and,
  +		the first time a method of the service interface is invoked, will force the creation
of the actual
  +		service (with the core service implementation, interceptors, references to other services,
and so forth).
  +		</p>
  +			
  +		<p>
  +		This means that getService() will return different things at different times; initially
it will return the proxy,
  +		but once the service has been created, it will return the service itself.  This is irrelevant
to your code,
  +		which (as with interceptors) is provided with an object that implements the service interface
and doesn't need to
  +		know anything more.
  +		</p>	 
  +		
  +		<p>
  +		In certain cases (including many of the fundamental services provided by HiveMind) this
behavior is not desired;
  +		in those cases, the <code>deferrable</code>	attribute of the &service;
element should be set to "false". In addition,
  +		there is rarely a need to defer service implementation or service interceptor factory
services.
  +		</p>
  +			
  +		</section>
  +		
   		
   		<section name="Frequently Asked Questions">
   			<ul>
  
  
  
  1.5       +4 -2      jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java
  
  Index: ClassFabImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ClassFabImpl.java	11 Aug 2003 15:19:51 -0000	1.4
  +++ ClassFabImpl.java	12 Aug 2003 17:31:54 -0000	1.5
  @@ -119,6 +119,7 @@
       }
   
       public MethodFab addMethod(
  +    int modifiers,
           String name,
           Class returnType,
           Class[] parameterTypes,
  @@ -130,9 +131,10 @@
           CtClass[] ctExceptions = convertClasses(exceptions);
   
           CtMethod method = new CtMethod(ctReturnType, name, ctParameters, _ctClass);
  -
  +		
           try
           {
  +			method.setModifiers(modifiers);
               method.setExceptionTypes(ctExceptions);
               method.setBody(body);
   
  
  
  
  1.2       +20 -1     jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabUtils.java
  
  Index: ClassFabUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabUtils.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ClassFabUtils.java	11 Aug 2003 15:19:51 -0000	1.1
  +++ ClassFabUtils.java	12 Aug 2003 17:31:54 -0000	1.2
  @@ -56,6 +56,9 @@
    */
   
   package org.apache.commons.hivemind.service.impl;
  +
  +import java.lang.reflect.Method;
  +
   /**
    * Static class containing utility methods.
    *
  @@ -81,5 +84,21 @@
               return getJavaClassName(inputClass.getComponentType()) + "[]";
   
           return inputClass.getName();
  +    }
  +
  +    /**
  +     * Returns true if the method is the standard toString() method.
  +     * Very few interfaces will ever include this method as part of
  +     * the interface, but we have to be sure.
  +     */
  +    public static boolean isToString(Method method)
  +    {
  +        if (!method.getName().equals("toString"))
  +            return false;
  +    
  +        if (method.getParameterTypes().length > 0)
  +            return false;
  +    
  +        return method.getReturnType().equals(String.class);
       }
   }
  
  
  
  1.9       +4 -19     jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/AbstractServiceInterceptorFactory.java
  
  Index: AbstractServiceInterceptorFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/AbstractServiceInterceptorFactory.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AbstractServiceInterceptorFactory.java	11 Aug 2003 15:19:51 -0000	1.8
  +++ AbstractServiceInterceptorFactory.java	12 Aug 2003 17:31:54 -0000	1.9
  @@ -59,6 +59,7 @@
   
   import java.lang.reflect.Constructor;
   import java.lang.reflect.Method;
  +import java.lang.reflect.Modifier;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
   import org.apache.commons.hivemind.HiveMind;
  @@ -218,7 +219,7 @@
                   m.getParameterTypes(),
                   m.getExceptionTypes());
   
  -            toString |= isToString(m);
  +            toString |= ClassFabUtils.isToString(m);
           }
   
           if (!toString)
  @@ -226,22 +227,6 @@
       }
   
       /**
  -     * Returns true if the method is the standard toString() method.
  -     * Very few interfaces will ever include this method as part of
  -     * the interface, but we have to be sure.
  -     */
  -    private boolean isToString(Method method)
  -    {
  -        if (!method.getName().equals("toString"))
  -            return false;
  -
  -        if (method.getParameterTypes().length > 0)
  -            return false;
  -
  -        return method.getReturnType().equals(String.class);
  -    }
  -
  -    /**
        * Creates a toString() method that identify the interceptor service id,
        * the intercepted service id, and the service interface class name).
        */
  @@ -258,6 +243,6 @@
   
           body.append("\";");
   
  -        fab.addMethod("toString", String.class, null, null, body.toString());
  +        fab.addMethod(Modifier.PUBLIC, "toString", String.class, null, null, body.toString());
       }
   }
  
  
  
  1.6       +9 -2      jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/LoggingInterceptorFactory.java
  
  Index: LoggingInterceptorFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/LoggingInterceptorFactory.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- LoggingInterceptorFactory.java	11 Aug 2003 15:19:51 -0000	1.5
  +++ LoggingInterceptorFactory.java	12 Aug 2003 17:31:54 -0000	1.6
  @@ -58,6 +58,7 @@
   package org.apache.commons.hivemind.service.impl;
   
   import java.lang.reflect.Constructor;
  +import java.lang.reflect.Modifier;
   
   import org.apache.commons.hivemind.InterceptorStack;
   import org.apache.commons.hivemind.service.ClassFab;
  @@ -143,7 +144,13 @@
           String body = buffer.toString();
   
           MethodFab methodFab =
  -            classFab.addMethod(methodName, returnType, parameterTypes, exceptions, body);
  +            classFab.addMethod(
  +                Modifier.PUBLIC,
  +                methodName,
  +                returnType,
  +                parameterTypes,
  +                exceptions,
  +                body);
   
           int count = exceptions == null ? 0 : exceptions.length;
   
  
  
  
  1.8       +204 -5    jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/ServiceExtensionPointImpl.java
  
  Index: ServiceExtensionPointImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/ServiceExtensionPointImpl.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ServiceExtensionPointImpl.java	8 Aug 2003 13:51:08 -0000	1.7
  +++ ServiceExtensionPointImpl.java	12 Aug 2003 17:31:54 -0000	1.8
  @@ -57,17 +57,24 @@
   
   package org.apache.commons.hivemind.impl;
   
  +import java.lang.reflect.Constructor;
  +import java.lang.reflect.Method;
  +import java.lang.reflect.Modifier;
   import java.util.ArrayList;
   import java.util.List;
   
   import org.apache.commons.hivemind.ApplicationRuntimeException;
  -import org.apache.commons.hivemind.HiveMind;
   import org.apache.commons.hivemind.ClassResolver;
  +import org.apache.commons.hivemind.HiveMind;
   import org.apache.commons.hivemind.Initializable;
  +import org.apache.commons.hivemind.Registry;
   import org.apache.commons.hivemind.ServiceExtensionPoint;
   import org.apache.commons.hivemind.ServiceImplementationConstructor;
   import org.apache.commons.hivemind.ServiceInterceptorContribution;
   import org.apache.commons.hivemind.schema.Schema;
  +import org.apache.commons.hivemind.service.ClassFab;
  +import org.apache.commons.hivemind.service.ClassFactory;
  +import org.apache.commons.hivemind.service.impl.ClassFabUtils;
   import org.apache.commons.lang.builder.ToStringBuilder;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -93,11 +100,15 @@
       private boolean _building;
       private Schema _parametersSchema;
       private Object _constructedService;
  +    private boolean _deferrable;
  +    private Object _deferredProxy;
  +
  +    private static int _proxyUid = 0;
   
       protected void extendDescription(ToStringBuilder builder)
       {
  -        builder.append("constructedService", _constructedService);
           builder.append("serviceInterfaceName", _serviceInterfaceName);
  +        builder.append("deferrable", _deferrable);
           builder.append("required", _required);
           builder.append("overridable", _overridable);
           builder.append("factoryContribution", _serviceConstructor);
  @@ -188,6 +199,20 @@
           if (_constructedService != null)
               return _constructedService;
   
  +        if (_deferrable)
  +            return getDeferredProxy();
  +
  +        return constructServiceImplementation();
  +    }
  +
  +    /**
  +     * Constructs the service implementation; this is invoked
  +     * from {@link #constructService()} and from the generated 
  +     * deferrable proxy.
  +     */
  +
  +    public Object constructServiceImplementation()
  +    {
           if (_building)
               throw new ApplicationRuntimeException(
                   HiveMind.format(
  @@ -198,13 +223,14 @@
           {
               _building = true;
   
  -            _constructedService = constructServiceInner();
  +            _constructedService = constructServiceImplementationInner();
   
               // After succesfully building, we don't need 
               // some of the definition stuff again.
   
               _serviceConstructor = null;
               _interceptorContributions = null;
  +            _deferredProxy = null;
   
           }
           finally
  @@ -215,7 +241,7 @@
           return _constructedService;
       }
   
  -    protected Object constructServiceInner()
  +    private Object constructServiceImplementationInner()
       {
           if (_serviceConstructor == null)
           {
  @@ -340,6 +366,179 @@
           }
   
           return result;
  +    }
  +
  +    public boolean isDeferrable()
  +    {
  +        return _deferrable;
  +    }
  +
  +    public void setDeferrable(boolean b)
  +    {
  +        _deferrable = b;
  +    }
  +
  +    /**
  +     * Returns the proxy, creating it if necessary.
  +     * 
  +     **/
  +
  +    private Object getDeferredProxy()
  +    {
  +        if (_deferredProxy == null)
  +            _deferredProxy = createDeferredProxy();
  +
  +        return _deferredProxy;
  +    }
  +
  +    /**
  +     * Creates a proxy class for the service and then constructs the class itself.
  +     */
  +    private Object createDeferredProxy()
  +    {
  +        if (_building)
  +            throw new ApplicationRuntimeException(
  +                HiveMind.format(
  +                    "ServiceExtensionPoint.recursive-service-build",
  +                    getExtensionPointId()));
  +        try
  +        {
  +            _building = true;
  +
  +            Class proxyClass = createDeferredProxyClass();
  +
  +            Constructor c =
  +                proxyClass.getConstructor(new Class[] { ServiceExtensionPointImpl.class
});
  +
  +            return c.newInstance(new Object[] { this });
  +        }
  +        catch (Exception ex)
  +        {
  +            throw new ApplicationRuntimeException(ex);
  +        }
  +        finally
  +        {
  +            _building = false;
  +        }
  +
  +    }
  +
  +	/**
  +	 * Creates a class that implements the service interface. Implements
  +	 * a private synchronized method, _service(), that constructs the service
  +	 * as needed, and has each service interface method re-invoke on _service().
  +	 * Adds a toString() method if the service interface does not define toString().
  +	 */
  +    private Class createDeferredProxyClass()
  +    {
  +        Registry registry = getModule().getRegistry();
  +
  +        ClassFactory factory =
  +            (ClassFactory) registry.getService(
  +                HiveMind.CLASS_FACTORY_SERVICE_ID,
  +                ClassFactory.class);
  +
  +        String className =
  +            "$Proxy_" + Long.toHexString(System.currentTimeMillis()) + "_" + _proxyUid++;
  +
  +        ClassFab classFab = factory.newClass(className, Object.class, getModule());
  +
  +        Class serviceInterface = getServiceInterface();
  +
  +        classFab.addInterface(serviceInterface);
  +
  +        classFab.addField("_service", serviceInterface);
  +        classFab.addField("_serviceExtensionPoint", ServiceExtensionPointImpl.class);
  +
  +        classFab.addConstructor(
  +            new Class[] { ServiceExtensionPointImpl.class },
  +            null,
  +            "{ super(); _serviceExtensionPoint = $1; }");
  +
  +        addServiceAccessor(classFab, serviceInterface);
  +        addServiceMethods(classFab, serviceInterface);
  +
  +        return classFab.createClass();
  +    }
  +
  +    private void addServiceAccessor(ClassFab classFab, Class serviceInterface)
  +    {
  +        StringBuffer buffer = new StringBuffer("{ \n");
  +        buffer.append(" if (_service == null)\n");
  +        buffer.append(" {\n");
  +        buffer.append("   _service = (");
  +        buffer.append(serviceInterface.getName());
  +        buffer.append(") _serviceExtensionPoint.constructServiceImplementation();\n");
  +        buffer.append(" }\n\n");
  +        buffer.append("return _service;\n");
  +        buffer.append("}");
  +
  +        String body = buffer.toString();
  +
  +        classFab.addMethod(
  +            Modifier.PRIVATE + Modifier.SYNCHRONIZED,
  +            "_service",
  +            serviceInterface,
  +            null,
  +            null,
  +            body);
  +    }
  +
  +    private void addServiceMethods(ClassFab classFab, Class serviceInterface)
  +    {
  +        boolean toString = false;
  +
  +        Method[] methods = serviceInterface.getMethods();
  +        StringBuffer buffer = new StringBuffer();
  +
  +        for (int i = 0; i < methods.length; i++)
  +        {
  +            Method m = methods[i];
  +
  +            String methodName = m.getName();
  +            Class returnType = m.getReturnType();
  +
  +            buffer.setLength(0);
  +
  +            buffer.append("{\n");
  +            buffer.append("  ");
  +
  +            if (!returnType.equals(Void.class))
  +                buffer.append("return ");
  +
  +            buffer.append("_service().");
  +            buffer.append(methodName);
  +            buffer.append("($$);\n");
  +            buffer.append("}");
  +
  +            String body = buffer.toString();
  +
  +            classFab.addMethod(
  +                Modifier.PUBLIC,
  +                methodName,
  +                m.getReturnType(),
  +                m.getParameterTypes(),
  +                m.getExceptionTypes(),
  +                body);
  +
  +            toString |= ClassFabUtils.isToString(m);
  +        }
  +
  +        if (!toString)
  +            createToString(classFab, serviceInterface);
  +    }
  +
  +    private void createToString(ClassFab classFab, Class serviceInterface)
  +    {
  +        StringBuffer buffer = new StringBuffer("return \"<Proxy for ");
  +        buffer.append(getExtensionPointId());
  +        buffer.append("(");
  +        buffer.append(serviceInterface.getName());
  +        buffer.append(")>\";");
  +
  +        String body = buffer.toString();
  +
  +        classFab.addMethod(Modifier.PUBLIC, "toString", String.class, null, null, body);
       }
   
   }
  
  
  
  1.21      +2 -1      jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java
  
  Index: RegistryBuilder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/impl/RegistryBuilder.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- RegistryBuilder.java	8 Aug 2003 13:51:08 -0000	1.20
  +++ RegistryBuilder.java	12 Aug 2003 17:31:54 -0000	1.21
  @@ -312,6 +312,7 @@
               point.setModule(module);
               point.setRequired(sd.isRequired());
               point.setOverridable(sd.isOverridable());
  +            point.setDeferrable(sd.isDeferrable());
               point.setServiceInterfaceName(sd.getInterfaceClassName());
               point.setParametersSchema(sd.getParametersSchema());
   
  
  
  
  1.14      +9 -2      jakarta-commons-sandbox/hivemind/src/xsl/hivemind.xsl
  
  Index: hivemind.xsl
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/xsl/hivemind.xsl,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- hivemind.xsl	11 Aug 2003 17:58:04 -0000	1.13
  +++ hivemind.xsl	12 Aug 2003 17:31:54 -0000	1.14
  @@ -389,7 +389,14 @@
   						<xsl:if test="not(@overridable)">false</xsl:if>
   						<xsl:value-of select="@overridable"/>
   					</td>
  -				</tr>				
  +				</tr>	
  +				<tr>
  +					<th>Deferrable</th>
  +					<td>
  +						<xsl:if test="not(@deferrable)">true</xsl:if>
  +						<xsl:value-of select="@deferrable"/>
  +					</td>
  +				</tr>					
   				<xsl:if test="description">
   					<tr>
   						<td colspan="2" class="description">
  
  
  
  1.7       +4 -2      jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/impl/CountFactory.java
  
  Index: CountFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/services/impl/CountFactory.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CountFactory.java	5 Aug 2003 17:16:29 -0000	1.6
  +++ CountFactory.java	12 Aug 2003 17:31:54 -0000	1.7
  @@ -57,6 +57,8 @@
   
   package hivemind.test.services.impl;
   
  +import java.lang.reflect.Modifier;
  +
   import org.apache.commons.hivemind.service.ClassFab;
   import org.apache.commons.hivemind.service.impl.AbstractServiceInterceptorFactory;
   
  @@ -101,7 +103,7 @@
           body.append("($$);\n\n");
           body.append("}");
   
  -        classFab.addMethod(methodName, returnType, parameterTypes, exceptions, body.toString());
  +        classFab.addMethod(Modifier.PUBLIC, methodName, returnType, parameterTypes, exceptions,
body.toString());
       }
   
   }
  
  
  
  1.2       +12 -1     jakarta-commons-sandbox/hivemind/src/test/hivemind/test/TestMisc.java
  
  Index: TestMisc.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/TestMisc.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestMisc.java	11 Aug 2003 15:19:51 -0000	1.1
  +++ TestMisc.java	12 Aug 2003 17:31:54 -0000	1.2
  @@ -281,4 +281,15 @@
           }
   
       }
  +
  +    public void testServiceDeferrableAccessor()
  +    {
  +        ServiceExtensionPointImpl sep = new ServiceExtensionPointImpl();
  +
  +        assertEquals(false, sep.isDeferrable());
  +
  +        sep.setDeferrable(true);
  +
  +        assertEquals(true, sep.isDeferrable());
  +    }
   }
  
  
  
  1.15      +5 -5      jakarta-commons-sandbox/hivemind/src/META-INF/hivemodule.xml
  
  Index: hivemodule.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/META-INF/hivemodule.xml,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- hivemodule.xml	11 Aug 2003 17:45:28 -0000	1.14
  +++ hivemodule.xml	12 Aug 2003 17:31:54 -0000	1.15
  @@ -97,12 +97,12 @@
   	</service>
   	
   	
  -	<service id="ClassFactory" interface="org.apache.commons.hivemind.service.ClassFactory">
  +	<service id="ClassFactory" interface="org.apache.commons.hivemind.service.ClassFactory"
deferrable="false">
   		<description>Wrapper around Javassist used to dynamically create classes such as
service interceptors.</description>
   		<create-instance class="org.apache.commons.hivemind.service.impl.ClassFactoryImpl"/>
   	</service>
   	
  -		<service id="LoggingInterceptor" interface="org.apache.commons.hivemind.ServiceInterceptorFactory">
  +		<service id="LoggingInterceptor" interface="org.apache.commons.hivemind.ServiceInterceptorFactory"
deferrable="false">
   		<description>
   			An interceptor factory for adding method-level logging to a service. 
   			Logging occurs at level DEBUG and uses the service id as the logger. 
  @@ -130,7 +130,7 @@
   		<create-instance class="org.apache.commons.hivemind.service.impl.NameLookupImpl"/>

   	</service>
   	
  -	<service id="BuilderFactory" interface="org.apache.commons.hivemind.ServiceImplementationFactory">
  +	<service id="BuilderFactory" interface="org.apache.commons.hivemind.ServiceImplementationFactory"
deferrable="false">
   		<description>
   		Used to construct a service from a class name and a set of properties and values to be
set in the instantiated class.	
   		</description>
  @@ -262,7 +262,7 @@
   	
   
   	<service id="EJBProxyFactory"
  -		interface="org.apache.commons.hivemind.ServiceImplementationFactory">
  +		interface="org.apache.commons.hivemind.ServiceImplementationFactory" deferrable="false">
   		<description>
   		Core service implementation factory that constructs dynamic proxies to EJB stateless
session beans.  A single parameter, the JNDI name of the proxy, is required.	
   		</description>
  
  
  
  1.2       +3 -1      jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/ClassFab.java
  
  Index: ClassFab.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/ClassFab.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ClassFab.java	9 Jul 2003 11:27:23 -0000	1.1
  +++ ClassFab.java	12 Aug 2003 17:31:54 -0000	1.2
  @@ -81,6 +81,7 @@
       /**
        * Adds a method.  The method is a public instance method.
        * @return a method fabricator, used to add catch handlers.
  +     * @param modifiers - Modifiers for the method
        * @param name The name of the method to create.
        * @param returnType the return type of the method.
        * @param parameterTypes the types of each parameter, or null if the method takes no
parameters.
  @@ -89,6 +90,7 @@
        */
   
       public MethodFab addMethod(
  +    	int modifiers,
           String name,
           Class returnType,
           Class[] parameterTypes,
  
  
  
  1.3       +5 -1      jakarta-commons-sandbox/hivemind/src/test/hivemind/test/rules/TestExtensionPointTranslator.java
  
  Index: TestExtensionPointTranslator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/rules/TestExtensionPointTranslator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TestExtensionPointTranslator.java	11 Aug 2003 17:45:28 -0000	1.2
  +++ TestExtensionPointTranslator.java	12 Aug 2003 17:31:54 -0000	1.3
  @@ -108,6 +108,10 @@
           DatumHolder h =
               (DatumHolder) r.getService("hivemind.test.rules.Failure", DatumHolder.class);
   
  +		// Force creation of service, and thus the error.
  +		
  +		h.getDatums();
  +
           checkLoggingEvent(
               ExtensionPointTranslator.class.getName(),
               "Error accessing extension point hivemind\\.test\\.rules\\.missing \\(at .*\\):
"
  
  
  

Mime
View raw message