You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@excalibur.apache.org by ha...@apache.org on 2004/07/10 06:02:57 UTC

svn commit: rev 22783 - in excalibur/branches/fortress-experiments: bean container-api container-api/src/java/org/apache/avalon/fortress container-api/src/java/org/apache/avalon/fortress/attributes container-api/src/java/org/apache/avalon/fortress/attributes/qdox container-api/src/java/org/apache/avalon/fortress/interceptor container-api/src/test/org/apache/avalon/fortress/attributes/qdox/test container-impl container-impl/src/java/org/apache/avalon/fortress/impl container-impl/src/java/org/apache/avalon/fortress/impl/factory container-impl/src/java/org/apache/avalon/fortress/impl/interceptor container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/cglib container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/simple container-impl/src/java/org/apache/avalon/fortress/impl/role container-test container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples container-test/src/test/org/apache/avalon/fortress/test/data examples examples/src/java/org/apache/avalon/fortress/examples/interceptors examples/src/java/org/apache/avalon/fortress/examples/interceptors/business examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors meta meta/src/java/org/apache/avalon/fortress/tools meta/src/test/org/apache/avalon/fortress/tools/test

Author: hammett
Date: Fri Jul  9 21:02:55 2004
New Revision: 22783

Added:
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/cglib/CGLibInterceptableFactory.java   (contents, props changed)
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/AbstractInterceptorManagerTest.java   (contents, props changed)
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/PerformanceTestCase.java   (contents, props changed)
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObject.java   (contents, props changed)
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObjectImpl.java   (contents, props changed)
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/FakeTransactionManager.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xconf
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xlog
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Main.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/WhoAmI.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/DefaultPersistenceManager.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/PersistenceManager.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/SecurityInterceptor.java   (contents, props changed)
   excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/TransactionalInterceptor.java   (contents, props changed)
Modified:
   excalibur/branches/fortress-experiments/bean/project.xml
   excalibur/branches/fortress-experiments/container-api/project.xml
   excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/ExtendedMetaInfo.java
   excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/AttributeInfo.java
   excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/qdox/QDoxSerializer.java
   excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/interceptor/Interceptor.java
   excalibur/branches/fortress-experiments/container-api/src/test/org/apache/avalon/fortress/attributes/qdox/test/QDoxSerializerTestCase.java
   excalibur/branches/fortress-experiments/container-impl/project.xml
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/InterceptorEnabledContainer.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/factory/BCELCodeGenerator.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/AbstractInterceptor.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/DefaultInterceptorManager.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/InterceptableFactory.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/TailInterceptor.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/simple/SimpleInterceptableFactory.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/AbstractMetaInfoManager.java
   excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/ServiceMetaManager.java
   excalibur/branches/fortress-experiments/container-test/project.xml
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/DefaultInterceptorManagerTestCase.java
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/CustomerDAOImpl.java
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/ValidInterceptor.java
   excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/test/data/test1.xconf
   excalibur/branches/fortress-experiments/examples/project.xml
   excalibur/branches/fortress-experiments/meta/project.xml
   excalibur/branches/fortress-experiments/meta/src/java/org/apache/avalon/fortress/tools/Component.java
   excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ComponentTestCase.java
   excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ServiceTestCase.java
Log:
- Interceptions work now using Reflection or CGLib.Enhancer. 
- QDoxSerializer uses MetaClass project, but there seems to be a problem with attributes parameters.

Modified: excalibur/branches/fortress-experiments/bean/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/bean/project.xml	(original)
+++ excalibur/branches/fortress-experiments/bean/project.xml	Fri Jul  9 21:02:55 2004
@@ -104,7 +104,17 @@
         </dependency>
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
         </dependency>
         <dependency>
             <id>ant</id>
@@ -130,6 +140,10 @@
         <dependency>
             <id>commons-beanutils</id>
             <version>1.6.1</version>
+        </dependency>
+        <dependency>
+            <id>excalibur-i18n</id>
+            <version>1.2</version>
         </dependency>
         
     </dependencies>

Modified: excalibur/branches/fortress-experiments/container-api/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/project.xml	(original)
+++ excalibur/branches/fortress-experiments/container-api/project.xml	Fri Jul  9 21:02:55 2004
@@ -46,7 +46,17 @@
         </dependency>
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
         </dependency>
     </dependencies>
 

Modified: excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/ExtendedMetaInfo.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/ExtendedMetaInfo.java	(original)
+++ excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/ExtendedMetaInfo.java	Fri Jul  9 21:02:55 2004
@@ -18,83 +18,19 @@
 package org.apache.avalon.fortress;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import org.apache.avalon.fortress.attributes.AttributeInfo;
-import org.apache.avalon.fortress.attributes.AttributeLevel;
 
 /**
  * Pending
  * 
  * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
  */
-public class ExtendedMetaInfo
+public interface ExtendedMetaInfo
 {
-    private static final AttributeInfo[] EMPTY = new AttributeInfo[0]; 
+    AttributeInfo[] getClassAttributes();
     
-    private final AttributeInfo[] m_classAttributes;
-    private final Map m_method2Attributes;
-    
-    public ExtendedMetaInfo( AttributeInfo[] attributes )
-    {
-        final List classLevel = new ArrayList();
-        m_method2Attributes = new HashMap(); 
-        
-        for (int i = 0; i < attributes.length; i++)
-        {
-            final AttributeInfo attribute = attributes[i];
-            
-            if (attribute.getAttributeLevel() == AttributeLevel.ClassLevel)
-            {
-                classLevel.add( attribute );
-            }
-            else if (attribute.getAttributeLevel() == AttributeLevel.MethodLevel)
-            {
-                if (attribute.getMethod() != null)
-                {
-                    associateMethodAttribute( attribute );
-                }
-            }
-        }
-        
-        m_classAttributes = (AttributeInfo[]) classLevel.toArray( new AttributeInfo[0] );
-    }
-    
-    public AttributeInfo[] getClassAttributes()
-    {
-        return m_classAttributes;
-    }
-    
-    public AttributeInfo[] getAttributesForMethod( final Method method )
-    {
-        List attributes = obtainAttributeList( method );
-        
-        if (attributes == null)
-        {
-            return EMPTY;
-        }
-        
-        return (AttributeInfo[]) attributes.toArray( new AttributeInfo[0] );
-    }
-    
-    private void associateMethodAttribute( AttributeInfo attribute )
-    {
-        List attrs = obtainAttributeList( attribute.getMethod() );
-        
-        if (attrs == null)
-        {
-            attrs = new ArrayList();
-            m_method2Attributes.put( attribute.getMethod(), attrs );
-        }
-        
-        attrs.add( attribute );
-    }
+    AttributeInfo[] getAttributesForMethod( final Method method );
 
-    private List obtainAttributeList( final Method method )
-    {
-        return (List) m_method2Attributes.get( method );
-    }
+    AttributeInfo getAttributeForMethod( final String name, final Method method );
 }

Modified: excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/AttributeInfo.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/AttributeInfo.java	(original)
+++ excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/AttributeInfo.java	Fri Jul  9 21:02:55 2004
@@ -17,7 +17,7 @@
 
 package org.apache.avalon.fortress.attributes;
 
-import java.lang.reflect.Method;
+import java.util.Collections;
 import java.util.Map;
 
 /**
@@ -27,24 +27,26 @@
  */
 public class AttributeInfo
 {
+    public static final AttributeInfo EMPTY = new AttributeInfo();
+    
     private final String m_name;
     private final Map m_properties;
     private final AttributeLevel m_level;
-    private final Method m_method;
 
-    public AttributeInfo( final String name, final Map properties, 
-                          final AttributeLevel level, final Method method )
+    private AttributeInfo()
     {
-        m_name = name;
-        m_properties = properties;
-        m_level = level;
-        m_method = method;
+        m_name = "";
+        m_properties = Collections.EMPTY_MAP;
+        m_level = AttributeLevel.Undefined;
     }
-    
-    public AttributeInfo( final String name, final Map properties, 
+
+    public AttributeInfo( final String name, 
+                          final Map properties, 
                           final AttributeLevel level )
     {
-        this( name, properties, level, null );
+        m_name = name;
+        m_properties = properties;
+        m_level = level;
     }
     
     public String getName()
@@ -65,15 +67,5 @@
     public AttributeLevel getAttributeLevel()
     {
         return m_level;
-    }
-
-    /**
-     * Pending
-     * 
-     * @return
-     */
-    public Method getMethod()
-    {
-        return m_method;
     }
 }

Modified: excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/qdox/QDoxSerializer.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/qdox/QDoxSerializer.java	(original)
+++ excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/attributes/qdox/QDoxSerializer.java	Fri Jul  9 21:02:55 2004
@@ -19,25 +19,24 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
+import java.io.OutputStream;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.attributes.AttributeInfo;
 import org.apache.avalon.fortress.attributes.AttributeLevel;
+import org.codehaus.metaclass.io.MetaClassIOBinary;
+import org.codehaus.metaclass.model.Attribute;
+import org.codehaus.metaclass.model.ClassDescriptor;
+import org.codehaus.metaclass.model.MethodDescriptor;
+import org.codehaus.metaclass.model.ParameterDescriptor;
+import org.codehaus.metaclass.tools.qdox.QDoxDescriptorParser;
 
-import com.thoughtworks.qdox.model.DocletTag;
 import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaMethod;
-import com.thoughtworks.qdox.model.JavaParameter;
 
 /**
  * Implements a serialization and deserialization 
@@ -48,6 +47,9 @@
 public class QDoxSerializer
 {
     private static final QDoxSerializer m_instance = new QDoxSerializer();
+
+    private MetaClassIOBinary binary = new MetaClassIOBinary();
+    private QDoxDescriptorParser parser = new QDoxDescriptorParser();
     
     private QDoxSerializer()
     {
@@ -58,271 +60,169 @@
         return m_instance;
     }
 
-    public void serialize( final ObjectOutputStream stream, final JavaClass clazz )
+    public void serialize( final OutputStream stream, final JavaClass clazz )
         throws IOException
     {
-        DocletTag[] tags = clazz.getTags();
+        binary.serializeClass( stream, parser.buildClassDescriptor( clazz ) );
+    }
 
-        for (int i = 0; i < tags.length; i++)
+    public ExtendedMetaInfo deserialize( final InputStream stream, final Class target )
+        throws IOException
+    {
+        ClassDescriptor descriptor = binary.deserializeClass( stream );
+        return new ExtendedMetaInfoAdapter( descriptor );
+    }
+    
+    public static class ExtendedMetaInfoAdapter implements ExtendedMetaInfo
+    {
+        private static final AttributeInfo[] EMPTY = new AttributeInfo[0];
+        private final ClassDescriptor m_descriptor;
+        private final AttributeInfo[] m_classAttributes;
+        private final Map m_method2Attributes = new HashMap(); 
+        
+        /**
+         * @param descriptor
+         */
+        public ExtendedMetaInfoAdapter( final ClassDescriptor descriptor )
         {
-            DocletTag tag = tags[i];
-            
-            if (tag.getName().equalsIgnoreCase("author"))
-            {
-                continue;
-            }
-            
-            stream.writeInt( 1 );
-            QDoxSerializer.instance().serialize( stream, tag );
+            m_descriptor = descriptor;
+            m_classAttributes = buildAttributeInfoArray( descriptor.getAttributes() );
         }
 
-        // TODO: Do we need to inspect super classes?
-        final JavaMethod[] methods = clazz.getMethods();
-        
-        for ( int i = 0; i < methods.length; i++ )
+        /**
+         * Document me!
+         *  
+         * @see org.apache.avalon.fortress.ExtendedMetaInfo#getClassAttributes()
+         */
+        public AttributeInfo[] getClassAttributes()
         {
-            JavaMethod method = methods[i];
-            tags = method.getTags();
-                
-            if (tags.length == 0)
-            {
-                continue;
-            }
-                
-            for (int j = 0; j < tags.length; j++)
-            {
-                DocletTag tag = tags[j];
-                stream.writeInt( 1 );
-                QDoxSerializer.instance().serialize( stream, method, tag );
-            }
+            return m_classAttributes;
         }
 
-        stream.writeInt( 0 );
-    }
-
-    public ExtendedMetaInfo deserialize( final InputStream stream, final Class target )
-        throws IOException
-    {
-        final MethodInfoHelper methodHelper = new MethodInfoHelper( target );
-         
-        final ObjectInputStream inStream = new ObjectInputStream( stream );
-        
-        final List attributes = new ArrayList();
-        
-        try
+        /**
+         * Document me!
+         *  
+         * @see org.apache.avalon.fortress.ExtendedMetaInfo#getAttributesForMethod(java.lang.reflect.Method)
+         */
+        public AttributeInfo[] getAttributesForMethod( final Method method )
         {
-            while ( inStream.readInt() == 1 )
+            AttributeInfo[] attributes = (AttributeInfo[]) m_method2Attributes.get( method );
+            
+            if (attributes != null)
             {
-                QDoxSerializer.TagInfo info = QDoxSerializer.instance().deserialize( inStream );
-                    
-                if (info == null)
+                return attributes;
+            }
+            
+            attributes = EMPTY;
+            
+            final MethodDescriptor[] descriptors = m_descriptor.getMethods();
+            
+            for (int i = 0; i < descriptors.length; i++)
+            {
+                MethodDescriptor descriptor = descriptors[i];
+                if (!(method.getName().equals(descriptor.getName())))
+                {
+                    continue;
+                }
+                if (!(method.getReturnType().getName().equals(descriptor.getReturnType())))
                 {
                     continue;
                 }
                 
-                AttributeInfo attribute = null;
-                 
-                if (info.getMethod() != null)
+                Class[] parameters = method.getParameterTypes();
+                ParameterDescriptor[] paramsDesc = descriptor.getParameters();
+                
+                if ( parameters.length != paramsDesc.length )
                 {
-                    attribute = buildAttributeInfoForMethod( info, methodHelper );
+                    continue;
                 }
-                else
+                
+                for (int j = 0; j < parameters.length; j++)
                 {
-                    attribute = buildAttributeInfoForClass( info );
+                    Class paramClass = parameters[j];
+                    if (!(paramsDesc[j].getName().equals( paramClass.getName() )))
+                    {
+                        break;
+                    }
                 }
                 
-                attributes.add( attribute );
+                attributes = buildAttributeInfoArray( descriptor.getAttributes() );
+                break;
             }
-        }
-        catch(ClassNotFoundException ex)
-        {
-            // is ignoring a good strategy? Don't think so
-            // but let's sticky with it at the moment.
-        }
-        finally
-        {
-            inStream.close();
-        }
             
-        AttributeInfo[] attrs = (AttributeInfo[]) attributes.toArray( new AttributeInfo[0] ); 
-        
-        return new ExtendedMetaInfo( attrs );
-    }
-    
-    public void serialize( final ObjectOutputStream stream, final DocletTag tag )
-        throws IOException
-    {
-        serialize( stream, null, tag );
-    }
-
-    public void serialize( final ObjectOutputStream stream, final JavaMethod method, final DocletTag tag )
-        throws IOException
-    {
-        stream.writeObject( new TagInfo( tag, method ) );
-    }
-    
-    private TagInfo deserialize( final ObjectInputStream stream )
-        throws IOException, ClassNotFoundException
-    {
-        return (TagInfo) stream.readObject();
-    }
-
-    private static AttributeInfo buildAttributeInfoForMethod( final QDoxSerializer.TagInfo info, 
-        final MethodInfoHelper methodHelper )
-    {
-        Method classMethod = methodHelper.obtainRealMethod( info.getMethod() );
-
-        return new AttributeInfo( info.getTag().getName(), buildAttributes( info ), 
-            AttributeLevel.MethodLevel, classMethod );
-    }
-
-    private static AttributeInfo buildAttributeInfoForClass( final QDoxSerializer.TagInfo info )
-    {
-        return new AttributeInfo( info.getTag().getName(), buildAttributes( info ), 
-            AttributeLevel.ClassLevel );
-    }
-        
-    private static Map buildAttributes( final QDoxSerializer.TagInfo info )
-    {
-        Map parameters = Collections.EMPTY_MAP;
-            
-        String[] params = info.getTag().getParameters();
+            m_method2Attributes.put( method, attributes );
             
-        if (params.length != 0)
+            return attributes;
+        }
+
+        /**
+         * Document me!
+         *  
+         * @see org.apache.avalon.fortress.ExtendedMetaInfo#getAttributeForMethod(java.lang.String, java.lang.reflect.Method)
+         */
+        public AttributeInfo getAttributeForMethod( final String name, final Method method )
         {
-            parameters = new TreeMap( String.CASE_INSENSITIVE_ORDER );
-                
-            for (int i = 0; i < params.length; i++)
+            final AttributeInfo[] attributes = getAttributesForMethod( method );
+            AttributeInfo attribute = null;
+            
+            if (attributes != EMPTY)
             {
-                final String property = params[i];
-                final int equalIndex = property.indexOf( '=' );
-                    
-                String key = property;
-                String value = "";
-                    
-                if ( equalIndex != -1 )
+                for (int i = 0; i < attributes.length; i++)
                 {
-                    key = property.substring( 0, equalIndex );
-                    value = property.substring( equalIndex + 1 );
-                }
+                    final AttributeInfo info = attributes[i];
                     
-                parameters.put( key, value );
+                    if (name.equalsIgnoreCase( name ))
+                    {
+                        attribute = info;
+                        break;
+                    }
+                }
             }
-        }
             
-        return parameters;
-    }
-    
-    public static class TagInfo implements Serializable
-    {
-        private final DocletTag m_tag;
-        private final JavaMethod m_method;
-        
-        public TagInfo( final DocletTag tag, final JavaMethod method )
-        {
-            m_tag = tag;
-            m_method = method;
-        }
-        
-        public DocletTag getTag()
-        {
-            return m_tag;
+            return attribute;
         }
         
-        public JavaMethod getMethod()
+        private AttributeInfo[] buildAttributeInfoArray( final Attribute[] attributes )
         {
-            return m_method;
-        }
-    }
-
-    /**
-     * Pending
-     * 
-     * @author hammett
-     */
-    public static class MethodInfoHelper
-    {
-        private final Map m_key2Method = new HashMap();
-        
-        /**
-         * Pending
-         * 
-         * @param class1
-         */
-        public MethodInfoHelper(Class targetClass)
-        {
-            final Method[] methods = targetClass.getMethods();
+            final AttributeInfo[] newArray = new AttributeInfo[ attributes.length ];
             
-            for (int i = 0; i < methods.length; i++)
+            for (int i = 0; i < attributes.length; i++)
             {
-                Method method = methods[i];
-                m_key2Method.put( buildKey( method ), method );
+                Attribute attribute = attributes[i];
+                newArray[i] = buildAttributeInfo( attribute );
             }
+            
+            return newArray;
         }
         
-        /**
-         * Pending
-         * 
-         * @param javaMethod
-         * @return
-         */
-        public Method obtainRealMethod( JavaMethod javaMethod )
+        private AttributeInfo buildAttributeInfo( final Attribute attribute )
         {
-            return (Method) m_key2Method.get( buildKey( javaMethod ) );
+            return new AttributeInfo( 
+                attribute.getName(), 
+                buildAttributes( attribute ), 
+                AttributeLevel.ClassLevel );
         }
 
-        /**
-         * Pending
-         * 
-         * @param method
-         * @return
-         */
-        private String buildKey(final Method method)
+        private Map buildAttributes( final Attribute attribute )
         {
-            StringBuffer sb = new StringBuffer();
-            sb.append( method.getReturnType().getName() );
-            sb.append( ' ' );
-            sb.append( method.getDeclaringClass().getName() );
-            sb.append( ' ' );
-            sb.append( method.getName() );
-
-            Class[] parameters = method.getParameterTypes();
-
-            for (int i = 0; i < parameters.length; i++)
-            {
-                Class parameter = parameters[i];
-                sb.append( ' ' );
-                sb.append( parameter.getName() );
-            }
+            Map parameters = Collections.EMPTY_MAP;
             
-            return sb.toString();
-        }
-
-        /**
-         * Pending
-         * 
-         * @param method
-         * @return
-         */
-        private String buildKey(final JavaMethod method)
-        {
-            StringBuffer sb = new StringBuffer();
-            sb.append( method.getReturns().getValue() );
-            sb.append( ' ' );
-            sb.append( method.getParentClass().getFullyQualifiedName() );
-            sb.append( ' ' );
-            sb.append( method.getName() );
-
-            JavaParameter[] parameters = method.getParameters();
-
-            for (int i = 0; i < parameters.length; i++)
+            final String[] paramNames = attribute.getParameterNames();
+            
+            if (paramNames.length != 0)
             {
-                JavaParameter parameter = parameters[i];
-                sb.append( ' ' );
-                sb.append( parameter.getType().getValue() );
+                parameters = new TreeMap( String.CASE_INSENSITIVE_ORDER );
+                
+                for (int i = 0; i < paramNames.length; i++)
+                {
+                    final String key = paramNames[i];
+                    final String value = attribute.getParameter( key );
+                    
+                    parameters.put( key, value );
+                }
             }
             
-            return sb.toString();
-        }
+            return parameters;
+        }    
     }
 }

Modified: excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/interceptor/Interceptor.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/interceptor/Interceptor.java	(original)
+++ excalibur/branches/fortress-experiments/container-api/src/java/org/apache/avalon/fortress/interceptor/Interceptor.java	Fri Jul  9 21:02:55 2004
@@ -20,6 +20,8 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import org.apache.avalon.fortress.ExtendedMetaInfo;
+
 /**
  * Pending
  * 
@@ -31,6 +33,6 @@
     
     Interceptor getNext();
     
-    Object intercept( Object instance, Method method, Object[] args ) 
+    Object intercept( Object instance, ExtendedMetaInfo meta, Method method, Object[] args ) 
         throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; 
 }

Modified: excalibur/branches/fortress-experiments/container-api/src/test/org/apache/avalon/fortress/attributes/qdox/test/QDoxSerializerTestCase.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-api/src/test/org/apache/avalon/fortress/attributes/qdox/test/QDoxSerializerTestCase.java	(original)
+++ excalibur/branches/fortress-experiments/container-api/src/test/org/apache/avalon/fortress/attributes/qdox/test/QDoxSerializerTestCase.java	Fri Jul  9 21:02:55 2004
@@ -21,9 +21,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.ObjectOutputStream;
 import java.lang.reflect.Method;
 
 import org.apache.avalon.fortress.ExtendedMetaInfo;
@@ -84,10 +82,8 @@
         
         /// Serialization
         ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
-        ObjectOutputStream outStream = new ObjectOutputStream( byteOutStream );   
         
-        QDoxSerializer.instance().serialize( outStream, clazz );
-        outStream.close();
+        QDoxSerializer.instance().serialize( byteOutStream, clazz );
         byteOutStream.close();
         
         assertTrue( byteOutStream.size() != 0 );
@@ -113,10 +109,8 @@
         targetFile.deleteOnExit();
         
         FileOutputStream fsOutStream = new FileOutputStream( targetFile ); 
-        ObjectOutputStream outStream = new ObjectOutputStream( fsOutStream );   
         
-        QDoxSerializer.instance().serialize( outStream, clazz );
-        outStream.close();
+        QDoxSerializer.instance().serialize( fsOutStream, clazz );
         fsOutStream.close();
         
         /// Deserialization
@@ -135,6 +129,15 @@
         assertNotNull( classAttrs );
         assertEquals( 3, classAttrs.length );
         
+        assertEquals( "attribute1", classAttrs[0].getName() );
+        assertEquals( 0, classAttrs[0].getProperties().size() );
+        
+        assertEquals( "attribute2", classAttrs[1].getName() );
+        assertEquals( 1, classAttrs[1].getProperties().size() );
+
+        assertEquals( "attribute3", classAttrs[2].getName() );
+        assertEquals( 2, classAttrs[2].getProperties().size() );
+        
         Method[] methods = Component.class.getDeclaredMethods();
         
         for (int i = 0; i < methods.length; i++)
@@ -146,7 +149,7 @@
         }
     }
 
-    private JavaClass createJavaClass() throws FileNotFoundException
+    private JavaClass createJavaClass() throws Exception
     {
         JavaDocBuilder builder = new JavaDocBuilder();
         builder.addSource(new File("src/test/org/apache/avalon/fortress/attributes/qdox/test/data/Component.java"));

Modified: excalibur/branches/fortress-experiments/container-impl/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/project.xml	(original)
+++ excalibur/branches/fortress-experiments/container-impl/project.xml	Fri Jul  9 21:02:55 2004
@@ -100,7 +100,22 @@
         </dependency>
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>cglib</id>
+            <artifactId>cglib-full</artifactId>
+            <version>2.0</version>
         </dependency>
         
         <dependency>

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/InterceptorEnabledContainer.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/InterceptorEnabledContainer.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/InterceptorEnabledContainer.java	Fri Jul  9 21:02:55 2004
@@ -17,6 +17,7 @@
 
 package org.apache.avalon.fortress.impl;
 
+import org.apache.avalon.fortress.impl.factory.ProxyManager;
 import org.apache.avalon.fortress.impl.interceptor.DefaultInterceptorManager;
 import org.apache.avalon.fortress.interceptor.InterceptorManager;
 import org.apache.avalon.fortress.util.CompositeException;
@@ -69,6 +70,24 @@
     /// 
 
     /**
+     * Turn off proxy (interceptable components already has proxy)
+     *
+     * @param proxyType
+     * @throws ConfigurationException
+     */
+    protected void interpretProxy( final String proxyType ) throws ConfigurationException
+    {
+        try
+        {
+            setProxyManager( new ProxyManager( ProxyManager.NONE ) );
+        }
+        catch (Exception e)
+        {
+            throw new ConfigurationException("Could not create ProxyManager", e);
+        }
+    }
+    
+    /**
      * Pending
      * 
      * @see org.apache.avalon.fortress.impl.AbstractContainer#provideComponentContext(org.apache.avalon.framework.context.Context)
@@ -77,6 +96,7 @@
     {
         DefaultContext context = new DefaultContext( parent );
         context.put( "container", this );
+        context.put( "metamanager", m_metaManager );
         context.makeReadOnly();
         return context;
     }

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/factory/BCELCodeGenerator.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/factory/BCELCodeGenerator.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/factory/BCELCodeGenerator.java	Fri Jul  9 21:02:55 2004
@@ -36,7 +36,6 @@
  *
  * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
  */
-
 public final class BCELCodeGenerator
 {
     //***************************************************************************

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/AbstractInterceptor.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/AbstractInterceptor.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/AbstractInterceptor.java	Fri Jul  9 21:02:55 2004
@@ -20,6 +20,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.interceptor.Interceptor;
 
 /**
@@ -56,9 +57,9 @@
      * 
      * @see org.apache.avalon.fortress.interceptor.Interceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
      */
-    public Object intercept(Object instance, Method method, Object[] args)
+    public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
         throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
     {
-        return getNext().intercept( instance, method, args );
+        return getNext().intercept( instance, meta, method, args );
     }
 }

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/DefaultInterceptorManager.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/DefaultInterceptorManager.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/DefaultInterceptorManager.java	Fri Jul  9 21:02:55 2004
@@ -22,8 +22,11 @@
 
 import org.apache.avalon.fortress.Container;
 import org.apache.avalon.fortress.ContainerListener;
+import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.MetaInfoEntry;
 import org.apache.avalon.fortress.MetaInfoManager;
+import org.apache.avalon.fortress.attributes.AttributeInfo;
+import org.apache.avalon.fortress.impl.interceptor.strategies.simple.SimpleInterceptableFactory;
 import org.apache.avalon.fortress.interceptor.Interceptor;
 import org.apache.avalon.fortress.interceptor.InterceptorManager;
 import org.apache.avalon.fortress.interceptor.InterceptorManagerException;
@@ -43,15 +46,20 @@
 public class DefaultInterceptorManager
     implements InterceptorManager, Configurable, Contextualizable, Initializable, ContainerListener
 {
+    protected static final String INTERCEPTABLE_TAGNAME = "excalibur.interceptable";
+    protected static final String FAMILY_ATT_NAME = "family";
+    
     ///
     /// Instance fields
     ///
 
-    private Container m_container;
-    
-    private final Map m_families;
+    protected final Map m_families;
+
+    protected Container m_container;
+
+    protected MetaInfoManager m_metaManager;
     
-    private MetaInfoManager m_metaManager;
+    protected InterceptableFactory m_interFactory = new SimpleInterceptableFactory();
 
     ///
     /// Constructors
@@ -82,6 +90,7 @@
     public void contextualize(Context context) throws ContextException
     {
         m_container = (Container) context.get("container");
+        m_metaManager = (MetaInfoManager) context.get("metamanager");
     }
 
     /**
@@ -91,43 +100,10 @@
      */
     public void configure(final Configuration config) throws ConfigurationException
     {
-        final Configuration[] sets = config.getChildren("set");
-        
-        for (int i = 0; i < sets.length; i++)
-        {
-            final Configuration set = sets[i];
-            final String familyName = set.getAttribute("family", "");
-            
-            if ( "".equals(familyName) )
-            {
-                throw new ConfigurationException("Element 'set' must " +
                    "specify a valid 'family' attribute.");
-            }
-            
-            Configuration[] interceptors = set.getChildren("interceptor");
-            
-            for (int j = 0; j < interceptors.length; j++)
-            {
-                final Configuration interceptor = interceptors[j];
-                final String key = interceptor.getAttribute("name", "");
-                final String clazz = interceptor.getAttribute("class", "");
-                
-                if ( "".equals(key) || "".equals(clazz) )
-                {
-                    throw new ConfigurationException("Element 'interceptor' must " +
                        "specify 'name' and 'class' attributes.");
-                }
-                
-                try
-                {
-                    add( familyName, key, clazz );
-                }
-                catch(InterceptorManagerException ex)
-                {
-                    throw new ConfigurationException("Invalid interceptor entry", ex);
-                }
-            }
-        }
+        configureFactory( config.getAttribute("factory", "") );
+        configureInterceptors(config);
     }
-
+    
     /**
      * Pending
      * 
@@ -149,15 +125,32 @@
      */
     public Object componentCreated( final MetaInfoEntry entry, final Object instance )
     {
-        try
-        {
-            m_metaManager = (MetaInfoManager) m_container.get( MetaInfoManager.ROLE, null );
-        }
-        catch(Exception ex)
+        Object newInstance = instance;
+        
+        final ExtendedMetaInfo metaInfo = 
+            m_metaManager.getExtendedMetaInfo( entry.getComponentClass().getName() );
+        final String family = obtainComponentFamily( metaInfo );
+        
+        if ( family != null )
         {
+            try
+            {
+                Interceptor chain = buildChain( family );
+                
+                Class[] interfaces = entry.getComponentClass().getInterfaces();
+                
+                newInstance = m_interFactory.createInterceptableInstance( 
+                    instance, metaInfo, interfaces, chain );
+            }
+            catch(IllegalAccessException ex)
+            {
+            }
+            catch(InstantiationException ex)
+            {
+            }
         }
 
-        return instance;
+        return newInstance;
     }
 
     /**
@@ -267,6 +260,84 @@
         return new TailInterceptor();
     }
     
+    protected String obtainComponentFamily( final ExtendedMetaInfo metaInfo )
+    {
+        // TODO: There are plenty space here for optimizations.
+        
+        AttributeInfo[] attributes = metaInfo.getClassAttributes();
+        
+        for (int i = 0; i < attributes.length; i++)
+        {
+            AttributeInfo info = attributes[i];
+            if (INTERCEPTABLE_TAGNAME.equalsIgnoreCase( info.getName() ))
+            {
+                return (String) info.getProperties().get( FAMILY_ATT_NAME );
+            }
+        }
+        
+        return null;
+    }
+    
+    protected void configureFactory( final String factoryClass ) throws ConfigurationException
+    {
+        if ( factoryClass.equals("") )
+        {
+            // Use the default factory
+            return;
+        }
+        
+        try
+        {
+            m_interFactory = (InterceptableFactory) 
+                Thread.currentThread().getContextClassLoader().loadClass( factoryClass ).newInstance();
+        }
+        catch(Exception ex)
+        {
+            throw new ConfigurationException("Custom InterceptableFactory specified could not be created.");
+        }
+    }
+
+    protected void configureInterceptors(final Configuration config) throws ConfigurationException
+    {
+        final Configuration[] sets = config.getChildren("set");
+        
+        for (int i = 0; i < sets.length; i++)
+        {
+            final Configuration set = sets[i];
+            final String familyName = set.getAttribute(FAMILY_ATT_NAME, "");
+            
+            if ( "".equals(familyName) )
+            {
+                throw new ConfigurationException("Element 'set' must " +
+                    "specify a valid 'family' attribute.");
+            }
+            
+            Configuration[] interceptors = set.getChildren("interceptor");
+            
+            for (int j = 0; j < interceptors.length; j++)
+            {
+                final Configuration interceptor = interceptors[j];
+                final String key = interceptor.getAttribute("name", "");
+                final String clazz = interceptor.getAttribute("class", "");
+                
+                if ( "".equals(key) || "".equals(clazz) )
+                {
+                    throw new ConfigurationException("Element 'interceptor' must " +
+                        "specify 'name' and 'class' attributes.");
+                }
+                
+                try
+                {
+                    add( familyName, key, clazz );
+                }
+                catch(InterceptorManagerException ex)
+                {
+                    throw new ConfigurationException("Invalid interceptor entry", ex);
+                }
+            }
+        }
+    }
+
     ///
     /// Private implementation
     ///

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/InterceptableFactory.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/InterceptableFactory.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/InterceptableFactory.java	Fri Jul  9 21:02:55 2004
@@ -17,6 +17,7 @@
 
 package org.apache.avalon.fortress.impl.interceptor;
 
+import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.interceptor.Interceptor;
 
 /**
@@ -26,6 +27,6 @@
  */
 public interface InterceptableFactory
 {
-    Object createInterceptableInstance( Object realInstance, /*ClassMetaData meta,*/ 
+    Object createInterceptableInstance( Object realInstance, ExtendedMetaInfo meta, 
         Class[] interfaces, Interceptor chain );
 }

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/TailInterceptor.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/TailInterceptor.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/TailInterceptor.java	Fri Jul  9 21:02:55 2004
@@ -20,6 +20,8 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import org.apache.avalon.fortress.ExtendedMetaInfo;
+
 /**
  * The tail interceptor delegates the call to the object.
  * 
@@ -30,7 +32,7 @@
     /**
      * Simply invokes the method on the instance.
      */
-    public Object intercept(Object instance, Method method, Object[] args)
+    public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
         throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
     {
         return method.invoke( instance, args );

Added: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/cglib/CGLibInterceptableFactory.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/cglib/CGLibInterceptableFactory.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.strategies.cglib;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+import org.apache.avalon.fortress.ExtendedMetaInfo;
+import org.apache.avalon.fortress.impl.interceptor.AbstractInterceptor;
+import org.apache.avalon.fortress.impl.interceptor.InterceptableFactory;
+import org.apache.avalon.fortress.impl.interceptor.TailInterceptor;
+import org.apache.avalon.fortress.interceptor.Interceptor;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class CGLibInterceptableFactory implements InterceptableFactory
+{
+    /**
+     * Document me!
+     *  
+     * @see org.apache.avalon.fortress.impl.interceptor.InterceptableFactory#createInterceptableInstance(java.lang.Object, org.apache.avalon.fortress.ExtendedMetaInfo, java.lang.Class[], org.apache.avalon.fortress.interceptor.Interceptor)
+     */
+    public Object createInterceptableInstance(Object realInstance, ExtendedMetaInfo meta, Class[] interfaces, Interceptor chain)
+    {
+        InternalMethodInterceptor methodInterceptor = new InternalMethodInterceptor( realInstance, meta, chain );
+        
+        return Enhancer.create( realInstance.getClass(), interfaces, methodInterceptor );
+    }
+
+    public static class InternalMethodInterceptor implements MethodInterceptor
+    {
+        private final Object m_instance;
+        private final ExtendedMetaInfo m_meta;
+        private final Interceptor m_chain;
+        private MethodProxy m_proxy;
+        
+        /**
+         * @param instance
+         * @param meta
+         * @param chain
+         */
+        public InternalMethodInterceptor(final Object instance, 
+                                         final ExtendedMetaInfo meta, 
+                                         final Interceptor chain)
+        {
+            m_instance = instance;
+            m_meta = meta;
+            m_chain = chain;
+
+            // Now we need to find the tailInterceptor and replace it
+            Interceptor previous = chain;
+            Interceptor next = chain;
+            
+            while( next != null )
+            {
+                if (next.getClass() == TailInterceptor.class)
+                {
+                    previous.init( new AbstractInterceptor()
+                    {
+                        public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
+                            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
+                        {
+                            try
+                            {
+                                return m_proxy.invoke( instance, args );
+                            }
+                            catch(IllegalAccessException ex)
+                            {
+                                throw ex;
+                            }
+                            catch(IllegalArgumentException ex)
+                            {
+                                throw ex;
+                            }
+                            catch(InvocationTargetException ex)
+                            {
+                                throw ex;
+                            }
+                            catch(Throwable ex)
+                            {
+                                throw new InvocationTargetException(ex);
+                            }
+                        }
+                    } );
+                    
+                    break;
+                }
+                
+                previous = next;
+                next = next.getNext();
+            }
+        }
+
+        public Object intercept(Object instance, Method method, Object[] args, MethodProxy proxy) throws Throwable
+        {
+            m_proxy = proxy;
+            
+            return m_chain.intercept( m_instance, m_meta, method, args );
+        }
+    }
+}

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/simple/SimpleInterceptableFactory.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/simple/SimpleInterceptableFactory.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/interceptor/strategies/simple/SimpleInterceptableFactory.java	Fri Jul  9 21:02:55 2004
@@ -21,6 +21,7 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 
+import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.impl.interceptor.InterceptableFactory;
 import org.apache.avalon.fortress.interceptor.Interceptor;
 
@@ -36,21 +37,25 @@
      * 
      * @see org.apache.avalon.fortress.impl.interceptor.InterceptableFactory#createInterceptableInstance(java.lang.Object, org.apache.avalon.fortress.interceptor.Interceptor)
      */
-    public Object createInterceptableInstance(Object realInstance, Class[] interfaces, Interceptor chain)
+    public Object createInterceptableInstance( Object realInstance, ExtendedMetaInfo meta, Class[] interfaces, Interceptor chain )
     {
         ClassLoader loader = Thread.currentThread().getContextClassLoader();
-        return Proxy.newProxyInstance( loader, interfaces, new InterceptorInvocationHandler( realInstance, chain ) );
+        InterceptorInvocationHandler handler = new InterceptorInvocationHandler( realInstance, chain, meta );
+        
+        return Proxy.newProxyInstance( loader, interfaces, handler );
     }
     
     public static class InterceptorInvocationHandler implements InvocationHandler
     {
         private final Object m_instance;
         private final Interceptor m_chain;
+        private final ExtendedMetaInfo m_meta;
         
-        public InterceptorInvocationHandler( Object instance, Interceptor chain )
+        public InterceptorInvocationHandler( Object instance, Interceptor chain, ExtendedMetaInfo meta )
         {
             m_instance = instance;
             m_chain = chain;
+            m_meta = meta;
         }
         
         /**
@@ -60,7 +65,7 @@
          */
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
         {
-            return m_chain.intercept( m_instance, method, args );
+            return m_chain.intercept( m_instance, m_meta, method, args );
         }
     }
 }

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/AbstractMetaInfoManager.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/AbstractMetaInfoManager.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/AbstractMetaInfoManager.java	Fri Jul  9 21:02:55 2004
@@ -24,6 +24,7 @@
 import org.apache.avalon.fortress.attributes.AttributeInfo;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
 
+import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -61,7 +62,23 @@
 
     static
     {
-        EMPTY_EXTENDED_META_INFO = new ExtendedMetaInfo( new AttributeInfo[0] );
+        EMPTY_EXTENDED_META_INFO = new ExtendedMetaInfo( )
+        {
+            public AttributeInfo[] getClassAttributes()
+            {
+                return new AttributeInfo[0];
+            }
+
+            public AttributeInfo[] getAttributesForMethod(Method method)
+            {
+                return new AttributeInfo[0];
+            }
+
+            public AttributeInfo getAttributeForMethod(String name, Method method)
+            {
+                return AttributeInfo.EMPTY;
+            }
+        };
     }
 
     /**

Modified: excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/ServiceMetaManager.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/ServiceMetaManager.java	(original)
+++ excalibur/branches/fortress-experiments/container-impl/src/java/org/apache/avalon/fortress/impl/role/ServiceMetaManager.java	Fri Jul  9 21:02:55 2004
@@ -128,7 +128,9 @@
 
     public ExtendedMetaInfo getExtendedMetaInfo( final String classname )
     {
-        return EMPTY_EXTENDED_META_INFO;
+        ExtendedMetaInfo info = (ExtendedMetaInfo) m_class2ExtendedInfo.get( classname );
+        
+        return info != null ? info : EMPTY_EXTENDED_META_INFO;
     }
     
     /**

Modified: excalibur/branches/fortress-experiments/container-test/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/container-test/project.xml	(original)
+++ excalibur/branches/fortress-experiments/container-test/project.xml	Fri Jul  9 21:02:55 2004
@@ -122,6 +122,14 @@
             <id>xml-apis</id>
             <version>2.0.2</version>
         </dependency>
+        <dependency>
+            <id>xml-apis</id>
+            <version>2.0.2</version>
+        </dependency>
+        <dependency>
+            <id>cglib</id>
+            <version>full-2.0</version>
+        </dependency>
 
         <!-- test -->
         <dependency>
@@ -138,11 +146,25 @@
             <version>1.2</version>
             <groupId>excalibur-fortress</groupId>
         </dependency>
+        <dependency>
+            <id>excalibur-i18n</id>
+            <version>1.2</version>
+        </dependency>
 
         <!-- dependencies for tools -->
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
         </dependency>
         <dependency>
             <id>ant</id>

Added: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/AbstractInterceptorManagerTest.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/AbstractInterceptorManagerTest.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.test;
+
+import org.apache.avalon.fortress.ContainerManager;
+import org.apache.avalon.fortress.impl.DefaultContainerManager;
+import org.apache.avalon.fortress.impl.InterceptorEnabledContainer;
+import org.apache.avalon.fortress.impl.interceptor.test.examples.ValidInterceptor;
+import org.apache.avalon.fortress.interceptor.InterceptorManager;
+import org.apache.avalon.fortress.util.FortressConfig;
+import org.apache.avalon.framework.container.ContainerUtil;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public abstract class AbstractInterceptorManagerTest extends TestCase
+{
+    protected InterceptorEnabledContainer m_container;
+    protected InterceptorManager m_interManager;
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        
+        m_container = createContainer();
+        m_interManager = m_container.getInterceptorManager();
+    }
+
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        
+        m_container.dispose();
+    }
+
+    protected void addValidInterceptor() throws Exception
+    {
+        m_interManager.add( "dao", "key", ValidInterceptor.class.getName() );
+    }
+
+    protected InterceptorEnabledContainer createContainer() throws Exception
+    {
+        final FortressConfig config = new FortressConfig();
+        config.setContainerClass( InterceptorEnabledContainer.class );
+        config.setContextDirectory( "./" );
+        config.setWorkDirectory( "./" );
+        
+        final String BASE = "resource://org/apache/avalon/fortress/test/data/";
+        config.setContainerConfiguration( BASE + "test1.xconf" );
+        config.setLoggerManagerConfiguration( BASE + "test1.xlog" );
+
+        final ContainerManager cm = new DefaultContainerManager( config.getContext() );
+        ContainerUtil.initialize( cm );
+
+        return (InterceptorEnabledContainer) cm.getContainer();
+    }
+}

Modified: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/DefaultInterceptorManagerTestCase.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/DefaultInterceptorManagerTestCase.java	(original)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/DefaultInterceptorManagerTestCase.java	Fri Jul  9 21:02:55 2004
@@ -17,56 +17,23 @@
 
 package org.apache.avalon.fortress.impl.interceptor.test;
 
-import org.apache.avalon.fortress.ContainerManager;
-import org.apache.avalon.fortress.impl.DefaultContainerManager;
-import org.apache.avalon.fortress.impl.InterceptorEnabledContainer;
+import org.apache.avalon.fortress.impl.handler.ComponentHandler;
 import org.apache.avalon.fortress.impl.interceptor.TailInterceptor;
 import org.apache.avalon.fortress.impl.interceptor.test.components.CustomerDataAccessObject;
+import org.apache.avalon.fortress.impl.interceptor.test.examples.FakeTransactionManager;
 import org.apache.avalon.fortress.impl.interceptor.test.examples.ValidInterceptor;
 import org.apache.avalon.fortress.interceptor.Interceptor;
-import org.apache.avalon.fortress.interceptor.InterceptorManager;
-import org.apache.avalon.fortress.util.FortressConfig;
-import org.apache.avalon.framework.container.ContainerUtil;
-
-import junit.framework.TestCase;
 
 /**
  * Pending
  * 
  * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
  */
-public class DefaultInterceptorManagerTestCase extends TestCase
+public class DefaultInterceptorManagerTestCase extends AbstractInterceptorManagerTest
 {
-    private InterceptorEnabledContainer m_container;
-    private InterceptorManager m_interManager;
-    
-    /**
-     * Constructor for DefaultInterceptorManagerTestCase.
-     * @param name
-     */
-    public DefaultInterceptorManagerTestCase(String name)
-    {
-        super(name);
-    }
-
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-        
-        m_container = createContainer();
-        m_interManager = m_container.getInterceptorManager();
-    }
-
-    protected void tearDown() throws Exception
-    {
-        super.tearDown();
-        
-        m_container.dispose();
-    }
-
     public void testAddInterceptor() throws Exception
     {
-        m_interManager.add( "dao", "key", ValidInterceptor.class.getName() );
+        addValidInterceptor();
         String[] families = m_interManager.getFamilies();
         
         assertNotNull( families );
@@ -102,30 +69,29 @@
         assertNull( interceptor.getNext() );
     }
 
-    private InterceptorEnabledContainer createContainer() throws Exception
-    {
-        final FortressConfig config = new FortressConfig();
-        config.setContainerClass( InterceptorEnabledContainer.class );
-        config.setContextDirectory( "./" );
-        config.setWorkDirectory( "./" );
-        
-        final String BASE = "resource://org/apache/avalon/fortress/test/data/";
-        config.setContainerConfiguration( BASE + "test1.xconf" );
-        config.setLoggerManagerConfiguration( BASE + "test1.xlog" );
-
-        final ContainerManager cm = new DefaultContainerManager( config.getContext() );
-        ContainerUtil.initialize( cm );
-
-        return (InterceptorEnabledContainer) cm.getContainer();
-    }
     
     public void testGetComponent() throws Exception
     {
         testAddInterceptor();
         
-        m_container.get( CustomerDataAccessObject.ROLE, "*" );
+        ComponentHandler handler = (ComponentHandler) 
+            m_container.get( CustomerDataAccessObject.ROLE, "*" );
         
+        CustomerDataAccessObject dao = (CustomerDataAccessObject) handler.get();
         
-    }
+        assertEquals( 0, FakeTransactionManager.instance().getTransactionsStarted() );
+        assertEquals( 0, FakeTransactionManager.instance().getTransactionsFinished() );
+        
+        dao.save( "Data" );
+
+        assertEquals( 1, FakeTransactionManager.instance().getTransactionsStarted() );
+        assertEquals( 1, FakeTransactionManager.instance().getTransactionsFinished() );
+        
+        dao.save( "More data" );
 
+        assertEquals( 2, FakeTransactionManager.instance().getTransactionsStarted() );
+        assertEquals( 2, FakeTransactionManager.instance().getTransactionsFinished() );
+        
+        handler.put( dao );
+    }
 }

Added: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/PerformanceTestCase.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/PerformanceTestCase.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.test;
+
+import org.apache.avalon.fortress.impl.handler.ComponentHandler;
+import org.apache.avalon.fortress.impl.interceptor.test.components.CustomerDataAccessObject;
+import org.apache.avalon.fortress.impl.interceptor.test.components.SupplierDataAccessObject;
+import org.apache.avalon.fortress.impl.interceptor.test.examples.FakeTransactionManager;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class PerformanceTestCase extends AbstractInterceptorManagerTest
+{
+    public void testGetInterceptableComponent() throws Exception
+    {
+        addValidInterceptor();
+        
+        ComponentHandler handler = (ComponentHandler) 
+            m_container.get( CustomerDataAccessObject.ROLE, "*" );
+
+        CustomerDataAccessObject dao = (CustomerDataAccessObject) handler.get();
+
+        long begin = System.currentTimeMillis();
+
+        for( int i = 0; i < 60000; i++ )
+        {
+            FakeTransactionManager.instance().clear();
+            
+            assertEquals( 0, FakeTransactionManager.instance().getTransactionsStarted() );
+            assertEquals( 0, FakeTransactionManager.instance().getTransactionsFinished() );
+            
+            dao.save( "Data" );
+    
+            assertEquals( 1, FakeTransactionManager.instance().getTransactionsStarted() );
+            assertEquals( 1, FakeTransactionManager.instance().getTransactionsFinished() );
+        }
+        
+        long end = System.currentTimeMillis();
+
+        handler.put( dao );
+        
+        System.out.println( "testGetInterceptableComponent took " + (end - begin) + " ms" );
+    }
+
+    public void testGetOrdinaryComponent() throws Exception
+    {
+        ComponentHandler handler = (ComponentHandler) 
+            m_container.get( SupplierDataAccessObject.ROLE, "*" );
+
+        SupplierDataAccessObject dao = (SupplierDataAccessObject) handler.get();
+
+        long begin = System.currentTimeMillis();
+
+        for( int i = 0; i < 60000; i++ )
+        {
+            FakeTransactionManager.instance().clear();
+            
+            assertEquals( 0, FakeTransactionManager.instance().getTransactionsStarted() );
+            assertEquals( 0, FakeTransactionManager.instance().getTransactionsFinished() );
+            
+            dao.save( "Data" );
+    
+            assertEquals( 1, FakeTransactionManager.instance().getTransactionsStarted() );
+            assertEquals( 1, FakeTransactionManager.instance().getTransactionsFinished() );
+        }
+        
+        long end = System.currentTimeMillis();
+
+        handler.put( dao );
+        
+        System.out.println( "testGetOrdinaryComponent took " + (end - begin) + " ms" );
+    }
+}

Modified: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/CustomerDAOImpl.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/CustomerDAOImpl.java	(original)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/CustomerDAOImpl.java	Fri Jul  9 21:02:55 2004
@@ -33,5 +33,6 @@
      */
     public void save( final Object data )
     {
+        // Some fake work
     }
 }

Added: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObject.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObject.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.test.components;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public interface SupplierDataAccessObject extends DataAccessObject
+{
+    static String ROLE = SupplierDataAccessObject.class.getName();  
+
+}

Added: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObjectImpl.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/components/SupplierDataAccessObjectImpl.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.test.components;
+
+import org.apache.avalon.fortress.impl.interceptor.test.examples.FakeTransactionManager;
+
+/**
+ * @avalon.component
+ * @avalon.service type=SupplierDataAccessObject
+ * @x-avalon.lifestyle type=singleton
+ * @x-avalon.info name=supplierDAO
+ *
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class SupplierDataAccessObjectImpl implements SupplierDataAccessObject
+{
+    /**
+     * @excalibur.transaction required
+     */
+    public void save( final Object data )
+    {
+        FakeTransactionManager.instance().startTransaction();
+        
+        // Some fake work
+        
+        FakeTransactionManager.instance().endTransaction();
+    }
+
+}

Added: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/FakeTransactionManager.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/FakeTransactionManager.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.impl.interceptor.test.examples;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class FakeTransactionManager
+{
+    private static final FakeTransactionManager m_instance = new FakeTransactionManager();
+    
+    private int m_transactionsStarted;
+    private int m_transactionsFinished;
+    
+    public static FakeTransactionManager instance()
+    {
+        return m_instance;
+    }
+    
+    public void clear()
+    {
+        m_transactionsStarted = m_transactionsFinished = 0;
+    }
+    
+    public void startTransaction()
+    {
+        m_transactionsStarted ++;
+    }
+
+    public void endTransaction()
+    {
+        m_transactionsFinished ++;
+    }
+    
+    /**
+     * @return
+     */
+    public int getTransactionsFinished()
+    {
+        return m_transactionsFinished;
+    }
+
+    /**
+     * @return
+     */
+    public int getTransactionsStarted()
+    {
+        return m_transactionsStarted;
+    }
+
+}

Modified: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/ValidInterceptor.java
==============================================================================
--- excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/ValidInterceptor.java	(original)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/impl/interceptor/test/examples/ValidInterceptor.java	Fri Jul  9 21:02:55 2004
@@ -17,6 +17,10 @@
 
 package org.apache.avalon.fortress.impl.interceptor.test.examples;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.avalon.fortress.ExtendedMetaInfo;
 import org.apache.avalon.fortress.impl.interceptor.AbstractInterceptor;
 
 /**
@@ -26,4 +30,21 @@
  */
 public class ValidInterceptor extends AbstractInterceptor
 {
+    /**
+     * Document me!
+     *  
+     * @see org.apache.avalon.fortress.interceptor.Interceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
+        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
+    {
+        FakeTransactionManager.instance().startTransaction();
+        
+        Object returnData = super.intercept(instance, meta, method, args);
+        
+        FakeTransactionManager.instance().endTransaction();
+        
+        return returnData;
+    }
+
 }

Modified: excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/test/data/test1.xconf
==============================================================================
--- excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/test/data/test1.xconf	(original)
+++ excalibur/branches/fortress-experiments/container-test/src/test/org/apache/avalon/fortress/test/data/test1.xconf	Fri Jul  9 21:02:55 2004
@@ -17,19 +17,22 @@
 <test>
     <component1 id="component1"
         logger="component1"
-        activation="startup"/>
+        activation="lazy"/>
     <component2 id="component2"
         logger="component2"
         pool-min="2"
-        activation="startup"/>
+        activation="lazy"/>
     <component3 id="component3"
         logger="component3"
-        activation="startup"/>
+        activation="lazy"/>
     <component4 id="component4"
         logger="component4"
-        activation="startup"/>
+        activation="lazy"/>
     <customerDAO id="customerDAO"
         logger="customerDAO"
+        activation="lazy"/>
+    <supplierDAO id="supplierDAO"
+        logger="supplierDAO"
         activation="lazy"/>
 </test>
 

Modified: excalibur/branches/fortress-experiments/examples/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/examples/project.xml	(original)
+++ excalibur/branches/fortress-experiments/examples/project.xml	Fri Jul  9 21:02:55 2004
@@ -102,7 +102,17 @@
         <!-- dependencies for tools -->
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
         </dependency>
         <dependency>
             <id>ant</id>

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xconf
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xconf	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+<!--
+Copyright 2004 The Apache Software Foundation
+Licensed  under the  Apache License,  Version 2.0  (the "License");
+you may not use  this file  except in  compliance with the License.
+You may obtain a copy of the License at 
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed  under the  License is distributed on an "AS IS" BASIS,
+WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+implied.
+
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<!-- Example Fortress configuration file -->
+<fortress-example>
+
+  <persistenceManager id="persistenceManager" logger="persistenceManager" activation="lazy" />
+  
+  <interceptorManager>
+  
+    <set family="businessObject">
+      <interceptor 
+      		name="security" 
+      		class="org.apache.avalon.fortress.examples.interceptors.business.interceptors.SecurityInterceptor" />
+      <interceptor 
+      		name="transactional" 
+      		class="org.apache.avalon.fortress.examples.interceptors.business.interceptors.TransactionalInterceptor" />
+    </set>
+  
+  </interceptorManager>
+  
+</fortress-example>
+

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xlog
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Interceptors.xlog	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,28 @@
+<logkit logger="system.logkit" log-level="INFO">
+    
+    <factories>
+      <factory type="stream" class="org.apache.avalon.excalibur.logger.factory.StreamTargetFactory"/>
+    </factories>
+
+    <targets>
+      <stream id="console">
+        <stream>System.out</stream>
+        <format type="extended">
+          %7.7{priority} %23.23{time:yyyy-MM-dd HH:mm:ss.SSS} [%24.24{category}] (%{context}): %{message}\n%{throwable}
+        </format>
+      </stream>
+    </targets>
+
+    <categories>
+      <!-- Log output from the default logger -->
+      <category name="" log-level="INFO">
+        <log-target id-ref="console"/>
+      </category>
+
+      <!-- Log output from the fortress system -->
+      <category name="system" log-level="INFO">
+        <log-target id-ref="console"/>
+      </category>
+    </categories>
+
+</logkit>

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Main.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/Main.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,77 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.fortress.examples.interceptors;
+
+import org.apache.avalon.fortress.examples.interceptors.business.PersistenceManager;
+import org.apache.avalon.fortress.impl.DefaultContainerManager;
+import org.apache.avalon.fortress.impl.InterceptorEnabledContainer;
+import org.apache.avalon.fortress.util.FortressConfig;
+import org.apache.avalon.fortress.ContainerManager;
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * Fortress container example allowing you to perform lookups on components
+ * via a simple swing gui.
+ *
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public final class Main
+{
+    /**
+     * @param args a <code>String[]</code> array of command line arguments
+     * @exception java.lang.Exception if an error occurs
+     */
+    public static final void main( String[] args )
+        throws Exception
+    {
+        final FortressConfig config = new FortressConfig();
+        config.setContainerClass( InterceptorEnabledContainer.class );
+        config.setContainerConfiguration( "resource://org/apache/avalon/fortress/examples/interceptors/Interceptors.xconf" );
+        config.setLoggerManagerConfiguration( "resource://org/apache/avalon/fortress/examples/interceptors/Interceptors.xlog" );
+
+        ContainerManager cm = new DefaultContainerManager( config.getContext() );
+        ContainerUtil.initialize( cm );
+        
+        InterceptorEnabledContainer container = (InterceptorEnabledContainer) cm.getContainer();
+        
+        ServiceManager manager = container.getServiceManager();
+        
+        PersistenceManager persistenceManager = (PersistenceManager) manager.lookup( PersistenceManager.ROLE );
+        
+        // Within an worker role, we should access the method
+
+        WhoAmI.instance().checkIn( "Homer", "Worker" );
+        persistenceManager.persist( "my profile info" );
+        
+        // Student role is not accepted
+
+        try
+        {
+            WhoAmI.instance().checkIn( "Bart", "Student" );
+            persistenceManager.persist( "my profile info" );
+        }
+        catch( SecurityException ex )
+        {
+            
+        }
+        
+        ContainerUtil.dispose( cm );
+    }
+}
+

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/WhoAmI.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/WhoAmI.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.examples.interceptors;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class WhoAmI
+{
+    private static final WhoAmI m_instance = new WhoAmI();
+
+    private String m_name;
+    private String m_role;
+    
+    private WhoAmI()
+    {
+    }
+    
+    public static WhoAmI instance()
+    {
+        return m_instance;
+    }
+    
+    public void checkIn( String name, String role )
+    {
+        m_name = name;
+        m_role = role;
+    }
+    
+    public String getRole()
+    {
+        return m_role;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+}

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/DefaultPersistenceManager.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/DefaultPersistenceManager.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.examples.interceptors.business;
+
+/**
+ * @avalon.component
+ * @avalon.service type=PersistenceManager
+ * @x-avalon.info name=persistenceManager
+ * @x-avalon.lifestyle type=singleton
+ * @excalibur.interceptable family=businessObject
+ * 
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class DefaultPersistenceManager implements PersistenceManager
+{
+    /**
+     * @transaction.required
+     * @security.enabled roles=Admin,Director,Worker
+     */
+    public void persist(Object data)
+    {
+        // Working, working, working
+    }
+
+    /**
+     * @transaction.supported
+     */
+    public Object load()
+    {
+        return "Data";
+    }
+}

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/PersistenceManager.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/PersistenceManager.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.examples.interceptors.business;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public interface PersistenceManager
+{
+    static String ROLE = PersistenceManager.class.getName(); 
+    
+    void persist( Object data );
+    
+    Object load( );
+}

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/SecurityInterceptor.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/SecurityInterceptor.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.examples.interceptors.business.interceptors;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.StringTokenizer;
+
+import org.apache.avalon.fortress.ExtendedMetaInfo;
+import org.apache.avalon.fortress.attributes.AttributeInfo;
+import org.apache.avalon.fortress.examples.interceptors.WhoAmI;
+import org.apache.avalon.fortress.impl.interceptor.AbstractInterceptor;
+
+/**
+ * Sample security interceptor. Checks if the current user have 
+ * the necessary role to execute the method.
+ * This is just a sample and for the sake of readability
+ * it hasn't been optimized in any way.
+ * 
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class SecurityInterceptor extends AbstractInterceptor
+{
+    /**
+     * Checks the required roles and the current user role.
+     */
+    public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
+        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
+    {
+        AttributeInfo attribute = meta.getAttributeForMethod( "security.enabled", method );
+        
+        if (attribute != null)
+        {
+            boolean canAccess = false;
+
+            final String roles = (String) attribute.getProperties().get( "roles" );
+            
+            // First lets see if the current user can access
+            
+            final String currentRole = WhoAmI.instance().getRole();
+            
+            StringTokenizer tokenizer = new StringTokenizer(roles, ",");
+            while( tokenizer.hasMoreTokens() )
+            {
+                final String token = tokenizer.nextToken();
+                
+                if (token.equalsIgnoreCase( currentRole ))
+                {
+                    canAccess = true;
+                }
+            }
+            
+            if (!canAccess)
+            {
+                throw new SecurityException("You don't have ne necessary roles to access this method.");
+            }
+        }
+        
+        // Allows the chain to proceed.
+        
+        return super.intercept(instance, meta, method, args);
+    }
+}

Added: excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/TransactionalInterceptor.java
==============================================================================
--- (empty file)
+++ excalibur/branches/fortress-experiments/examples/src/java/org/apache/avalon/fortress/examples/interceptors/business/interceptors/TransactionalInterceptor.java	Fri Jul  9 21:02:55 2004
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package org.apache.avalon.fortress.examples.interceptors.business.interceptors;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.avalon.fortress.ExtendedMetaInfo;
+import org.apache.avalon.fortress.impl.interceptor.AbstractInterceptor;
+
+/**
+ * @author <a href="mailto:dev@excalibur.apache.org">Excalibur Development Team</a>
+ */
+public class TransactionalInterceptor extends AbstractInterceptor
+{
+
+    /**
+     * Document me!
+     *  
+     * @see org.apache.avalon.fortress.interceptor.Interceptor#intercept(java.lang.Object, org.apache.avalon.fortress.ExtendedMetaInfo, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object intercept(Object instance, ExtendedMetaInfo meta, Method method, Object[] args)
+        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
+    {
+        // TODO Auto-generated method stub
+        return super.intercept(instance, meta, method, args);
+    }
+
+}

Modified: excalibur/branches/fortress-experiments/meta/project.xml
==============================================================================
--- excalibur/branches/fortress-experiments/meta/project.xml	(original)
+++ excalibur/branches/fortress-experiments/meta/project.xml	Fri Jul  9 21:02:55 2004
@@ -44,7 +44,17 @@
         </dependency>
         <dependency>
             <id>qdox</id>
-            <version>1.2</version>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-runtime</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <id>metaclass</id>
+            <artifactId>metaclass-tools</artifactId>
+            <version>1.1</version>
         </dependency>
         <dependency>
             <id>ant</id>

Modified: excalibur/branches/fortress-experiments/meta/src/java/org/apache/avalon/fortress/tools/Component.java
==============================================================================
--- excalibur/branches/fortress-experiments/meta/src/java/org/apache/avalon/fortress/tools/Component.java	(original)
+++ excalibur/branches/fortress-experiments/meta/src/java/org/apache/avalon/fortress/tools/Component.java	Fri Jul  9 21:02:55 2004
@@ -26,7 +26,6 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.ObjectOutputStream;
 import java.util.*;
 
 /**
@@ -373,9 +372,7 @@
         
         try
         {
-            ObjectOutputStream objOutStream = new ObjectOutputStream( outStream );
-            QDoxSerializer.instance().serialize( objOutStream, m_javaClass );
-            objOutStream.close();
+            QDoxSerializer.instance().serialize( outStream, m_javaClass );
         }
         finally
         {

Modified: excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ComponentTestCase.java
==============================================================================
--- excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ComponentTestCase.java	(original)
+++ excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ComponentTestCase.java	Fri Jul  9 21:02:55 2004
@@ -47,7 +47,7 @@
     {
         super.setUp();
         
-        JavaClass model = new JavaClass()
+        JavaClass model = new JavaClass(null)
         {
             public String getFullyQualifiedName()
             {

Modified: excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ServiceTestCase.java
==============================================================================
--- excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ServiceTestCase.java	(original)
+++ excalibur/branches/fortress-experiments/meta/src/test/org/apache/avalon/fortress/tools/test/ServiceTestCase.java	Fri Jul  9 21:02:55 2004
@@ -69,7 +69,7 @@
 
     public void testAddComponent()
     {
-        JavaClass model = new JavaClass()
+        JavaClass model = new JavaClass(null)
         {
             public String getFullyQualifiedName()
             {

---------------------------------------------------------------------
To unsubscribe, e-mail: scm-unsubscribe@excalibur.apache.org
For additional commands, e-mail: scm-help@excalibur.apache.org