hivemind-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject cvs commit: jakarta-hivemind/framework/src/java/org/apache/hivemind/service ClassFabUtils.java
Date Tue, 14 Sep 2004 17:48:26 GMT
hlship      2004/09/14 10:48:26

  Modified:    .        Tag: branch-1-0 status.xml
               library/src/java/org/apache/hivemind/lib/impl Tag:
                        branch-1-0 ServicePropertyFactory.java
               framework/src/java/org/apache/hivemind/service/impl Tag:
                        branch-1-0 LoggingInterceptorFactory.java
               framework/src/java/org/apache/hivemind/service Tag:
                        branch-1-0 ClassFabUtils.java
  Added:       framework/src/test/org/apache/hivemind/service/impl Tag:
                        branch-1-0 TestLoggingInterceptorFactory.java
                        TestClassFabUtils.java
  Log:
  HIVEMIND-55: Make fabricated classes work with JDK proxies.
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.1.2.1   +97 -0     jakarta-hivemind/framework/src/test/org/apache/hivemind/service/impl/Attic/TestLoggingInterceptorFactory.java
  
  
  
  
  1.1.2.1   +42 -0     jakarta-hivemind/framework/src/test/org/apache/hivemind/service/impl/Attic/TestClassFabUtils.java
  
  
  
  
  No                   revision
  No                   revision
  1.57.2.8  +6 -0      jakarta-hivemind/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/status.xml,v
  retrieving revision 1.57.2.7
  retrieving revision 1.57.2.8
  diff -u -r1.57.2.7 -r1.57.2.8
  --- status.xml	11 Sep 2004 13:06:51 -0000	1.57.2.7
  +++ status.xml	14 Sep 2004 17:48:25 -0000	1.57.2.8
  @@ -30,6 +30,12 @@
     
     <changes>
     
  +   <release version="1.0" date="unreleased">
  +    <action type="fix" dev="HLS" fixes-bug="HIVEMIND-55">
  +      Ensure that the logging interceptor will work properly when wrapping around JDK dynamic
proxies.
  +    </action>
  +   </release>
  +  
       <release version="1.0-rc-2" date="Sep 11 2004">
         <action type="add" dev="HLS">
           Add method <code>getSymbolValue()</code> to RegistryInfrastructure
and Module
  
  
  
  No                   revision
  No                   revision
  1.4.2.2   +26 -61    jakarta-hivemind/library/src/java/org/apache/hivemind/lib/impl/ServicePropertyFactory.java
  
  Index: ServicePropertyFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/library/src/java/org/apache/hivemind/lib/impl/ServicePropertyFactory.java,v
  retrieving revision 1.4.2.1
  retrieving revision 1.4.2.2
  diff -u -r1.4.2.1 -r1.4.2.2
  --- ServicePropertyFactory.java	7 Sep 2004 19:38:27 -0000	1.4.2.1
  +++ ServicePropertyFactory.java	14 Sep 2004 17:48:25 -0000	1.4.2.2
  @@ -32,23 +32,19 @@
   import org.apache.hivemind.util.PropertyUtils;
   
   /**
  - * Factory that dynamically exposes a property of another service. A proxy
  - * is constructed that accesses the target service and obtains a property from that.
  - * The service interface of the constructed service must match the
  - * type of the exposed property.
  - *
  + * Factory that dynamically exposes a property of another service. A proxy is
  + * constructed that accesses the target service and obtains a property from
  + * that. The service interface of the constructed service must match the type of
  + * the exposed property.
  + * 
    * @author Howard Lewis Ship
    */
   public class ServicePropertyFactory implements ServiceImplementationFactory
   {
       private ClassFactory _classFactory;
   
  -    public Object createCoreServiceImplementation(
  -        String serviceId,
  -        Class serviceInterface,
  -        Log serviceLog,
  -        Module invokingModule,
  -        List parameters)
  +    public Object createCoreServiceImplementation(String serviceId, Class serviceInterface,
Log serviceLog,
  +            Module invokingModule, List parameters)
       {
           ServicePropertyFactoryParameter p = (ServicePropertyFactoryParameter) parameters.get(0);
   
  @@ -60,31 +56,18 @@
           String readMethodName = pa.getReadMethodName();
   
           if (readMethodName == null)
  -            throw new ApplicationRuntimeException(
  -                ImplMessages.servicePropertyNotReadable(propertyName, targetService),
  -                null,
  -                p.getLocation(),
  -                null);
  +            throw new ApplicationRuntimeException(ImplMessages.servicePropertyNotReadable(propertyName,
targetService),
  +                    null, p.getLocation(), null);
   
           if (!(serviceInterface.isAssignableFrom(pa.getPropertyType())))
  -            throw new ApplicationRuntimeException(
  -                ImplMessages.servicePropertyWrongType(
  -                    propertyName,
  -                    targetService,
  -                    pa.getPropertyType(),
  -                    serviceInterface),
  -                p.getLocation(),
  -                null);
  +            throw new ApplicationRuntimeException(ImplMessages.servicePropertyWrongType(propertyName,
targetService, pa
  +                    .getPropertyType(), serviceInterface), p.getLocation(), null);
   
           // Now we're good to go.
   
           String name = ClassFabUtils.generateClassName("ServicePropertyProxy");
   
  -        ClassFab cf =
  -            _classFactory.newClass(
  -                name,
  -                Object.class,
  -                invokingModule.getClassResolver().getClassLoader());
  +        ClassFab cf = _classFactory.newClass(name, Object.class, invokingModule.getClassResolver().getClassLoader());
   
           addInfrastructure(cf, targetService, serviceInterface, propertyName, readMethodName);
   
  @@ -94,7 +77,8 @@
   
           try
           {
  -            return ConstructorUtils.invokeConstructor(proxyClass, new Object[] { targetService
});
  +            return ConstructorUtils.invokeConstructor(proxyClass, new Object[]
  +            { targetService });
           }
           catch (Throwable ex)
           {
  @@ -102,31 +86,22 @@
           }
       }
   
  -    private void addInfrastructure(
  -        ClassFab cf,
  -        Object targetService,
  -        Class serviceInterface,
  -        String propertyName,
  -        String readPropertyMethodName)
  +    private void addInfrastructure(ClassFab cf, Object targetService, Class serviceInterface,
String propertyName,
  +            String readPropertyMethodName)
       {
           cf.addInterface(serviceInterface);
   
  -        Class targetServiceClass = targetService.getClass();
  +        Class targetServiceClass = ClassFabUtils.getInstanceClass(targetService, serviceInterface);
   
           cf.addField("_targetService", targetServiceClass);
   
  -        cf.addConstructor(
  -            new Class[] { targetServiceClass },
  -            null,
  -            "{ super(); _targetService = $1; }");
  +        cf.addConstructor(new Class[]
  +        { targetServiceClass }, null, "{ super(); _targetService = $1; }");
   
           BodyBuilder b = new BodyBuilder();
   
           b.begin();
  -        b.addln(
  -            "{0} property = _targetService.{1}();",
  -            serviceInterface.getName(),
  -            readPropertyMethodName);
  +        b.addln("{0} property = _targetService.{1}();", serviceInterface.getName(), readPropertyMethodName);
   
           b.addln("if (property == null)");
           b.add("  throw new java.lang.NullPointerException(");
  @@ -137,17 +112,12 @@
   
           b.end();
   
  -        MethodSignature sig =
  -            new MethodSignature(serviceInterface, "_targetServiceProperty", null, null);
  +        MethodSignature sig = new MethodSignature(serviceInterface, "_targetServiceProperty",
null, null);
           cf.addMethod(Modifier.FINAL | Modifier.PRIVATE, sig, b.toString());
       }
   
  -    private void addMethods(
  -        ClassFab cf,
  -        String serviceId,
  -        Class serviceInterface,
  -        String propertyName,
  -        Object targetService)
  +    private void addMethods(ClassFab cf, String serviceId, Class serviceInterface, String
propertyName,
  +            Object targetService)
       {
           boolean toString = false;
   
  @@ -165,17 +135,12 @@
           }
   
           if (!toString)
  -            ClassFabUtils.addToStringMethod(
  -                cf,
  -                ImplMessages.servicePropertyToString(
  -                    serviceId,
  -                    serviceInterface,
  -                    propertyName,
  -                    targetService));
  +            ClassFabUtils.addToStringMethod(cf, ImplMessages.servicePropertyToString(serviceId,
serviceInterface,
  +                    propertyName, targetService));
       }
   
       public void setClassFactory(ClassFactory factory)
       {
           _classFactory = factory;
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  No                   revision
  No                   revision
  1.8.2.3   +38 -51    jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/LoggingInterceptorFactory.java
  
  Index: LoggingInterceptorFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/impl/LoggingInterceptorFactory.java,v
  retrieving revision 1.8.2.2
  retrieving revision 1.8.2.3
  diff -u -r1.8.2.2 -r1.8.2.3
  --- LoggingInterceptorFactory.java	8 Sep 2004 17:18:09 -0000	1.8.2.2
  +++ LoggingInterceptorFactory.java	14 Sep 2004 17:48:26 -0000	1.8.2.3
  @@ -35,23 +35,22 @@
   import org.apache.hivemind.service.MethodSignature;
   
   /**
  - * An interceptor factory that adds logging capability to a service.
  - * The logging is based upon the Jakarta 
  - * <a href="http://jakarta.apache.org/commons/logging.html">commons-logging</a>
toolkit, 
  - * which makes
  - * it very transportable.
  - * 
  + * An interceptor factory that adds logging capability to a service. The logging
  + * is based upon the Jakarta <a
  + * href="http://jakarta.apache.org/commons/logging.html">commons-logging </a>
  + * toolkit, which makes it very transportable.
    * <p>
  - * The interceptor will log entry to each method and exit from the method
  - * (with return value), plus log any exceptions thrown by the method.
  - * The logger used is the <em>id of the service</em>, which is not necessarily
  - * the name of the implementing class.  Logging occurs at the debug level.
  - *
  + * The interceptor will log entry to each method and exit from the method (with
  + * return value), plus log any exceptions thrown by the method. The logger used
  + * is the <em>id of the service</em>, which is not necessarily the name of
  + * the implementing class. Logging occurs at the debug level.
  + * 
    * @author Howard Lewis Ship
    */
   public class LoggingInterceptorFactory implements ServiceInterceptorFactory
   {
       private ClassFactory _factory;
  +
       private String _serviceId;
   
       /**
  @@ -166,18 +165,13 @@
       }
   
       /**
  -     * Creates a toString() method that identify the interceptor service id,
  -     * the intercepted service id, and the service interface class name).
  +     * Creates a toString() method that identify the interceptor service id, the
  +     * intercepted service id, and the service interface class name).
        */
       protected void addToStringMethod(InterceptorStack stack, ClassFab fab)
       {
  -        ClassFabUtils.addToStringMethod(
  -            fab,
  -            "<LoggingInterceptor for "
  -                + stack.getServiceExtensionPointId()
  -                + "("
  -                + stack.getServiceInterface().getName()
  -                + ")>");
  +        ClassFabUtils.addToStringMethod(fab, "<LoggingInterceptor for " + stack.getServiceExtensionPointId()
+ "("
  +                + stack.getServiceInterface().getName() + ")>");
   
       }
   
  @@ -206,8 +200,7 @@
   
           String name = ClassFabUtils.generateClassName("Interceptor");
   
  -        ClassFab classFab =
  -            _factory.newClass(name, Object.class, module.getClassResolver().getClassLoader());
  +        ClassFab classFab = _factory.newClass(name, Object.class, module.getClassResolver().getClassLoader());
   
           classFab.addInterface(serviceInterfaceClass);
   
  @@ -220,35 +213,34 @@
   
       private void createInfrastructure(InterceptorStack stack, ClassFab classFab)
       {
  -        Class topClass = stack.peek().getClass();
  +        Class topClass = ClassFabUtils.getInstanceClass(stack.peek(), stack.getServiceInterface());
   
           classFab.addField("_log", Log.class);
   
  -        // This is very important: since we know the instance of the top object (the next
  -        // object in the pipeline for this service), we can build the instance variable
  -        // and constructor to use the exact class rather than the service interface.
  -        // That's more efficient at runtime, lowering the cost of using interceptors.
  +        // This is very important: since we know the instance of the top object
  +        // (the next
  +        // object in the pipeline for this service), we can build the instance
  +        // variable
  +        // and constructor to use the exact class rather than the service
  +        // interface.
  +        // That's more efficient at runtime, lowering the cost of using
  +        // interceptors.
           // One of the reasons I prefer Javassist over JDK Proxies.
   
           classFab.addField("_inner", topClass);
   
  -        classFab.addConstructor(
  -            new Class[] { Log.class, topClass },
  -            null,
  -            "{ _log = $1; _inner = $2; }");
  +        classFab.addConstructor(new Class[]
  +        { Log.class, topClass }, null, "{ _log = $1; _inner = $2; }");
       }
   
       /**
  -     * Creates the interceptor.
  -     * The class that is created is cached; if an interceptor is requested
  -     * for the same extension point, then the previously constructed class
  -     * is reused (this can happen with the threaded service model, for example,
  -     * when a thread-local service implementation is created for different threads).
  +     * Creates the interceptor. The class that is created is cached; if an
  +     * interceptor is requested for the same extension point, then the
  +     * previously constructed class is reused (this can happen with the threaded
  +     * service model, for example, when a thread-local service implementation is
  +     * created for different threads).
        */
  -    public void createInterceptor(
  -        InterceptorStack stack,
  -        Module contributingModule,
  -        List parameters)
  +    public void createInterceptor(InterceptorStack stack, Module contributingModule, List
parameters)
       {
           Class interceptorClass = constructInterceptorClass(stack, parameters);
   
  @@ -260,13 +252,8 @@
           }
           catch (Exception ex)
           {
  -            throw new ApplicationRuntimeException(
  -                ServiceMessages.errorInstantiatingInterceptor(
  -                    _serviceId,
  -                    stack,
  -                    interceptorClass,
  -                    ex),
  -                ex);
  +            throw new ApplicationRuntimeException(ServiceMessages.errorInstantiatingInterceptor(_serviceId,
stack,
  +                    interceptorClass, ex), ex);
           }
       }
   
  @@ -280,14 +267,14 @@
           return mc == null || mc.getInclude();
       }
   
  -    private Object instantiateInterceptor(InterceptorStack stack, Class interceptorClass)
  -        throws Exception
  +    private Object instantiateInterceptor(InterceptorStack stack, Class interceptorClass)
throws Exception
       {
           Object stackTop = stack.peek();
   
           Constructor c = interceptorClass.getConstructors()[0];
   
  -        return c.newInstance(new Object[] { stack.getServiceLog(), stackTop });
  +        return c.newInstance(new Object[]
  +        { stack.getServiceLog(), stackTop });
       }
   
       public void setFactory(ClassFactory factory)
  @@ -299,4 +286,4 @@
       {
           _serviceId = string;
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  No                   revision
  No                   revision
  1.3.2.1   +37 -18    jakarta-hivemind/framework/src/java/org/apache/hivemind/service/ClassFabUtils.java
  
  Index: ClassFabUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-hivemind/framework/src/java/org/apache/hivemind/service/ClassFabUtils.java,v
  retrieving revision 1.3
  retrieving revision 1.3.2.1
  diff -u -r1.3 -r1.3.2.1
  --- ClassFabUtils.java	12 Jun 2004 18:43:41 -0000	1.3
  +++ ClassFabUtils.java	14 Sep 2004 17:48:26 -0000	1.3.2.1
  @@ -16,10 +16,11 @@
   
   import java.lang.reflect.Method;
   import java.lang.reflect.Modifier;
  +import java.lang.reflect.Proxy;
   
   /**
    * Static class containing utility methods.
  - *
  + * 
    * @author Howard Lewis Ship
    */
   public class ClassFabUtils
  @@ -33,8 +34,7 @@
       }
   
       /**
  -     * Generates a unique class name, which will be in the
  -     * default package.
  +     * Generates a unique class name, which will be in the default package.
        */
   
       public static synchronized String generateClassName(String baseName)
  @@ -43,11 +43,10 @@
       }
   
       /**
  -     * Javassist needs the class name to be as it appears in source code, even for arrays.
  -     * Invoking getName() on a Class instance representing an array returns the internal
  -     * format (i.e, "[...;" or something).  This returns it as it would appear in
  -     * Java code.
  -     *
  +     * Javassist needs the class name to be as it appears in source code, even
  +     * for arrays. Invoking getName() on a Class instance representing an array
  +     * returns the internal format (i.e, "[...;" or something). This returns it
  +     * as it would appear in Java code.
        */
       public static String getJavaClassName(Class inputClass)
       {
  @@ -58,9 +57,9 @@
       }
   
       /**
  -     * 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.
  +     * 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)
       {
  @@ -77,8 +76,10 @@
        * Adds a <code>toString()</code> method to a class that returns a fixed,
        * pre-computed value.
        * 
  -     * @param classFab ClassFab used to construct the new class.
  -     * @param toStringResult fixed result to be returned by the method.
  +     * @param classFab
  +     *            ClassFab used to construct the new class.
  +     * @param toStringResult
  +     *            fixed result to be returned by the method.
        */
       public static void addToStringMethod(ClassFab classFab, String toStringResult)
       {
  @@ -88,10 +89,28 @@
           buffer.append(QUOTE);
           buffer.append(";");
   
  -        classFab.addMethod(
  -            Modifier.PUBLIC,
  -            new MethodSignature(String.class, "toString", null, null),
  -            buffer.toString());
  +        classFab.addMethod(Modifier.PUBLIC, new MethodSignature(String.class, "toString",
null, null), buffer
  +                .toString());
       }
   
  -}
  +    /**
  +     * Returns the class of an instance. However, if the instance is, in fact, a
  +     * JDK proxy, returns the interfaceClass (because JDK proxies do not work
  +     * with Javassist).
  +     * 
  +     * @param instance
  +     *            the object instance to obtain a class from
  +     * @param interfaceClass
  +     *            the interface class to return if the instance is a JDK proxy.
  +     */
  +    public static Class getInstanceClass(Object instance, Class interfaceClass)
  +    {
  +        Class instanceClass = instance.getClass();
  +
  +        if (Proxy.isProxyClass(instanceClass))
  +            return interfaceClass;
  +
  +        return instanceClass;
  +    }
  +
  +}
  \ 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