avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From blorit...@apache.org
Subject cvs commit: avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/handler AbstractComponentHandler.java PassThroughInvocationHandler.java ProxyHelper.java ProxyObjectFactory.java
Date Tue, 22 Apr 2003 16:11:23 GMT
bloritsch    2003/04/22 09:11:23

  Modified:    fortress build.xml default.properties
               fortress/src/java/org/apache/avalon/fortress/impl
                        AbstractContainer.java
               fortress/src/java/org/apache/avalon/fortress/impl/handler
                        AbstractComponentHandler.java
  Added:       fortress/src/java/org/apache/avalon/fortress/impl/factory
                        AbstractObjectFactory.java BCELCodeGenerator.java
                        BCELWrapperGenerator.java
                        PassThroughInvocationHandler.java ProxyManager.java
                        ProxyObjectFactory.java WrapperClass.java
                        WrapperObjectFactory.java
  Removed:     fortress/src/java/org/apache/avalon/fortress/impl/handler
                        PassThroughInvocationHandler.java ProxyHelper.java
                        ProxyObjectFactory.java
  Log:
  Restructure the proxying code, and add the implementation for BCEL enabled proxies--BTW, BCEL is NOT required.
  
  Revision  Changes    Path
  1.87      +10 -1     avalon-excalibur/fortress/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/fortress/build.xml,v
  retrieving revision 1.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- build.xml	22 Apr 2003 00:07:56 -0000	1.86
  +++ build.xml	22 Apr 2003 16:11:22 -0000	1.87
  @@ -22,6 +22,7 @@
           <pathelement location="${excalibur-instrument-manager.jar}"/>
           <pathelement location="${excalibur-instrument-manager-interfaces.jar}"/>
           <pathelement location="${excalibur-event.jar}"/>
  +        <pathelement location="${bcel.jar}"/>
           <pathelement location="${excalibur-logger.jar}"/>
           <pathelement location="${excalibur-sourceresolve.jar}"/>
           <pathelement location="${excalibur-lifecycle.jar}"/>
  @@ -94,7 +95,13 @@
         </jar>
       </target>
   
  -    <target name="dependencies" description="Check dependencies" unless="skip.dependencies">
  +    <target name="checkBCEL">
  +      <available classname="org.apache.bcel.classfile.JavaClass" property="bcel.present">
  +        <classpath refid="project.class.path"/>
  +      </available>
  +    </target>
  +
  +    <target name="dependencies" depends="checkBCEL" description="Check dependencies" unless="skip.dependencies">
           <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkCommon"/>
           <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkCommonsCollections"/>
           <ant antfile="${depchecker.prefix}/depchecker.xml" target="checkFramework"/>
  @@ -150,6 +157,8 @@
               target="1.2">
               <classpath refid="build.path"/>
               <include name="**/*.java"/>
  +            <exclude name="**/BCEL*.java" unless="bcel.present"/>
  +            <exclude name="**/factory/Wrapper*.java" unless="bcel.present"/>
           </javac>
   
           <!-- copy resources to same location as .class files -->
  
  
  
  1.75      +3 -0      avalon-excalibur/fortress/default.properties
  
  Index: default.properties
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/fortress/default.properties,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -r1.74 -r1.75
  --- default.properties	22 Apr 2003 12:37:06 -0000	1.74
  +++ default.properties	22 Apr 2003 16:11:22 -0000	1.75
  @@ -22,6 +22,9 @@
   # ----- QDox Jar ----
   qdox.jar=${basedir}/../lib/qdox-1.1.jar
   
  +# ----- BCEL Jar ----
  +bcel.jar=${basedir}/../lib/bcel.jar
  +
   # ----- Excalibur Lifecycle -----
   excalibur-lifecycle.home=${basedir}/../lifecycle
   excalibur-lifecycle.lib=${excalibur-lifecycle.home}/build/lib
  
  
  
  1.23      +8 -3      avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/AbstractContainer.java
  
  Index: AbstractContainer.java
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/AbstractContainer.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- AbstractContainer.java	18 Apr 2003 20:02:29 -0000	1.22
  +++ AbstractContainer.java	22 Apr 2003 16:11:22 -0000	1.23
  @@ -61,6 +61,9 @@
   import org.apache.avalon.fortress.impl.role.FortressRoleManager;
   import org.apache.avalon.fortress.impl.role.Role2MetaInfoManager;
   import org.apache.avalon.fortress.impl.role.ServiceMetaManager;
  +import org.apache.avalon.fortress.impl.factory.ProxyObjectFactory;
  +import org.apache.avalon.fortress.impl.factory.ProxyManager;
  +import org.apache.avalon.fortress.impl.handler.ComponentFactory;
   import org.apache.avalon.fortress.util.CompositeException;
   import org.apache.avalon.fortress.util.LifecycleExtensionManager;
   import org.apache.avalon.framework.activity.Disposable;
  @@ -132,6 +135,8 @@
       /** Contains an entry for each ComponentHandler */
       protected List m_components = new ArrayList( 10 );
   
  +    private ProxyManager m_proxyManager = new ProxyManager(true);
  +
       /**
        * Pull the manager items from the context so we can use them to set up
        * the system.
  @@ -454,14 +459,14 @@
        */
       protected ObjectFactory createObjectFactory( final String classname,
                                                    final Configuration configuration )
  -        throws ClassNotFoundException
  +        throws Exception
       {
           final Class clazz = m_classLoader.loadClass( classname );
           final ComponentFactory componentFactory =
               new ComponentFactory( clazz, configuration,
                   m_serviceManager, m_context,
                   m_loggerManager, m_extManager );
  -        return new ProxyObjectFactory( componentFactory );
  +        return m_proxyManager.getWrappedObjectFactory( componentFactory );
       }
   
       /**
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/AbstractObjectFactory.java
  
  Index: AbstractObjectFactory.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.excalibur.mpool.ObjectFactory;
  import org.apache.excalibur.instrument.Instrumentable;
  import org.apache.excalibur.instrument.Instrument;
  import org.apache.avalon.framework.logger.Loggable;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.Recontextualizable;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.component.Recomposable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Reconfigurable;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Reparameterizable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Suspendable;
  import org.apache.avalon.framework.activity.Disposable;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  
  /**
   * AbstractObjectFactory does XYZ
   *
   * @author <a href="bloritsch.at.apache.org">Berin Loritsch</a>
   * @version CVS $ Revision: 1.1 $
   */
  public abstract class AbstractObjectFactory implements ObjectFactory, Instrumentable
  {
      /**
       * The list interfaces that will not be proxied.
       */
      private static final Class[] INVALID_INTERFACES = new Class[]
      {
          Loggable.class,
          LogEnabled.class,
          Contextualizable.class,
          Recontextualizable.class,
          Composable.class,
          Recomposable.class,
          Serviceable.class,
          Configurable.class,
          Reconfigurable.class,
          Parameterizable.class,
          Reparameterizable.class,
          Initializable.class,
          Startable.class,
          Suspendable.class,
          Disposable.class,
          Serializable.class
      };
  
      /**
       * The {@link ObjectFactory ObjectFactory} proper
       * we delegate all calls to.
       */
      protected final ObjectFactory m_delegateFactory;
  
      public AbstractObjectFactory(final ObjectFactory objectFactory )
      {
          if ( null == objectFactory )
          {
              throw new NullPointerException( "objectFactory" );
          }
  
          m_delegateFactory = objectFactory;
      }
  
      /**
       * @see ObjectFactory#newInstance()
       */
      public abstract Object newInstance() throws Exception;
  
      /**
       * @see ObjectFactory#getCreatedClass()
       */
      public final Class getCreatedClass()
      {
          return m_delegateFactory.getCreatedClass();
      }
  
      /**
       * @see ObjectFactory#dispose(Object)
       */
      public abstract void dispose( Object object ) throws Exception;
  
      /* (non-Javadoc)
      * @see org.apache.excalibur.instrument.Instrumentable#setInstrumentableName(java.lang.String)
      */
      public final void setInstrumentableName( final String name )
      {
          if ( m_delegateFactory instanceof Instrumentable )
          {
              ( (Instrumentable) m_delegateFactory ).setInstrumentableName( name );
          }
      }
  
      /* (non-Javadoc)
      * @see org.apache.excalibur.instrument.Instrumentable#getInstrumentableName()
      */
      public final String getInstrumentableName()
      {
          if ( m_delegateFactory instanceof Instrumentable )
          {
              return ( (Instrumentable) m_delegateFactory ).getInstrumentableName();
          }
  
          return "";
      }
  
      /* (non-Javadoc)
      * @see org.apache.excalibur.instrument.Instrumentable#getInstruments()
      */
      public final Instrument[] getInstruments()
      {
          if ( m_delegateFactory instanceof Instrumentable )
          {
              return ( (Instrumentable) m_delegateFactory ).getInstruments();
          }
  
          return new Instrument[]{};
      }
  
      /* (non-Javadoc)
      * @see org.apache.excalibur.instrument.Instrumentable#getChildInstrumentables()
      */
      public final Instrumentable[] getChildInstrumentables()
      {
          if ( m_delegateFactory instanceof Instrumentable )
          {
              return ( (Instrumentable) m_delegateFactory ).getChildInstrumentables();
          }
  
          return new Instrumentable[]{};
      }
  
      /**
       * Get a list of interfaces to proxy by scanning through
       * all interfaces a class implements and skipping invalid interfaces
       * (as defined in {@link #INVALID_INTERFACES}).
       *
       * @param clazz the class
       * @return the list of interfaces to proxy
       */
      protected static Class[] guessWorkInterfaces( final Class clazz )
      {
          final ArrayList list = new ArrayList();
          guessWorkInterfaces( clazz, list );
  
          list.add( Component.class );
          return (Class[]) list.toArray( new Class[list.size()] );
      }
  
      /**
       * Get a list of interfaces to proxy by scanning through
       * all interfaces a class implements and skipping invalid interfaces
       * (as defined in {@link #INVALID_INTERFACES}).
       *
       * @param clazz the class
       * @param list the list of current work interfaces
       */
      private static void guessWorkInterfaces( final Class clazz,
                                               final ArrayList list )
      {
          if ( null != clazz )
          {
              final Class[] interfaces = clazz.getInterfaces();
  
              boolean skip;
              for ( int i = 0; i < interfaces.length; i++ )
              {
                  skip = false;
                  for ( int j = 0; j < INVALID_INTERFACES.length; j++ )
                  {
                      if ( interfaces[i] == INVALID_INTERFACES[j] )
                      {
                          skip = true;
                          continue;
                      }
                  }
  
                  if ( !skip )
                  {
                      list.add( interfaces[i] );
                  }
              }
  
              guessWorkInterfaces( clazz.getSuperclass(), list );
          }
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/BCELCodeGenerator.java
  
  Index: BCELCodeGenerator.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.bcel.classfile.JavaClass;
  import org.apache.bcel.classfile.Field;
  import org.apache.bcel.classfile.Method;
  import org.apache.bcel.classfile.ExceptionTable;
  import org.apache.bcel.generic.*;
  import org.apache.bcel.Constants;
  
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Set;
  import java.util.HashSet;
  
  /**
   * <p>
   * 	<code>BCELCodeGenerator</code> creates implementations for the
   * 	{@link org.apache.bcel.classfile.Method Method}s and
   *  {@link org.apache.bcel.classfile.Field Field}s needed in creating a
   * 	<code>WrapperClass</code>.
   * </p>
   *
   * @author <a href="mailto:olaf.bergner@gmx.de>Olaf Bergner</a>
   */
  
  public final class BCELCodeGenerator
  {
      //***************************************************************************
      // Fields
      //***************************************************************************
  
      /**
       * The name of the field holding the wrapped class in the generated
       * wrapper, e.g.
       * <pre>
       * 	<code>
       * 		private final <ClassToWrap> WRAPPED_CLASS_FN;
       * 	</code>
       * </pre>
       */
      private static final String WRAPPED_CLASS_FN = "m_wrappedClass";
  
      /**
       * The name of the field accessor used to ask the generated wrapper for
       * the wrapped class instance.
       */
      private static final String ACCESSOR_METHOD_NAME = "getWrappedObject";
  
      /**
       * The name of the wrapper class to be created.
       */
      private String m_wrapperClassName;
  
      /**
       * The name of the superclass of the wrapper class to be generated.
       */
      private String m_wrapperSuperclassName;
  
      /**
       * Class object holding the type of the object we want to create a
       * wrapper for.
       */
      private JavaClass m_classToWrap;
  
      /**
       * The {@link org.apache.bcel.generic.Type Type} of the class we want to
       * create a wrapper for.
       */
      private Type m_classToWrapType;
  
      /**
       * The {@link org.apache.bcel.generic.ClassGen ClassGen} instance to use for
       * code generation.
       */
      private ClassGen m_classGenerator;
  
      /**
       * The {@link org.apache.bcel.generic.ConstantPoolGen ConstantPoolGen}
       * instance to use for code generation.
       */
      private ConstantPoolGen m_constPoolGenerator;
  
      /**
       * The {@link org.apache.bcel.generic.InstructionList InstructionList} instance
       * to use during code generation.
       */
      private final InstructionList m_instructionList = new InstructionList();
  
      /**
       * The {@link org.apache.bcel.generic.InstructionFactory InstructionFactory} to
       * use during code gereration.
       */
      private InstructionFactory m_instructionFactory;
  
      /**
       * Flag indicating whether this instance is already initialized or not.
       */
      private boolean m_isInitialized = false;
  
      /**
       * Default constructor.
       */
      public BCELCodeGenerator()
      {
          // Left blank
      }
  
      public void init(
          final String wrapperClassName,
          final String wrapperSuperclassName,
          final JavaClass classToWrap,
          final ClassGen classGenerator )
          throws IllegalArgumentException
      {
          if ( classToWrap == null )
          {
              final String message = "Target class must not be <null>.";
              throw new IllegalArgumentException( message );
          }
          if ( classToWrap.isAbstract() || !classToWrap.isClass() )
          {
              final String message =
                  "Target class must neither be abstract nor an interface.";
              throw new IllegalArgumentException( message );
          }
          if ( classGenerator == null )
          {
              final String message = "ClassGenerator must not be <null>.";
              throw new IllegalArgumentException( message );
          }
  
          m_wrapperClassName = wrapperClassName;
          m_wrapperSuperclassName = wrapperSuperclassName;
          m_classToWrap = classToWrap;
          m_classToWrapType = new ObjectType( m_classToWrap.getClassName() );
          m_classGenerator = classGenerator;
          m_constPoolGenerator = m_classGenerator.getConstantPool();
          m_instructionFactory =
              new InstructionFactory( m_classGenerator, m_constPoolGenerator );
  
          m_isInitialized = true;
      }
  
      /**
       * Create a field declaration of the form
       * <pre>
       * 	<code>
       * 		private <ClassToWrap> WRAPPED_CLASS_FN;
       * 	</code>
       * </pre>
       *
       * @return Field
       *
       * @throws IllegalStateException If this instance is not initialized.
       */
      public Field createWrappedClassField() throws IllegalStateException
      {
          if ( !isInitialized() )
          {
              final String message =
                  "BCELMethodFieldImplementationGenerator is not initialized.";
              throw new IllegalStateException( message );
          }
  
          final FieldGen fg =
              new FieldGen(
                  Constants.ACC_PRIVATE,
                  m_classToWrapType,
                  WRAPPED_CLASS_FN,
                  m_constPoolGenerator );
  
          return fg.getField();
      }
  
      /**
       * Create the wrapper class' default constructor:
       * <pre>
       * 	<code>
       * 		public <wrapperClass>(<classToWrap> classToWrap)
       * 		{
       * 			this.<WRAPPED_CLASS_FN> = classToWrap;
       * 		}
       * 	</code>
       * </pre>
       *
       * @return The created default constructor
       *
       * @throws IllegalStateException If this instance is not initialized.
       */
      public Method createDefaultConstructor() throws IllegalStateException
      {
          if ( !isInitialized() )
          {
              final String message =
                  "BCELMethodFieldImplementationGenerator is not initialized.";
              throw new IllegalStateException( message );
          }
          final MethodGen mg =
              new MethodGen(
                  Constants.ACC_PUBLIC,
                  Type.VOID,
                  new Type[]{m_classToWrapType},
                  new String[]{"classToWrap"},
                  "<init>",
                  m_wrapperClassName,
                  m_instructionList,
                  m_constPoolGenerator );
  
          m_instructionList.append(
              m_instructionFactory.createLoad( Type.OBJECT, 0 ) );
          m_instructionList.append(
              m_instructionFactory.createInvoke(
                  m_wrapperSuperclassName,
                  "<init>",
                  Type.VOID,
                  Type.NO_ARGS,
                  Constants.INVOKESPECIAL ) );
          m_instructionList.append(
              m_instructionFactory.createLoad( Type.OBJECT, 0 ) );
          m_instructionList.append(
              m_instructionFactory.createLoad( Type.OBJECT, 1 ) );
          m_instructionList.append(
              m_instructionFactory.createFieldAccess(
                  m_wrapperClassName,
                  WRAPPED_CLASS_FN,
                  m_classToWrapType,
                  Constants.PUTFIELD ) );
          m_instructionList.append( m_instructionFactory.createReturn( Type.VOID ) );
          mg.setMaxStack();
          mg.setMaxLocals();
  
          return extractMethod( mg );
      }
  
      /**
       * Create a field accessor for the wrapped class instance of the form
       * <pre>
       * 	<code>
       * 		public Object <ACCESSOR_METHOD_NAME>()
       * 		{
       * 			return this.<WRAPPED_CLASS_FN>;
       * 		}
       * 	</code>
       * </pre>
       * @return Method
       * @throws IllegalStateException
       */
      public Method createWrappedClassAccessor() throws IllegalStateException
      {
          if ( !isInitialized() )
          {
              final String message =
                  "BCELMethodFieldImplementationGenerator is not initialized.";
              throw new IllegalStateException( message );
          }
  
          final MethodGen mg =
              new MethodGen(
                  Constants.ACC_PUBLIC,
                  Type.OBJECT,
                  Type.NO_ARGS,
                  new String[]{
                  },
                  ACCESSOR_METHOD_NAME,
                  m_classToWrap.getClassName(),
                  m_instructionList,
                  m_constPoolGenerator );
  
          m_instructionList.append(
              m_instructionFactory.createLoad( Type.OBJECT, 0 ) );
          m_instructionList.append(
              m_instructionFactory.createFieldAccess(
                  m_wrapperClassName,
                  WRAPPED_CLASS_FN,
                  m_classToWrapType,
                  Constants.GETFIELD ) );
          m_instructionList.append(
              m_instructionFactory.createReturn( Type.OBJECT ) );
  
          mg.setMaxStack();
          mg.setMaxLocals();
  
          return extractMethod( mg );
      }
  
      /**
       * Create a method declaration/definition of the form
       * <pre>
       * 	<code>
       * 		public <returnType> <methodName>(<parameterTypes>)
       * 			throws <exceptionNames>
       * 		{
       * 			return this.<WRAPPED_CLASS_FN>.<methodName>(<parameterTypes>);
       * 		}
       * 	</code>
       * </pre>
       *
       * @param methodName     The name of the method to create
       * @param returnType     The return type of the method to create
       * @param parameterTypes The array of parameter types of the method to create
       * @param exceptionNames The array of the names of the exceptions the method
       * 						  to create might throw
       *
       * @return Method		  The {@link org.apache.bcel.classfile.Method Method}
       * 						  object representing the created method
       *
       * @throws IllegalArgumentException If any of the parameters passed in is null.
       * @throws IllegalStateException If this instance is not initialized.
       */
      public Method createMethodWrapper(
          final String methodName,
          final Type returnType,
          final Type[] parameterTypes,
          final String[] exceptionNames )
          throws IllegalArgumentException, IllegalStateException
      {
          if ( !isInitialized() )
          {
              final String message =
                  "BCELMethodFieldImplementationGenerator is not initialized.";
              throw new IllegalStateException( message );
          }
          if ( methodName == null
              || returnType == null
              || parameterTypes == null
              || exceptionNames == null )
          {
              final String message = "None of the parameters may be <null>.";
              throw new IllegalArgumentException( message );
          }
  
          final MethodGen mg =
              new MethodGen(
                  Constants.ACC_PUBLIC,
                  returnType,
                  parameterTypes,
                  null,
                  methodName,
                  m_wrapperClassName,
                  m_instructionList,
                  m_constPoolGenerator );
  
          // Create throws clause
          for ( int i = 0; i < exceptionNames.length; i++ )
          {
              mg.addException( exceptionNames[i] );
          }
  
          // Loading the wrapped class instance onto the stack ...
          m_instructionList.append(
              m_instructionFactory.createLoad( Type.OBJECT, 0 ) );
          m_instructionList.append(
              m_instructionFactory.createFieldAccess(
                  m_wrapperClassName,
                  WRAPPED_CLASS_FN,
                  m_classToWrapType,
                  Constants.GETFIELD ) );
  
          // Loading all parameters onto the stack ...
          short stackIndex = 1;
          // Stack index 0 is occupied by the wrapped class instance.
          for ( int i = 0; i < parameterTypes.length; ++i )
          {
              m_instructionList.append(
                  m_instructionFactory.createLoad( parameterTypes[i], stackIndex ) );
              stackIndex += parameterTypes[i].getSize();
          }
  
          // Invoking the specified method with the loaded parameters on
          // the wrapped class instance ...
          m_instructionList.append(
              m_instructionFactory.createInvoke(
                  m_classToWrap.getClassName(),
                  methodName,
                  returnType,
                  parameterTypes,
                  Constants.INVOKEVIRTUAL ) );
  
          // Creating return statement ...
          m_instructionList.append( m_instructionFactory.createReturn( returnType ) );
  
          mg.setMaxStack();
          mg.setMaxLocals();
  
          return extractMethod( mg );
      }
  
      /**
       * Create a method declaration/definition of the form
       * <pre>
       * 	<code>
       * 		public <returnType> <methodName>(<parameterTypes>)
       * 			throws <exceptionNames>
       * 		{
       * 			return this.<WRAPPED_CLASS_FN>.<methodName>(<parameterTypes>);
       * 		}
       * 	</code>
       * </pre>
       *
       * @param methodToWrap The <code>Method</code> to create a wrapper for.
       *
       * @return Method		The wrapper method.
       *
       * @throws IllegalArgumentException If <code>methodToWrao</code> is null.
       * @throws IllegalStateException If this instance is not initialized.
       */
      public Method createMethodWrapper( final Method methodToWrap )
          throws IllegalArgumentException, IllegalStateException
      {
          if ( methodToWrap == null )
          {
              final String message = "Method parameter must not be <null>.";
              throw new IllegalArgumentException( message );
          }
  
          return createMethodWrapper(
              methodToWrap.getName(),
              methodToWrap.getReturnType(),
              methodToWrap.getArgumentTypes(),
              methodToWrap.getExceptionTable().getExceptionNames() );
      }
  
      /**
       * Creates an implementation for the supplied {@link org.apache.bcel.classfile.JavaClass JavaClass}
       * instance representing an interface.
       *
       * @param interfaceToImplement The interface we want to create an implementation for
       * @return Method[]            An array of {@link org.apache.bcel.classfile.Method Method}
       * 								instances representing the interface implementation.
       * @throws IllegalArgumentException If <code>interfaceToImplement</code> is <code>null</code>
       * 									 or does not represent an interface
       * @throws IllegalStateException    If this instance has not been initialized
       */
      public Method[] createImplementation( final JavaClass interfaceToImplement )
          throws IllegalArgumentException, IllegalStateException
      {
          if ( interfaceToImplement == null )
          {
              final String message = "Interface to implement must not be <null>.";
              throw new IllegalArgumentException( message );
          }
          if ( !interfaceToImplement.isInterface() )
          {
              final String message =
                  "Supplied JavaClass parameter is not an interface.";
              throw new IllegalArgumentException( message );
          }
          if ( !isInitialized() )
          {
              final String message =
                  "BCELInterfaceImplementationGenerator is not initialized.";
              throw new IllegalStateException( message );
          }
  
          final Method[] interfaceMethods = extractMethods( interfaceToImplement );
          final List gmList = new ArrayList();
          for ( int i = 0; i < interfaceMethods.length; ++i )
          {
              final Method im = interfaceMethods[i];
  
              // Skip <clinit> method ...
              if ( im.getName().equals( "<clinit>" ) )
              {
                  continue;
              }
  
              // Extract exception names ...
              final ExceptionTable exTable = im.getExceptionTable();
              final String[] exceptionNames = ( exTable == null ? new String[]{
              }
                  : exTable.getExceptionNames() );
              final Method generatedMethod =
                  createMethodWrapper(
                      im.getName(),
                      im.getReturnType(),
                      im.getArgumentTypes(),
                      exceptionNames );
  
              gmList.add( generatedMethod );
          }
  
          return (Method[]) gmList.toArray( new Method[gmList.size()] );
      }
  
      /**
       * Extracts the {@link org.apache.bcel.classfile.Method Method} out of
       * the supplied {@link org.apache.bcel.generic.MethodGen MethodGen} instance,
       * clears the {@link org.apache.bcel.generic.InstructionList InstructionList}
       * and returns the extracted <code>Method</code>.
       *
       * @param mg The {@link org.apache.bcel.generic.MethodGen MethodGen} instance
       * 			  holding the {@link org.apache.bcel.classfile.Method Method} to
       * 			  extract
       * @return   The extracted {@link org.apache.bcel.classfile.Method Method}
       */
      private Method extractMethod( final MethodGen mg )
      {
          final Method m = mg.getMethod();
          m_instructionList.dispose();
          return m;
      }
  
      /**
       * Has this instance already been initialized?
       *
       * @return TRUE, if this instance has already been initialized, FALSE otherwise
       */
      private boolean isInitialized()
      {
          return m_isInitialized;
      }
  
      /**
       * Extracts the collection of {@link org.apache.bcel.classfile.Method Method}s
       * declared in the supplied {@link org.apache.bcel.classfile.JavaClass JavaClass}
       * instance. This instance is supposed to represent an interface.
       *
       * @param interfaceToImplement The {@link org.apache.bcel.classfile.JavaClass JavaClass}
       * 								instance representing the interface we are asking for
       * 								its methods.
       * @return Method[]			The array of {@link org.apache.bcel.classfile.Method Method}s
       * 								declared by the interface
       * @throws IllegalArgumentException If <code>interfaceToImplement</code> does not represent an interface
       * @throws NullPointerException if the <code>interfaceToImplement</code> is <code>null</code>
       */
      static Method[] extractMethods( final JavaClass interfaceToImplement )
          throws IllegalArgumentException, NullPointerException
      {
          if ( interfaceToImplement == null )
          {
              final String message = "JavaClass parameter must not be <null>.";
              throw new NullPointerException( message );
          }
          if ( !interfaceToImplement.isInterface() )
          {
              final String message = "JavaClass parameter must be an interface";
              throw new IllegalArgumentException( message );
          }
  
          Set methods = new HashSet();
          extractMethods(interfaceToImplement, methods);
          JavaClass[] interfaces  = interfaceToImplement.getInterfaces();
          for (int i = 0; i < interfaces.length; i++)
          {
              extractMethods(interfaces[i], methods);
          }
  
          return (Method[])methods.toArray(new Method[] {});
      }
  
      private static final void extractMethods( final JavaClass interfaceToImplement, final Set methods )
      {
          Method[] meth = interfaceToImplement.getMethods();
          for ( int m = 0; m < meth.length; m++ )
          {
              methods.add( meth[m] );
          }
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/BCELWrapperGenerator.java
  
  Index: BCELWrapperGenerator.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.bcel.classfile.JavaClass;
  import org.apache.bcel.classfile.Method;
  import org.apache.bcel.generic.ClassGen;
  import org.apache.bcel.Constants;
  import org.apache.bcel.Repository;
  import org.apache.avalon.fortress.impl.factory.BCELCodeGenerator;
  
  /**
   * Create the BCELWrapper for the component
   *
   * @author <a href="mailto:olaf.bergner@gmx.de>Olaf Bergner</a>
   */
  
  
  final class BCELWrapperGenerator
  
  {
      /**
       * The suffix to be appended to the name of the wrapped class when creating
       * the name of the wrapper class.
       */
      private static final String WRAPPER_CLASS_SUFFIX = "$BCELWrapper";
  
      /**
       * The name of the superclass of the wrapper class to be generated.
       */
      private static final String WRAPPER_SUPERCLASS_NAME = "java.lang.Object";
  
      /**
       * The name of the interface each generated wrapper class has to implement.
       */
      private static final String WRAPPER_CLASS_INTERFACE_NAME =
          WrapperClass.class.getName();
  
      /**
       * The <code>BCELCodeGenerator</code> to use for
       * byte code generation.
       */
      private final BCELCodeGenerator m_codeGenerator;
  
      /**
       * The <code>ClassGen</code> instance to use for byte code generation.
       */
      private ClassGen m_classGenerator = null;
  
      /**
       * The <code>ClassLoader</code> to use when loading a class generated by this
       * <code>BCELWrapperGenerator</code>.
       */
      private final BCELClassLoader m_bcelClassLoader;
  
      /**
       * @author <a href="mailto:olaf.bergner@gmx.de>Olaf Bergner</a>
       */
  
  
      private final class BCELClassLoader extends ClassLoader
  
      {
          /**
           * The <i>byte code</i> representing the wrapper class created by the
           * enclosing <code>BCELWrapperGenerated</code>. This field will be
           * managed by the <code>BCELWrapperGenerator</code>.
           */
          private byte[] m_byteCode = null;
  
          /**
           * Constructs a <code>BCELClassLoader</code> with the specified class
           * loader as its parent.
           *
           * @param parent The parent <code>ClassLoader</code>
           */
          public BCELClassLoader( final ClassLoader parent )
          {
              super( parent );
          }
  
          /**
           * Constructs a <code>BCELClassLoader</code> with no parent.
           *
           */
          public BCELClassLoader()
          {
              super();
          }
  
          /**
           *
           * @see java.lang.ClassLoader#findClass(String)
           */
          protected Class findClass( final String name ) throws ClassNotFoundException
          {
              // Check if the requested class falls within the domain of
              // the BCELWrapperGenerator
              if ( name.endsWith( WRAPPER_CLASS_SUFFIX ) )
              {
                  return super.defineClass(
                      name,
                      getByteCode(),
                      0,
                      getByteCode().length );
              }
  
              return super.findClass( name );
          }
  
          /**
           * Passes in the <code>byte code</code> to use when loading a class
           * created by the <code>BCELWrapperGenerator</code>.
           * This method will be called by the <code>BCELWrapperGenerator</code>
           * prior to asking this class loader for the generated wrapper class.
           *
           * @param byteCode The <code>byte code</code> to use when loading
           * 					a generated class
           *
           * @throws IllegalArgumentException If <code>byteCode</code> is null or
           * 			empty
           */
          private void setByteCode( final byte[] byteCode )
              throws IllegalArgumentException
          {
              if ( byteCode == null || byteCode.length == 0 )
              {
                  final String message =
                      "Parameter byteCode must neither be <null> nor empty.";
                  throw new IllegalArgumentException( message );
              }
  
              m_byteCode = byteCode;
          }
  
          /**
           * Clears the <code>byte code</code>, setting it to <code>null</code>.
           * This method will be called by the <code>BCELWrapperGenerator</code>
           * immediately after this class loader has returned the generated wrapper
           * class.
           */
          private void clearByteCode()
          {
              m_byteCode = null;
          }
  
          /**
           * Returns the <code>byte code</code> to use when loading a generated
           * class.
           *
           * @return The <code>byte code</code> for defining the generated class
           */
          private byte[] getByteCode()
          {
              return m_byteCode;
          }
      } // End BCELClassLoader
  
      /**
       * No-args default constructor.
       */
      public BCELWrapperGenerator()
      {
          m_codeGenerator = new BCELCodeGenerator();
          m_bcelClassLoader =
              new BCELClassLoader( Thread.currentThread().getContextClassLoader() );
      }
  
      /**
       */
      public Class createWrapper( final Class classToWrap ) throws Exception
      {
          if ( classToWrap == null )
          {
              final String message = "Class to wrap must not be <null>.";
              throw new IllegalArgumentException( message );
          }
  
          // Guess work interfaces ...
          final Class[] interfacesToImplement =
              AbstractObjectFactory.guessWorkInterfaces( classToWrap );
  
          // Get JavaClasses as required by BCEL for the wrapped class and its interfaces
          final JavaClass javaClassToWrap = lookupClass( classToWrap );
          final JavaClass[] javaInterfacesToImplement =
              lookupClasses( interfacesToImplement );
  
          // The name of the wrapper class to be generated
          final String wrapperClassName =
              classToWrap.getName() + WRAPPER_CLASS_SUFFIX;
  
          // Create BCEL class generator
          m_classGenerator =
              new ClassGen(
                  wrapperClassName,
                  WRAPPER_SUPERCLASS_NAME,
                  null,
                  Constants.ACC_FINAL
              |Constants.ACC_PUBLIC
              |Constants.ACC_SUPER,
                  extractInterfaceNames( interfacesToImplement ) );
  
          // Initialize method-field generator
          m_codeGenerator.init(
              wrapperClassName,
              WRAPPER_SUPERCLASS_NAME,
              javaClassToWrap,
              m_classGenerator );
  
          final byte[] byteCode = buildWrapper( javaInterfacesToImplement );
          // TODO: Check synchronization
          Class generatedClass;
          synchronized ( m_bcelClassLoader )
          {
              m_bcelClassLoader.setByteCode( byteCode );
              generatedClass = m_bcelClassLoader.loadClass( wrapperClassName );
              m_bcelClassLoader.clearByteCode();
          }
  
          return generatedClass;
      }
  
      /**
       * Takes a <code>Class</code> instance as a its parameter and returns corresponding
       * the <code>JavaClass</code> instance as used by <b>BCEL</b>.
       *
       * @param clazz The <code>Class</code> instance we want to turn into a
       * 				 <code>JavaClass</code>
       * @return The <code>JavaClass</code> representing the given <code>Class</code>
       * 			instance
       */
      private JavaClass lookupClass( final Class clazz )
      {
          return Repository.lookupClass( clazz );
      }
  
      /**
       * Takes an array of <code>Class</code> instances and returns an array holding
       * the corresponding <code>JavaClass</code> instances as used by <b>BCEL</b>.
       *
       * @param classes      An array holding <code>Class</code> instances we
       * 						want to turn into <code>JavaClass</code> instances
       * @return JavaClass[] An array of <code>JavaClass</code> instances representing
       * 						the given <code>Class</code> instances
       */
      private JavaClass[] lookupClasses( final Class[] classes )
      {
          final JavaClass[] javaClasses = new JavaClass[classes.length];
          for ( int i = 0; i < classes.length; ++i )
          {
              javaClasses[i] = lookupClass( classes[i] );
          }
  
          return javaClasses;
      }
  
      /**
       * Takes an array of <code>Class</code> instances supposed to represent
       * interfaces and returns a list of the names of those interfaces.
       *
       * @param interfaces An array of <code>Class</code> instances
       * @return String[]  An array of the names of those <code>Class</code> instances
       */
      private String[] extractInterfaceNames( final Class[] interfaces )
      {
          final String[] ifaceNames = new String[interfaces.length + 1];
          for ( int i = 0; i < interfaces.length; ++i )
          {
              ifaceNames[i] = interfaces[i].getName();
          }
          // Add interface WrapperClass to the list of interfaces to be implemented
          ifaceNames[ifaceNames.length - 1] = WRAPPER_CLASS_INTERFACE_NAME;
  
          return ifaceNames;
      }
  
      /**
       * Generates the wrapper byte code for a given interface.
       *
       * @param interfacesToImplement The interfaces we want to generate wrapper
       * 								 byte code for
       * @return byte[] The generated byte code
       */
      private byte[] buildWrapper( final JavaClass[] interfacesToImplement )
      {
          // Create field for the wrapped class
          m_classGenerator.addField( m_codeGenerator.createWrappedClassField() );
  
          // Create default constructor
          m_classGenerator.addMethod( m_codeGenerator.createDefaultConstructor() );
  
          //Create field accessor for wrapped class instance
          m_classGenerator.addMethod(
              m_codeGenerator.createWrappedClassAccessor() );
  
          // Implement interfaces
          Method[] interfaceMethods;
          for ( int i = 0; i < interfacesToImplement.length; ++i )
          {
              interfaceMethods =
                  m_codeGenerator.createImplementation( interfacesToImplement[i] );
              for ( int j = 0; j < interfaceMethods.length; ++j )
              {
                  m_classGenerator.addMethod( interfaceMethods[j] );
              }
          }
  
          return m_classGenerator.getJavaClass().getBytes();
      }
  }
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/PassThroughInvocationHandler.java
  
  Index: PassThroughInvocationHandler.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  
  /**
   * InvocationHandler that just passes on all methods to target object.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   */
  final class PassThroughInvocationHandler
      implements InvocationHandler
  {
      /**
       * The target object delegated to.
       */
      private final Object m_object;
  
      /**
       * Create an Invocation handler for specified object.
       *
       * @param object the object to delegate to
       */
      public PassThroughInvocationHandler( final Object object )
      {
          if ( null == object )
          {
              throw new NullPointerException( "object" );
          }
  
          m_object = object;
      }
  
      /**
       * Invoke the appropriate method on underlying object.
       *
       * @param proxy the proxy object
       * @param meth the method
       * @param args the arguments
       * @return the return value of object
       * @exception Throwable method throws an exception
       */
      public Object invoke( final Object proxy,
                            final Method meth,
                            final Object[] args )
          throws Throwable
      {
          try
          {
              return meth.invoke( m_object, args );
          }
          catch ( final InvocationTargetException ite )
          {
              throw ite.getTargetException();
          }
      }
  
      /**
       * Retrieve the underlying object delegated to.
       *
       * @return the object delegated to
       */
      Object getObject()
      {
          return m_object;
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/ProxyManager.java
  
  Index: ProxyManager.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.excalibur.mpool.ObjectFactory;
  
  import java.lang.reflect.Constructor;
  
  /**
   * ProxyManager is used to abstract away the plumbing for the underlying
   * proxy generator.  Each proxy solution has to implement the ObjectFactory interface,
   * that way we can keep a soft dependency on things like BCEL.
   *
   * @author <a href="bloritsch.at.apache.org">Berin Loritsch</a>
   * @version CVS $ Revision: 1.1 $
   */
  public final class ProxyManager
  {
      private static final String BCEL_CLASS = "org.apache.bcel.classfile.JavaClass";
      private static final String BCEL_WRAPPER = "org.apache.avalon.fortress.impl.factory.WrapperObjectFactory";
      private static final String PROXY_WRAPPER = "org.apache.avalon.fortress.impl.factory.ProxyObjectFactory";
      private static final boolean m_isBCELPresent;
      private final boolean m_useBCELPreference;
      private Class m_factoryClass;
  
      static
      {
          boolean bcelPresent = false;
          try
          {
              Thread.currentThread().getContextClassLoader().loadClass( BCEL_CLASS );
              bcelPresent = true;
          }
          catch ( ClassNotFoundException cfne )
          {
              //ignore because we already have the proper value
          }
  
          m_isBCELPresent = bcelPresent;
      }
  
      public ProxyManager()
      {
          this(false);
      }
  
      public ProxyManager(final boolean useBCEL)
      {
          m_useBCELPreference = useBCEL;
      }
  
      public ObjectFactory getWrappedObjectFactory(final ObjectFactory source) throws Exception
      {
          if ( null == m_factoryClass )
          {
              final ClassLoader loader = source.getClass().getClassLoader();
  
              if (m_useBCELPreference && m_isBCELPresent)
              {
                  m_factoryClass = loader.loadClass(BCEL_WRAPPER);
              }
              else
              {
                  m_factoryClass = loader.loadClass(PROXY_WRAPPER);
              }
          }
  
          final Constructor constr = m_factoryClass.getConstructor(new Class[] {ObjectFactory.class});
          return (ObjectFactory) constr.newInstance(new Object[] {source});
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/ProxyObjectFactory.java
  
  Index: ProxyObjectFactory.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.excalibur.mpool.ObjectFactory;
  import org.apache.avalon.framework.component.Component;
  
  import java.lang.reflect.Proxy;
  
  /**
   * An ObjectFactory that delegates to another ObjectFactory
   * and proxies results of that factory.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/04/22 16:11:23 $
   */
  public final class ProxyObjectFactory extends AbstractObjectFactory
  {
      /**
       * Create factory that delegates to specified factory.
       *
       * @param objectFactory the factory to delegate to
       * @exception NullPointerException if the supplied object factory is null
       */
      public ProxyObjectFactory( final ObjectFactory objectFactory ) throws NullPointerException
      {
          super(objectFactory);
      }
  
      /**
       * Create a new instance from delegated factory and proxy it.
       *
       * @return the proxied object
       * @throws Exception if unable to create new instance
       */
      public Object newInstance()
          throws Exception
      {
          final Object object = m_delegateFactory.newInstance();
          return createProxy( object );
      }
  
      /**
       * Dispose of objects created by this factory.
       * Involves deproxying object and delegating to real ObjectFactory.
       *
       * @param object the proxied object
       * @throws Exception if unable to dispose of object
       */
      public void dispose( final Object object )
          throws Exception
      {
          final Object target = getObject( object );
          m_delegateFactory.dispose( target );
      }
  
      /**
       * Get the Component wrapped in the proxy.
       *
       * @param service the service object to proxy
       */
      public static Component createProxy( final Object service )
      {
          final Class clazz = service.getClass();
          final Class[] workInterfaces = guessWorkInterfaces( clazz );
  
          return (Component) Proxy.newProxyInstance( clazz.getClassLoader(),
              workInterfaces,
              new PassThroughInvocationHandler( service ) );
      }
  
      /**
       * Get the target object from specified proxy.
       *
       * @param proxy the proxy object
       * @return the target object
       * @throws NullPointerException if unable to aquire target object,
       *                   or specified object is not a proxy
       */
      public static Object getObject( final Object proxy )
  
      {
          if ( null == proxy )
          {
              throw new NullPointerException( "proxy" );
          }
  
          if ( !Proxy.isProxyClass( proxy.getClass() ) )
          {
              final String message = "object is not a proxy";
              throw new IllegalArgumentException( message );
          }
  
          final PassThroughInvocationHandler handler =
              (PassThroughInvocationHandler) Proxy.getInvocationHandler( proxy );
          return handler.getObject();
      }
  }
  
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/WrapperClass.java
  
  Index: WrapperClass.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  /**
   * <p>
   * 	The interface <code>WrapperClass</code> provides a means of asking a dynamically
   *  created wrapper for a given object for said wrapped object.
   * </p>
   *
   * @author <a href="mailto:olaf.bergner@gmx.de">Olaf Bergner</a>
   */
  
  public interface WrapperClass
  {
      /**
       * Return the object that is being wrapped by this wrapper class instance.
       *
       * @return Object                The wrapped object
       * @throws IllegalStateException
       */
      public Object getWrappedObject()
          throws IllegalStateException;
  }
  
  
  1.1                  avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/factory/WrapperObjectFactory.java
  
  Index: WrapperObjectFactory.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 modifica-
   tion, 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  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Avalon", "Excalibur" 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
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   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 (INCLU-
   DING, 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.avalon.fortress.impl.factory;
  
  import org.apache.excalibur.mpool.ObjectFactory;
  import org.apache.avalon.fortress.impl.factory.BCELWrapperGenerator;
  import org.apache.avalon.fortress.impl.factory.WrapperClass;
  
  /**
   * An object factory that delegates all calls to another object factory and
   * wraps the returned object into another object that exposes only the wrapped
   * object's work interface(s).
   *
   * @author <a href="mailto:olaf.bergner@gmx.de">Olaf Bergner</a>
   * @version CVS $ Revision: 1.1 $
   */
  public final class WrapperObjectFactory extends AbstractObjectFactory
  {
  
      /**
       * The {@link BCELWrapperGenerator} to use for creating the wrapper.
       */
      private final BCELWrapperGenerator m_wrapperGenerator;
  
      /**
       * Creates a {@link WrapperObjectFactory} with the specified
       * {@link org.apache.excalibur.mpool.ObjectFactory ObjectFactory} as the
       * object factory to delegate all calls for new instances to.
       *
       * @param  objectFactory The {@link org.apache.excalibur.mpool.ObjectFactory
       *                     ObjectFactory} to sue when creating new instances
       * @throws IllegalArgumentException If <code>objFactory</code> is
       * 									 <code>null</code>
       */
      public WrapperObjectFactory( final ObjectFactory objectFactory )
          throws IllegalArgumentException
      {
          super( objectFactory );
          m_wrapperGenerator = new BCELWrapperGenerator();
      }
  
      /**
       * @see org.apache.excalibur.mpool.ObjectFactory#newInstance()
       */
      public Object newInstance() throws Exception
      {
          final Object obj = m_delegateFactory.newInstance();
  
          final Class wrappedClass =
              m_wrapperGenerator.createWrapper( obj.getClass() );
  
          return wrappedClass.getConstructor(
              new Class[]{obj.getClass()} ).newInstance(
                  new Object[]{obj} );
      }
  
      /**
       * @see org.apache.excalibur.mpool.ObjectFactory#dispose(java.lang.Object)
       */
      public void dispose( final Object object ) throws Exception
      {
          if ( object == null )
          {
              final String error = "Supplied argument is <null>";
              throw new IllegalArgumentException( error );
          }
          if ( !( object instanceof WrapperClass ) )
          {
              final String error =
                  "Supplied argument is no instance of \""
                  + WrapperClass.class.getName()
                  + "\"";
              throw new IllegalArgumentException( error );
          }
  
          final Object target = ( (WrapperClass) object ).getWrappedObject();
  
          m_delegateFactory.dispose( target );
      }
  }
  
  
  1.14      +5 -5      avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/handler/AbstractComponentHandler.java
  
  Index: AbstractComponentHandler.java
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/fortress/src/java/org/apache/avalon/fortress/impl/handler/AbstractComponentHandler.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- AbstractComponentHandler.java	18 Apr 2003 20:02:29 -0000	1.13
  +++ AbstractComponentHandler.java	22 Apr 2003 16:11:23 -0000	1.14
  @@ -191,11 +191,11 @@
       /**
        * Initialize the ComponentHandler.
        * Subclasses should overide this to do their own initialization.
  +     *
  +     * @throws Exception if there is a problem
        */
  -    protected void doPrepare()
  -        throws Exception
  -    {
  -    }
  +    protected void doPrepare() throws Exception
  +    {}
   
       /**
        * Get a reference of the desired Component
  
  
  

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


Mime
View raw message