hlship      2003/07/09 04:27:26

  Modified:    hivemind/xdocs index.xml
               hivemind .classpath project.xml
               hivemind/src/java/org/apache/commons/hivemind/service/impl
                        LoggingInterceptorFactory.java
               hivemind/src/java/org/apache/commons/hivemind
                        HiveMindMessages.properties HiveMind.java
               hivemind/src/test/hivemind/test/services/impl
                        CountFactory.java
               hivemind/src/test/hivemind/test/services TestServices.java
               hivemind/src/META-INF hivemodule.xml
               hivemind/src/test/hivemind/test HiveMindTestCase.java
               hivemind/src/test-data/sample org.example.toolbar.ui.xml
               hivemind/src/test-data/TestConstructRegistry testBasic.xml
                        testUptoDate.xml
  Added:       hivemind/src/java/org/apache/commons/hivemind/service
                        MethodFab.java ClassFactory.java ClassFab.java
               hivemind/src/java/org/apache/commons/hivemind/service/impl
                        ClassFactoryImpl.java ClassFabImpl.java
                        AbstractServiceInterceptorFactory.java
                        MethodFabImpl.java AbstractLoggingInterceptor.java
  Log:
  Add infrastructure for creating interceptor classes dynamically using Javassist.
  
  Revision  Changes    Path
  1.3       +4 -5      jakarta-commons-sandbox/hivemind/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/index.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- index.xml 30 Jun 2003 23:04:28 -0000      1.2
  +++ index.xml 9 Jul 2003 11:27:23 -0000       1.3
  @@ -184,10 +184,9 @@
       the application.
       </p>
       
  -    <p>The <a href="base-registry.html">HiveMind module descriptor documentation</a>
  -    gives a general idea of what the documentation looks like.  Since its 
documentation
  -    for just the core HiveMind module, it doesn't really show off the bells and 
whistles
  -    you get when multiple modules work together.
  +    <p>The <a href="sample-registry/index.html">HiveMind module descriptor 
documentation</a>
  +    gives a general idea of what the documentation looks like, using a hypothetical
  +    collection of module descriptors.
       </p>
       
       </section>
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/MethodFab.java
  
  Index: MethodFab.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service;
  
  /**
   * Represents a created method on a class; used to add catch handlers.
   * @see org.apache.commons.hivemind.service.ClassFab#addMethod(String, Class, 
Class[], Class[], String)
   *
   * @author Howard Lewis Ship
   * @version $Id: MethodFab.java,v 1.1 2003/07/09 11:27:23 hlship Exp $
   */
  public interface MethodFab
  {
        /**
         * Adds a catch to the method.  The body must end with a return or throw.
         */
      public void addCatch(Class exceptionClass, String catchBody);
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/ClassFactory.java
  
  Index: ClassFactory.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service;
  
  /**
   * Service used when dynamically creating new classes.
   *
   * @author Howard Lewis Ship
   * @version $Id: ClassFactory.java,v 1.1 2003/07/09 11:27:23 hlship Exp $
   */
  public interface ClassFactory
  {
        /**
         * Creates a [EMAIL PROTECTED] ClassFab} object for the given name; the new 
class
         * is a subclass of the indicated class.  The new class
         * is public and concrete.
         */
        
        public ClassFab newClass(String name, Class superClass);
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/ClassFab.java
  
  Index: ClassFab.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service;
  
  /**
   * Used when fabricating a new class.  Represents a wrapper around
   * the Javassist library.
   *
   * @author Howard Lewis Ship
   * @version $Id: ClassFab.java,v 1.1 2003/07/09 11:27:23 hlship Exp $
   */
  public interface ClassFab
  {
      /**
       * Adds the specified interface as an interface implemented by this class.
       */
      public void addInterface(Class interfaceClass);
  
      /**
       * Adds a new field with the given name and type.  The field is
       * added as a private field.
       */
  
      public void addField(String name, Class type);
  
      /**
       * Adds a method.  The method is a public instance method.
       * @return a method fabricator, used to add catch handlers.
       * @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.
       * @param exceptions The types of all declared exceptions, or null if the method 
throws no exceptions.
       * @param body The body of the method.
       */
  
      public MethodFab addMethod(
          String name,
          Class returnType,
          Class[] parameterTypes,
          Class[] exceptions,
          String body);
  
      /**
       * Adds a constructor to the class.  The constructor will be public.
       * @param parameterTypes the type of each parameter, or null if the constructor 
takes no parameters.
       * @param exceptions the type of each exception, or null if the constructor 
throws no exceptions.
       * @param body The body of the constructor.
       */
      public void addConstructor(Class[] parameterTypes, Class[] exceptions, String 
body);
  
      /**
       * Invoked last to create the class.  This will enforce that
       * all abstract methods have been implemented in the (concrete) class.
       */
      public Class createClass();
  }
  
  
  
  1.8       +3 -0      jakarta-commons-sandbox/hivemind/.classpath
  
  Index: .classpath
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/.classpath,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- .classpath        26 Jun 2003 20:31:26 -0000      1.7
  +++ .classpath        9 Jul 2003 11:27:23 -0000       1.8
  @@ -20,5 +20,8 @@
       <classpathentry kind="var" path="MAVEN_REPO/ant/jars/ant-1.5.1.jar"/>
       <classpathentry kind="var" 
path="MAVEN_REPO/tapestry/jars/tapestry-3.0-beta-1a.jar"/>
       <classpathentry kind="var" path="MAVEN_REPO/jboss/jars/jboss-j2ee-3.2.1.jar"/>
  +    <classpathentry kind="var" path="MAVEN_REPO/mx4j/jars/mx4j-jmx-1.1.1.jar"/>
  +    <classpathentry kind="var"
  +        path="MAVEN_REPO/javassist/jars/javassist-2.5.1.jar" 
sourcepath="DOWNLOADS/Misc/javassist-2.5.1.zip"/>
       <classpathentry kind="output" path="bin"/>
   </classpath>
  
  
  
  1.11      +7 -1      jakarta-commons-sandbox/hivemind/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/project.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- project.xml       26 Jun 2003 20:31:26 -0000      1.10
  +++ project.xml       9 Jul 2003 11:27:23 -0000       1.11
  @@ -161,7 +161,13 @@
        <artifactId>jboss-j2ee</artifactId>
        <version>3.2.1</version>
       </dependency>
  +    
  +    <dependency>
  +     <id>javassist</id>      
  +     <version>2.5.1</version>
  +    </dependency>
     </dependencies>
  +  
   
     <build>
   
  
  
  
  1.3       +83 -91    
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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LoggingInterceptorFactory.java    1 Jul 2003 11:28:53 -0000       1.2
  +++ LoggingInterceptorFactory.java    9 Jul 2003 11:27:24 -0000       1.3
  @@ -57,13 +57,11 @@
   
   package org.apache.commons.hivemind.service.impl;
   
  -import java.lang.reflect.InvocationHandler;
  -import java.lang.reflect.InvocationTargetException;
  -import java.lang.reflect.Method;
  -import java.lang.reflect.Proxy;
  +import java.lang.reflect.Constructor;
   
  -import org.apache.commons.hivemind.ServiceInterceptorFactory;
   import org.apache.commons.hivemind.InterceptorStack;
  +import org.apache.commons.hivemind.service.ClassFab;
  +import org.apache.commons.hivemind.service.MethodFab;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -83,117 +81,111 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class LoggingInterceptorFactory implements ServiceInterceptorFactory
  +public class LoggingInterceptorFactory extends AbstractServiceInterceptorFactory
   {
  -    private static class Handler implements InvocationHandler
  -    {
  -        private static final int BUFFER_SIZE = 100;
  +    private static final String QUOTE = "\"";
   
  -        private Log _log;
  -        private Object _inner;
  +    protected void createInfrastructure(Class serviceInterfaceClass, ClassFab 
classFab)
  +    {
  +        classFab.addField("_inner", serviceInterfaceClass);
   
  -        private Handler(Log log, Object inner)
  -        {
  -            _log = log;
  -            _inner = inner;
  -        }
  +        classFab.addConstructor(
  +            new Class[] { Log.class, serviceInterfaceClass },
  +            null,
  +            "{ super($1); _inner = $2; }");
  +    }
   
  -        public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable
  -        {
  -            boolean debug = _log.isDebugEnabled();
  +    protected void createMethod(
  +        ClassFab classFab,
  +        String methodName,
  +        Class returnType,
  +        Class[] parameterTypes,
  +        Class[] exceptions)
  +    {
  +        boolean isVoid = (returnType == void.class);
   
  -            if (debug)
  -                logEntry(method, args);
  +        StringBuffer buffer = new StringBuffer(100);
   
  -            try
  -            {
  -                Object result = method.invoke(_inner, args);
  -
  -                if (debug)
  -                    logExit(method, result);
  -
  -                return result;
  -            }
  -            catch (InvocationTargetException ex)
  -            {
  -             Throwable t = ex.getTargetException();
  -             
  -                logException(method, t);
  +        buffer.append("{\n\n");
  +        
  +        buffer.append("boolean debug = _isDebugEnabled();\n\n");
  +
  +        buffer.append("if (debug) _logEntry(" + QUOTE);
  +        buffer.append(methodName);
  +        buffer.append(QUOTE + ", $args);\n\n");
  +
  +             if (!isVoid)
  +             {
  +                     // May need work, for arrays and such.
  +                     buffer.append(returnType);
  +                     buffer.append(" result = ");
  +             }
  +             
  +        buffer.append("_inner.");
  +        buffer.append(methodName);
  +        buffer.append("($$);\n\n");
   
  -                throw t;
  -            }
  +        if (isVoid)
  +        {
  +            buffer.append("if (debug) _logVoidExit(" + QUOTE);
  +            buffer.append(methodName);
  +            buffer.append(QUOTE + ");");
           }
  -
  -        private void logEntry(Method m, Object[] args)
  +        else
           {
  -            StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  -
  -            buffer.append("BEGIN ");
  -            buffer.append(m.getName());
  -            buffer.append("(");
  +            buffer.append("if (debug) _logExit(" + QUOTE);
  +            buffer.append(methodName);
  +            buffer.append(QUOTE + ", ($w)result);\n\n");
  +            buffer.append("return result;");
  +        }
   
  -            int count = (args == null) ? 0 : args.length;
  +        buffer.append("\n\n}");
   
  -            for (int i = 0; i < count; i++)
  -            {
  -                Object arg = args[i];
  +        String body = buffer.toString();
   
  -                if (i > 0)
  -                    buffer.append(", ");
  +        MethodFab methodFab =
  +            classFab.addMethod(methodName, returnType, parameterTypes, exceptions, 
body);
   
  -                buffer.append(arg);
  -            }
  +        int count = exceptions == null ? 0 : exceptions.length;
   
  -            buffer.append(")");
  +        if (count == 0)
  +            return;
   
  -            _log.debug(buffer.toString());
  -        }
  +        buffer.setLength(0);
   
  -        private void logExit(Method m, Object result)
  -        {
  -            StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  +        buffer.append("{\n\n");
  +        buffer.append("_logException(" + QUOTE);
  +        buffer.append(methodName);
  +        buffer.append(QUOTE + ", $e);\n\n");
  +        buffer.append("throw $e;");
  +        buffer.append("\n\n}");
   
  -            buffer.append("END ");
  -            buffer.append(m.getName());
  -            buffer.append("()");
  -
  -            if (m.getReturnType() != void.class)
  -            {
  -                buffer.append(" [");
  -                buffer.append(result);
  -                buffer.append("]");
  -            }
  -
  -            _log.debug(buffer.toString());
  -        }
  +        body = buffer.toString();
   
  -        private void logException(Method m, Throwable t)
  +        for (int i = 0; i < count; i++)
           {
  -            StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  -
  -            buffer.append("EXCEPTION ");
  -            buffer.append(m.getName());
  -            buffer.append("() -- ");
  -
  -            buffer.append(t.getClass().getName());
  -
  -            _log.debug(buffer.toString(), t);
  +            methodFab.addCatch(exceptions[i], body);
           }
  +    }
   
  +    protected Class getInterceptorSuperclass()
  +    {
  +        return AbstractLoggingInterceptor.class;
       }
   
  -    public void createInterceptor(InterceptorStack stack)
  +    protected Object instantiateInterceptor(
  +        InterceptorStack stack,
  +        Class serviceInterfaceClass,
  +        Object stackTop,
  +        Class interceptorClass)
  +        throws Exception
       {
  -        String id = stack.getServiceExtensionPoint().getExtensionPointId();
  -        Log log = LogFactory.getLog(id);
  -        ClassLoader loader =
  -            
stack.getServiceExtensionPoint().getModule().getResourceResolver().getClassLoader();
  -        InvocationHandler handler = new Handler(log, stack.peek());
  +        Log log = 
LogFactory.getLog(stack.getServiceExtensionPoint().getExtensionPointId());
   
  -        Object interceptor =
  -            Proxy.newProxyInstance(loader, new Class[] { 
stack.getServiceInterface()}, handler);
  +        Constructor c =
  +            interceptorClass.getConstructor(new Class[] { Log.class, 
serviceInterfaceClass });
   
  -        stack.push(interceptor);
  +        return c.newInstance(new Object[] { log, stackTop });
       }
   
   }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFactoryImpl.java
  
  Index: ClassFactoryImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service.impl;
  
  import javassist.ClassPool;
  import javassist.CtClass;
  import javassist.NotFoundException;
  
  import org.apache.commons.hivemind.HiveMind;
  import org.apache.commons.hivemind.service.ClassFab;
  import org.apache.commons.hivemind.service.ClassFactory;
  import org.apache.tapestry.ApplicationRuntimeException;
  
  /**
   * Implementation of [EMAIL PROTECTED] 
org.apache.commons.hivemind.service.ClassFactory}.
   *
   * @author Howard Lewis Ship
   * @version $Id: ClassFactoryImpl.java,v 1.1 2003/07/09 11:27:24 hlship Exp $
   */
  public class ClassFactoryImpl implements ClassFactory
  {
      private ClassPool _pool = ClassPool.getDefault();
  
      public ClassFab newClass(String name, Class superClass)
      {
          // TODO: Class loading issues.  Ensure that class loader for superClass
          // is known to _pool.
          CtClass ctSuperClass = getClass(superClass);
  
          try
          {
              CtClass ctNewClass = _pool.makeClass(name, ctSuperClass);
  
              return new ClassFabImpl(this, ctNewClass);
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ClassFactoryImpl.unable-to-create-class",
                      name,
                      superClass.getName(),
                      ex.getMessage()),
                  ex);
          }
  
      }
  
      public CtClass getClass(Class inputClass)
      {
          try
          {
              return _pool.get(inputClass.getName());
          }
          catch (NotFoundException ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format("ClassFactoryImpl.unable-to-lookup", inputClass, 
ex.getMessage()),
                  ex);
          }
      }
  
      public Class createClass(CtClass _ctClass)
      {
          try
          {
              return _pool.writeAsClass(_ctClass.getName());
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ClassFactoryImpl.unable-to-write-class",
                      _ctClass.getName(),
                      ex.getMessage()),
                  ex);
          }
      }
  
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/ClassFabImpl.java
  
  Index: ClassFabImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service.impl;
  
  import javassist.CannotCompileException;
  import javassist.CtClass;
  import javassist.CtConstructor;
  import javassist.CtField;
  import javassist.CtMethod;
  
  import org.apache.commons.hivemind.HiveMind;
  import org.apache.commons.hivemind.service.ClassFab;
  import org.apache.commons.hivemind.service.MethodFab;
  import org.apache.tapestry.ApplicationRuntimeException;
  
  public class ClassFabImpl implements ClassFab
  {
      private ClassFactoryImpl _factory;
      private CtClass _ctClass;
  
      public ClassFabImpl(ClassFactoryImpl factory, CtClass ctClass)
      {
          _factory = factory;
          _ctClass = ctClass;
      }
  
      public void addInterface(Class interfaceClass)
      {
          CtClass ctInterfaceClass = _factory.getClass(interfaceClass);
  
          _ctClass.addInterface(ctInterfaceClass);
      }
  
      public void addField(String name, Class type)
      {
          CtClass ctType = _factory.getClass(type);
  
          try
          {
              CtField field = new CtField(ctType, name, _ctClass);
  
              _ctClass.addField(field);
          }
          catch (CannotCompileException ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ClassFabImpl.unable-to-add-field",
                      name,
                      _ctClass.getName(),
                      ex.getMessage()),
                  ex);
          }
      }
  
      public MethodFab addMethod(
          String name,
          Class returnType,
          Class[] parameterTypes,
          Class[] exceptions,
          String body)
      {
          CtClass ctReturnType = _factory.getClass(returnType);
          CtClass[] ctParameters = convertClasses(parameterTypes);
          CtClass[] ctExceptions = convertClasses(exceptions);
  
          CtMethod method = new CtMethod(ctReturnType, name, ctParameters, _ctClass);
  
          try
          {
              method.setExceptionTypes(ctExceptions);
              method.setBody(body);
  
              _ctClass.addMethod(method);
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ClassFabImpl.unable-to-add-method",
                      name,
                      _ctClass.getName(),
                      ex.getMessage()),
                  ex);
          }
  
          // Return a MethodFab so the caller can add catches.
  
          return new MethodFabImpl(_factory, method);
  
      }
  
      public void addConstructor(Class[] parameterTypes, Class[] exceptions, String 
body)
      {
          CtClass[] ctParameters = convertClasses(parameterTypes);
          CtClass[] ctExceptions = convertClasses(exceptions);
  
          try
          {
              CtConstructor constructor = new CtConstructor(ctParameters, _ctClass);
              constructor.setExceptionTypes(ctExceptions);
              constructor.setBody(body);
  
              _ctClass.addConstructor(constructor);
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "ClassFabImpl.unable-to-add-constructor",
                      _ctClass.getName(),
                      ex.getMessage()),
                  ex);
          }
      }
  
      private CtClass[] convertClasses(Class[] inputClasses)
      {
          if (inputClasses == null || inputClasses.length == 0)
              return null;
  
          int count = inputClasses.length;
          CtClass[] result = new CtClass[count];
  
          for (int i = 0; i < count; i++)
          {
              CtClass ctClass = _factory.getClass(inputClasses[i]);
  
              result[i] = ctClass;
          }
  
          return result;
      }
  
      public Class createClass()
      {
          return _factory.createClass(_ctClass);
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/AbstractServiceInterceptorFactory.java
  
  Index: AbstractServiceInterceptorFactory.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service.impl;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.util.LinkedList;
  
  import org.apache.commons.hivemind.HiveMind;
  import org.apache.commons.hivemind.InitializeService;
  import org.apache.commons.hivemind.InterceptorStack;
  import org.apache.commons.hivemind.ServiceExtensionPoint;
  import org.apache.commons.hivemind.ServiceInterceptorFactory;
  import org.apache.commons.hivemind.service.ClassFab;
  import org.apache.commons.hivemind.service.ClassFactory;
  import org.apache.tapestry.ApplicationRuntimeException;
  
  /**
   * Base class for creating new service interceptors.  Most implementations
   * merely have to implement [EMAIL PROTECTED] #createMethod(ClassFab, String, Class, 
Class[], Class[])}.
   *
   * @author Howard Lewis Ship
   * @version $Id: AbstractServiceInterceptorFactory.java,v 1.1 2003/07/09 11:27:24 
hlship Exp $
   */
  public abstract class AbstractServiceInterceptorFactory
      implements ServiceInterceptorFactory, InitializeService
  {
      private ClassFactory _factory;
      private String _extensionId;
      private String _baseName;
      private int _uid;
  
      public void createInterceptor(InterceptorStack stack)
      {
          Class serviceInterfaceClass = stack.getServiceInterface();
  
          String name = _baseName + _uid++;
  
          ClassFab classFab = _factory.newClass(name, getInterceptorSuperclass());
  
          classFab.addInterface(serviceInterfaceClass);
  
          createInfrastructure(serviceInterfaceClass, classFab);
  
          createMethods(serviceInterfaceClass, classFab);
  
          Class interceptorClass = classFab.createClass();
  
          try
          {
  
              Object interceptor =
                  instantiateInterceptor(
                      stack,
                      serviceInterfaceClass,
                      stack.peek(),
                      interceptorClass);
  
              stack.push(interceptor);
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "AbstractServiceExtensionPoint.error-instantiating-interceptor",
                      new Object[] {
                          _extensionId,
                          serviceInterfaceClass.getName(),
                          stack.getServiceExtensionPoint().getExtensionPointId(),
                          interceptorClass.getName(),
                          ex.getMessage()}),
                  ex);
          }
      }
  
      /**
       * Looks up the [EMAIL PROTECTED] ClassFactory} in the registry.
       */
      public void initializeService(ServiceExtensionPoint point, Object service)
      {
          _extensionId = point.getExtensionPointId();
  
          _baseName = _extensionId.replace('.', '$') + "$interceptor_";
  
          _factory =
              (ClassFactory) point.getModule().getRegistry().getService(
                  HiveMind.CLASS_FACTORY_SERVICE_ID,
                  ClassFactory.class);
      }
  
      /**
       * Overridden in subclasses to identify the super-class
       * for the interceptor.  This implementation returns java.lang.Object.
       */
  
      protected Class getInterceptorSuperclass()
      {
          return Object.class;
      }
  
      /**
       * Invoked in subclasses to create any infrastructure. 
       * <p>This implementation creates a field, <code>_inner</code> whose
       * type matches the service interface, and
       * a constructor to set the field.
       * 
       */
      protected void createInfrastructure(Class serviceInterfaceClass, ClassFab 
classFab)
      {
          classFab.addField("_inner", serviceInterfaceClass);
          classFab.addConstructor(new Class[] { serviceInterfaceClass }, null, "_inner 
= $1;");
      }
  
      /**
       * Invoked for each method in the service interface to allow the factory to
       * construct the corresponding method in the interceptor.
       */
  
      protected abstract void createMethod(
          ClassFab classFab,
          String methodName,
          Class returnType,
          Class[] parameterTypes,
          Class[] exceptions);
  
      /**
       * Used to instantiate the interceptor.  This implementation passes the top 
object
       * on the interceptor stack to the interceptorClass' constructor.
       * 
       * @param stack the interceptor stack on which the returned interceptor will be 
placed.
       * @param serviceInterfaceClass the class for the interface
       * @param stackTop the top object on the stack (which may be the core 
implementation, or
       * another interceptor)
       * @param interceptorClass the generated class for the interceptor.
       * 
       * @throws Exception if there is an error getting or invoking the constructor
       * @see #createInfrastructure(Class, ClassFab)
       */
      protected Object instantiateInterceptor(
          InterceptorStack stack,
          Class serviceInterfaceClass,
          Object stackTop,
          Class interceptorClass)
          throws Exception
      {
          Constructor c = interceptorClass.getConstructor(new Class[] { 
serviceInterfaceClass });
  
          return c.newInstance(new Object[] { stackTop });
  
      }
  
      private void createMethods(Class serviceInterfaceClass, ClassFab fab)
      {
          Method[] methods = serviceInterfaceClass.getMethods();
  
          int count = methods.length;
          for (int i = 0; i < count; i++)
          {
              Method m = methods[i];
              createMethod(
                  fab,
                  m.getName(),
                  m.getReturnType(),
                  m.getParameterTypes(),
                  m.getExceptionTypes());
          }
      }
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/MethodFabImpl.java
  
  Index: MethodFabImpl.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service.impl;
  
  import javassist.CtClass;
  import javassist.CtMethod;
  
  import org.apache.commons.hivemind.HiveMind;
  import org.apache.commons.hivemind.service.MethodFab;
  import org.apache.tapestry.ApplicationRuntimeException;
  
  public class MethodFabImpl implements MethodFab
  {
      private ClassFactoryImpl _factory;
      private CtMethod _method;
  
      public MethodFabImpl(ClassFactoryImpl factory, CtMethod method)
      {
          _factory = factory;
          _method = method;
      }
  
      public void addCatch(Class exceptionClass, String catchBody)
      {
          CtClass ctException = _factory.getClass(exceptionClass);
  
          try
          {
              _method.addCatch(catchBody, ctException);
          }
          catch (Exception ex)
          {
              throw new ApplicationRuntimeException(
                  HiveMind.format(
                      "MethodFabImpl.unable-to-add-catch",
                      exceptionClass.getName(),
                      _method.getDeclaringClass().getName(),
                      ex.getMessage()),
                  ex);
          }
      }
  
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/service/impl/AbstractLoggingInterceptor.java
  
  Index: AbstractLoggingInterceptor.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.commons.hivemind.service.impl;
  
  import org.apache.commons.logging.Log;
  
  /**
   * Base class used to dynamically build logging interceptors.
   * [EMAIL PROTECTED] 
org.apache.commons.hivemind.service.impl.LoggingInterceptorFactory}
   * will create a subclass dynamically.
   *
   * @author Howard Lewis Ship
   * @version $Id: AbstractLoggingInterceptor.java,v 1.1 2003/07/09 11:27:24 hlship 
Exp $
   */
  public abstract class AbstractLoggingInterceptor
  {
      private static final int BUFFER_SIZE = 100;
  
      private Log _log;
  
      protected AbstractLoggingInterceptor(Log log)
      {
          _log = log;
      }
  
      protected void _logEntry(String methodName, Object[] args)
      {
          StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  
          buffer.append("BEGIN ");
          buffer.append(methodName);
          buffer.append("(");
  
          int count = (args == null) ? 0 : args.length;
  
          for (int i = 0; i < count; i++)
          {
              Object arg = args[i];
  
              if (i > 0)
                  buffer.append(", ");
  
              buffer.append(arg);
          }
  
          buffer.append(")");
  
          _log.debug(buffer.toString());
      }
  
      protected void _logExit(String methodName, Object result)
      {
          StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  
          buffer.append("END ");
          buffer.append(methodName);
          buffer.append("() [");
          buffer.append(result);
          buffer.append("]");
  
          _log.debug(buffer.toString());
      }
  
      protected void _logVoidExit(String methodName)
      {
          StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  
          buffer.append("END ");
          buffer.append(methodName);
          buffer.append("()");
  
          _log.debug(buffer.toString());
      }
  
      protected void _logException(String methodName, Throwable t)
      {
          StringBuffer buffer = new StringBuffer(BUFFER_SIZE);
  
          buffer.append("EXCEPTION ");
          buffer.append(methodName);
          buffer.append("() -- ");
  
          buffer.append(t.getClass().getName());
  
          _log.debug(buffer.toString(), t);
      }
  
      protected boolean _isDebugEnabled()
      {
          return _log.isDebugEnabled();
      }
  
  }
  
  
  1.10      +17 -1     
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMindMessages.properties
  
  Index: HiveMindMessages.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMindMessages.properties,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- HiveMindMessages.properties       2 Jul 2003 21:41:12 -0000       1.9
  +++ HiveMindMessages.properties       9 Jul 2003 11:27:24 -0000       1.10
  @@ -60,6 +60,22 @@
   
   MessagesImpl.unable-to-read=Unable to read message properties from {0}.
   
  +# javassist package
  +
  +AbstractServiceExtensionPoint.error-instantiating-interceptor=Service interceptor 
factory {0} failed to create {1} interceptor for service {2} as class {3}: {4}
  +
  +# javassist.impl package
  +
  +ClassFactoryImpl.unable-to-lookup=Unable to lookup {0}: {1}
  +ClassFactoryImpl.unable-to-create-class=Unable to create class {0} as subclass of 
{1}: {2}
  +ClassFactoryImpl.unable-to-write-class=Unable to create class {0}: {2}
  +
  +ClassFabImpl.unable-to-add-field=Unable to add field {0} to class {1}: {2}
  +ClassFabImpl.unable-to-add-method=Unable to add method {0} to class {1}: {2}
  +ClassFabImpl.unable-to-add-constructor=Unable to add constructor to class {0}: {1}
  +
  +MethodFabImpl.unable-to-add-catch=Unable to add catch block for exception {0} to 
class {1}: {2}
  +
   # parse package
   
   InstanceBuilderDescriptor.unable-to-set-property=Unable to set property {0} of {1} 
to {2}: {3}
  
  
  
  1.8       +8 -1      
jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMind.java
  
  Index: HiveMind.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/java/org/apache/commons/hivemind/HiveMind.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- HiveMind.java     2 Jul 2003 15:40:43 -0000       1.7
  +++ HiveMind.java     9 Jul 2003 11:27:24 -0000       1.8
  @@ -90,6 +90,13 @@
        */
       public static final String NAME_LOOKUP_SERVICE_ID = 
"org.apache.commons.hivemind.NameLookup";
   
  +    /**
  +     * Service id for the [EMAIL PROTECTED] 
org.apache.commons.hivemind.service.ClassFactory} service.
  +     */
  +
  +    public static final String CLASS_FACTORY_SERVICE_ID =
  +        "org.apache.commons.hivemind.ClassFactory";
  +
       private static Registry _registry;
       private static final ResourceBundle _bundle;
   
  
  
  
  1.5       +21 -25    
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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- CountFactory.java 30 Jun 2003 23:08:13 -0000      1.4
  +++ CountFactory.java 9 Jul 2003 11:27:25 -0000       1.5
  @@ -63,6 +63,8 @@
   
   import org.apache.commons.hivemind.ServiceInterceptorFactory;
   import org.apache.commons.hivemind.InterceptorStack;
  +import org.apache.commons.hivemind.service.ClassFab;
  +import org.apache.commons.hivemind.service.impl.AbstractServiceInterceptorFactory;
   
   /**
    * Simple factory that uses dynamic proxies to count the number of times
  @@ -71,7 +73,7 @@
    * @author Howard Lewis Ship
    * @version $Id$
    */
  -public class CountFactory implements ServiceInterceptorFactory
  +public class CountFactory extends AbstractServiceInterceptorFactory
   {
       private static int _count = 0;
   
  @@ -85,33 +87,27 @@
           _count = 0;
       }
   
  -    public static class CountHandler implements InvocationHandler
  +    public static void incrementCount()
       {
  -        private Object _inner;
  -
  -        public CountHandler(Object inner)
  -        {
  -            _inner = inner;
  -        }
  -
  -        public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable
  -        {
  -            _count++;
  -
  -            return method.invoke(_inner, args);
  -        }
  -
  +        _count++;
       }
   
  -    public void createInterceptor(InterceptorStack stack)
  +    protected void createMethod(
  +        ClassFab classFab,
  +        String methodName,
  +        Class returnType,
  +        Class[] parameterTypes,
  +        Class[] exceptions)
       {
  -        Class interfaceClass = stack.getServiceInterface();
  -        ClassLoader loader = stack.getResourceResolver().getClassLoader();
  -        Object top = stack.peek();
  +        StringBuffer body = new StringBuffer();
  +        body.append("{\n\n");
  +        
body.append("hivemind.test.services.impl.CountFactory#incrementCount();\n\n");
  +        body.append("return ($r) _inner.");
  +        body.append(methodName);
  +        body.append("($$);\n\n");
  +        body.append("}");
   
  -        Object interceptor =
  -            Proxy.newProxyInstance(loader, new Class[] { interfaceClass }, new 
CountHandler(top));
  -
  -        stack.push(interceptor);
  +        classFab.addMethod(methodName, returnType, parameterTypes, exceptions, 
body.toString());
       }
  +
   }
  
  
  
  1.12      +6 -25     
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.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- TestServices.java 2 Jul 2003 21:41:14 -0000       1.11
  +++ TestServices.java 9 Jul 2003 11:27:25 -0000       1.12
  @@ -66,11 +66,8 @@
   
   import java.rmi.RemoteException;
   import java.util.List;
  -import java.util.Locale;
   
   import org.apache.commons.hivemind.Registry;
  -import org.apache.commons.hivemind.impl.RegistryBuilder;
  -import org.apache.commons.hivemind.parse.DescriptorParser;
   import org.apache.tapestry.ApplicationRuntimeException;
   
   /**
  @@ -179,14 +176,10 @@
   
       public void testLogging() throws Exception
       {
  -        RegistryBuilder b = new RegistryBuilder();
  -        DescriptorParser p = new DescriptorParser();
  -        b.processModule(_resolver, p.parse(getMasterModuleLocation()));
  -        b.processModule(_resolver, p.parse(getLocation("TestLogging.xml")));
  -
           interceptLogging("hivemind.test.services.Demo");
   
  -        Registry r = b.constructRegistry(Locale.getDefault());
  +        Registry r = buildRegistry("TestLogging.xml");
  +
           DemoService s =
               (DemoService) r.getService("hivemind.test.services.Demo", 
DemoService.class);
   
  @@ -251,11 +244,7 @@
   
       public void testEJBProxy() throws Exception
       {
  -        RegistryBuilder b = new RegistryBuilder();
  -        DescriptorParser p = new DescriptorParser();
  -        b.processModule(_resolver, p.parse(getMasterModuleLocation()));
  -        b.processModule(_resolver, p.parse(getLocation("EJBProxy.xml")));
  -        Registry r = b.constructRegistry(Locale.getDefault());
  +        Registry r = buildRegistry("EJBProxy.xml");
   
           SimpleHomeImpl home = new SimpleHomeImpl();
           FakeContext context = new FakeContext();
  @@ -272,11 +261,7 @@
   
       public void testEJBProxyNameFailure() throws Exception
       {
  -        RegistryBuilder b = new RegistryBuilder();
  -        DescriptorParser p = new DescriptorParser();
  -        b.processModule(_resolver, p.parse(getMasterModuleLocation()));
  -        b.processModule(_resolver, p.parse(getLocation("EJBProxy.xml")));
  -        Registry r = b.constructRegistry(Locale.getDefault());
  +             Registry r = buildRegistry("EJBProxy.xml");
   
           FakeContext context = new FakeContext();
           context.setForceError(true);
  @@ -304,11 +289,7 @@
   
       public void testEJBProxyRemoteFailure() throws Exception
       {
  -        RegistryBuilder b = new RegistryBuilder();
  -        DescriptorParser p = new DescriptorParser();
  -        b.processModule(_resolver, p.parse(getMasterModuleLocation()));
  -        b.processModule(_resolver, p.parse(getLocation("EJBProxy.xml")));
  -        Registry r = b.constructRegistry(Locale.getDefault());
  +             Registry r = buildRegistry("EJBProxy.xml");
   
           SimpleHomeImpl home = new SimpleHomeImpl();
           home.setForceError(true);
  
  
  
  1.6       +7 -2      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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- hivemodule.xml    2 Jul 2003 15:40:43 -0000       1.5
  +++ hivemodule.xml    9 Jul 2003 11:27:25 -0000       1.6
  @@ -12,7 +12,12 @@
                <description>Provides a list of sources for substitution 
symbols.</description>
        </configuration>
        
  -     <service id="LoggingInterceptor" 
interface="org.apache.commons.hivemind.ServiceInterceptorFactory">
  +     <service id="ClassFactory" 
interface="org.apache.commons.hivemind.service.ClassFactory">
  +             <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">
                <description>An interceptor factory for adding method-level logging to 
a service.</description>
                <create-instance 
class="org.apache.commons.hivemind.service.impl.LoggingInterceptorFactory"/>
        </service>
  
  
  
  1.12      +3 -1      
jakarta-commons-sandbox/hivemind/src/test/hivemind/test/HiveMindTestCase.java
  
  Index: HiveMindTestCase.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/test/hivemind/test/HiveMindTestCase.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- HiveMindTestCase.java     2 Jul 2003 21:41:12 -0000       1.11
  +++ HiveMindTestCase.java     9 Jul 2003 11:27:25 -0000       1.12
  @@ -116,6 +116,8 @@
               builder.processModule(_resolver, md);
           }
   
  +             builder.processModule(_resolver, 
_parser.parse(getMasterModuleLocation()));
  +
           return builder.constructRegistry(Locale.getDefault());
       }
   
  
  
  
  1.4       +4 -4      
jakarta-commons-sandbox/hivemind/src/test-data/sample/org.example.toolbar.ui.xml
  
  Index: org.example.toolbar.ui.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/test-data/sample/org.example.toolbar.ui.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- org.example.toolbar.ui.xml        26 Jun 2003 20:31:31 -0000      1.3
  +++ org.example.toolbar.ui.xml        9 Jul 2003 11:27:25 -0000       1.4
  @@ -16,7 +16,7 @@
                </description>
                
                <new>
  -                     <set property="label" value="Quit"/>
  +                     <set-message property="label" key="quit.label"/>
                        <set property="mneumonic" value="Q"/>
                        <set property="order" value="1"/>
                        <set-create property="callback" 
class="org.example.ui.toolbar.impl.QuitCallback"/>              
  @@ -30,10 +30,10 @@
                <interceptor 
service-id="org.apache.commons.hivemind.LoggingInterceptor"/>
        </service>
        
  -     <contribute-configuration 
configuration-id="org.apache.commons.hivemind.VariableSource">
  +     <contribute-configuration 
configuration-id="org.apache.commons.hivemind.SymbolSource">
                <new>
                         <set property="order" value="100"/>
  -                      <set-create property="source" 
class="org.example.toolbar.ui.impl.PreferencesVariableSource"/>
  +                      <set-create property="source" 
class="org.example.toolbar.ui.impl.PreferencesSymbolSource"/>
                </new>  
        </contribute-configuration>
        
  
  
  
  1.6       +13 -7     
jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/testBasic.xml
  
  Index: testBasic.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/testBasic.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- testBasic.xml     2 Jul 2003 15:40:43 -0000       1.5
  +++ testBasic.xml     9 Jul 2003 11:27:25 -0000       1.6
  @@ -7,15 +7,21 @@
               id="org.apache.commons.hivemind.SymbolSource" uid="3">
               <description>Provides a list of sources for substitution 
symbols.</description>
           </configuration>
  +        <service id="org.apache.commons.hivemind.ClassFactory"
  +            interface="org.apache.commons.hivemind.service.ClassFactory" uid="4">
  +            <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="org.apache.commons.hivemind.LoggingInterceptor"
  -            interface="org.apache.commons.hivemind.ServiceInterceptorFactory" 
uid="4">
  +            interface="org.apache.commons.hivemind.ServiceInterceptorFactory" 
uid="5">
               <description>An interceptor factory for adding method-level
                   logging to a service.</description>
               <create-instance 
class="org.apache.commons.hivemind.service.impl.LoggingInterceptorFactory"/>
           </service>
           <service
               id="org.apache.commons.hivemind.RemoteExceptionCoordinator"
  -            
interface="org.apache.commons.hivemind.service.RemoteExceptionCoordinator" uid="5">
  +            
interface="org.apache.commons.hivemind.service.RemoteExceptionCoordinator" uid="6">
               <description>Used to coordinate propogation of remote
                   exceptions (typically, to allow    cached remote data to
                   be discarded after a remote exception).</description>
  @@ -23,7 +29,7 @@
           </service>
           <service id="org.apache.commons.hivemind.NameLookup"
               interface="org.apache.commons.hivemind.service.NameLookup"
  -            overridable="true" required="false" uid="6">
  +            overridable="true" required="false" uid="7">
               <description>    A service which can perform name lookups of
                   objects; typically an implementation based on JNDI is
                   supplied.     The default implementation uses JNDI but
  @@ -32,7 +38,7 @@
               <create-instance 
class="org.apache.commons.hivemind.service.impl.NameLookupImpl"/>
           </service>
           <service id="org.apache.commons.hivemind.EJBProxyFactory"
  -            interface="org.apache.commons.hivemind.ServiceImplementationFactory" 
uid="7">
  +            interface="org.apache.commons.hivemind.ServiceImplementationFactory" 
uid="8">
               <description>   Core service implementation factory that
                   constructs dynamic proxies to EJB stateless session
                   beans.  A single parameter, the JNDI name of the proxy,
  @@ -40,16 +46,16 @@
               <create-instance 
class="org.apache.commons.hivemind.service.impl.EJBProxyFactory"/>
           </service>
       </module>
  -    <module id="hivemind.test.config" uid="8" version="1.0.0">
  +    <module id="hivemind.test.config" uid="9" version="1.0.0">
           <contribute-configuration
  -            configuration-id="org.apache.commons.hivemind.SymbolSource" uid="9">
  +            configuration-id="org.apache.commons.hivemind.SymbolSource" uid="10">
               <new>
                   <set-create
                       class="hivemind.test.external.PropertiesSymbolSource" 
property="source"/>
               </new>
           </contribute-configuration>
           <configuration element-type="java.lang.String"
  -            id="hivemind.test.config.Dogs" uid="10">
  +            id="hivemind.test.config.Dogs" uid="11">
               <value>${dog}</value>
           </configuration>
       </module>
  
  
  
  1.6       +12 -6     
jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/testUptoDate.xml
  
  Index: testUptoDate.xml
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/hivemind/src/test-data/TestConstructRegistry/testUptoDate.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- testUptoDate.xml  2 Jul 2003 15:40:43 -0000       1.5
  +++ testUptoDate.xml  9 Jul 2003 11:27:25 -0000       1.6
  @@ -7,15 +7,21 @@
               id="org.apache.commons.hivemind.SymbolSource" uid="3">
               <description>Provides a list of sources for substitution 
symbols.</description>
           </configuration>
  +        <service id="org.apache.commons.hivemind.ClassFactory"
  +            interface="org.apache.commons.hivemind.service.ClassFactory" uid="4">
  +            <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="org.apache.commons.hivemind.LoggingInterceptor"
  -            interface="org.apache.commons.hivemind.ServiceInterceptorFactory" 
uid="4">
  +            interface="org.apache.commons.hivemind.ServiceInterceptorFactory" 
uid="5">
               <description>An interceptor factory for adding method-level
                   logging to a service.</description>
               <create-instance 
class="org.apache.commons.hivemind.service.impl.LoggingInterceptorFactory"/>
           </service>
           <service
               id="org.apache.commons.hivemind.RemoteExceptionCoordinator"
  -            
interface="org.apache.commons.hivemind.service.RemoteExceptionCoordinator" uid="5">
  +            
interface="org.apache.commons.hivemind.service.RemoteExceptionCoordinator" uid="6">
               <description>Used to coordinate propogation of remote
                   exceptions (typically, to allow    cached remote data to
                   be discarded after a remote exception).</description>
  @@ -23,7 +29,7 @@
           </service>
           <service id="org.apache.commons.hivemind.NameLookup"
               interface="org.apache.commons.hivemind.service.NameLookup"
  -            overridable="true" required="false" uid="6">
  +            overridable="true" required="false" uid="7">
               <description>    A service which can perform name lookups of
                   objects; typically an implementation based on JNDI is
                   supplied.     The default implementation uses JNDI but
  @@ -32,7 +38,7 @@
               <create-instance 
class="org.apache.commons.hivemind.service.impl.NameLookupImpl"/>
           </service>
           <service id="org.apache.commons.hivemind.EJBProxyFactory"
  -            interface="org.apache.commons.hivemind.ServiceImplementationFactory" 
uid="7">
  +            interface="org.apache.commons.hivemind.ServiceImplementationFactory" 
uid="8">
               <description>   Core service implementation factory that
                   constructs dynamic proxies to EJB stateless session
                   beans.  A single parameter, the JNDI name of the proxy,
  @@ -40,8 +46,8 @@
               <create-instance 
class="org.apache.commons.hivemind.service.impl.EJBProxyFactory"/>
           </service>
       </module>
  -    <module id="hivemind.test.config" uid="8" version="1.0.0">
  +    <module id="hivemind.test.config" uid="9" version="1.0.0">
           <configuration count="1" element-type="java.lang.String"
  -            id="hivemind.test.config.Required" uid="9"/>
  +            id="hivemind.test.config.Required" uid="10"/>
       </module>
   </registry>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to