[jboss-cvs] JBossAS SVN: r76038 - in projects/aop/branches/joinpoint_graph/aop/src: test/org/jboss/aop/joinpoint/graph and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sun Jul 20 18:23:06 EDT 2008


Author: flavia.rainone at jboss.com
Date: 2008-07-20 18:23:06 -0400 (Sun, 20 Jul 2008)
New Revision: 76038

Added:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MetaDataUpdater.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParserUtil.java
Modified:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeDomainData.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraph.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphFactory.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphImpl.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Node.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardClassNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/UnitaryJoinPointGraph.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/MainJoinPointGraphTest.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java
Log:
[JBAOP-509] Integration required new features from the graph:
- graph cloning
- ability of updating when an annotation override is added
- tracking of unitary domain graph instances
- GeneratedAdvisorDomain now reads as an unitary domain
- lazy initialization of unitary joinpoint graph (the advisor is not part of the domain when the graph is created)
- support for overriden methods (the overriden method infos were literarily overriding the original method infos)
Besides, the @Mixin-annotated method of Pojo5 had to become public static because it was breaking one of the
JBoss AOP unit tests.

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/AdvisedData.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -35,7 +35,7 @@
  * 
  * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
  */
-class AdvisedData
+class AdvisedData implements Cloneable
 {
    private Advisor advisor;
    private Tree<FieldNode> fields;
@@ -96,6 +96,22 @@
    }
    
    /**
+    * Updates the {@code field} keys, adding a new metadata.
+    * 
+    * @param field    the field that acquired a new metadata
+    * @param metaData a new metadata that has been attached to {@code field}
+    */
+   public void updateField(Field field, String metaData)
+   {
+      String defaultKey = FieldNode.getIdentifierKey(field);
+      FieldNode fieldNode = fields.searchValue(defaultKey);
+      if (fieldNode != null)
+      {
+         fields.insert(fieldNode.getMetaDataKey(metaData), fieldNode);
+      }
+   }
+   
+   /**
     * Returns the behavior node that represents {@code constructor}.
     * 
     * @param constructor  a member of the class managed by {@link #getAdvisor}. This
@@ -117,6 +133,22 @@
    }
    
    /**
+    * Updates the {@code constructor} keys, adding a new metadata.
+    * 
+    * @param constructor the constructor that acquired a new metadata
+    * @param metaData    a new metadata that has been attached to {@code constructor}
+    */
+   public void updateBehavior(Constructor constructor, String metaData)
+   {
+      String defaultKey = BehaviorNode.getIdentifierKey(constructor);
+      BehaviorNode behaviorNode = behaviors.searchValue(defaultKey);
+      if (behaviorNode != null)
+      {
+         behaviors.insert(behaviorNode.getMetaDataKey(metaData), behaviorNode);
+      }
+   }
+   
+   /**
     * Returns the behavior node that represents {@code method}.
     * 
     * @param method  a member of the class managed by {@link #getAdvisor}. This
@@ -138,6 +170,22 @@
    }
 
    /**
+    * Updates the {@code method} keys, adding a new metadata.
+    * 
+    * @param method   the method that acquired a new metadata
+    * @param metaData a new metadata that has been attached to {@code method}
+    */
+   public void updateBehavior(Method method, String metaData)
+   {
+      String defaultKey = BehaviorNode.getIdentifierKey(method);
+      BehaviorNode behaviorNode = behaviors.searchValue(defaultKey);
+      if (behaviorNode != null)
+      {
+         behaviors.insert(behaviorNode.getMetaDataKey(metaData), behaviorNode);
+      }
+   }
+   
+   /**
     * Searches for all field nodes whose keys match {@code fieldExpression}.
     * The search is performed on the field subtree, hence returning only
     * members associated with {@link #getAdvisor()}.
@@ -164,4 +212,12 @@
    {
       return behaviors.search(behaviorExpression);
    }
+   
+   public AdvisedData clone()
+   {
+      AdvisedData advisedData = new AdvisedData(this.advisor);
+      advisedData.fields = this.fields.clone();
+      advisedData.behaviors = this.behaviors.clone();
+      return advisedData;
+   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/BehaviorNode.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -114,6 +114,31 @@
    }
    
    /**
+    * Returns the key that identifies uniquely a callee.
+    * 
+    * @param clazz  the callee class
+    * @param method the callee method
+    * @return the the identifier key of {@code method} as a callee
+    */
+   private static final String getCalleeIdentifierKey(Class<?> clazz, Method method)
+   {
+      return clazz.getName() + SEPARATOR + getIdentifierKey(method);
+   }
+   
+   private static final Collection<String> getCalleeMetaDataKey(Class<?> clazz, Method method, String metaData)
+   {
+      CALLEE_KEY_LOADER.loadCallee(clazz, method);
+      try
+      {
+         return CALLEE_KEY_LOADER.getMetaDataKeys(metaData);
+      }
+      finally
+      {
+         CALLEE_KEY_LOADER.unloadCallee();
+      }
+   }
+   
+   /**
     * Returns the key that would identify a behavior node representing {@code
     * constructor} in the graph.
     * <p>
@@ -132,6 +157,31 @@
    }
    
    /**
+    * Returns the key that identifies uniquely a callee.
+    * 
+    * @param clazz       the callee class
+    * @param constructor the callee constructor
+    * @return the the identifier key of {@code constructor} as a callee
+    */
+   private static final String getCalleeIdentifierKey(Class<?> clazz, Constructor constructor)
+   {
+      return clazz.getName() + SEPARATOR + getIdentifierKey(constructor);
+   }
+   
+   private static final Collection<String> getCalleeMetaDataKey(Constructor constructor, String metaData)
+   {
+      CALLEE_KEY_LOADER.loadCallee(constructor.getDeclaringClass(), constructor);
+      try
+      {
+         return CALLEE_KEY_LOADER.getMetaDataKeys(metaData);
+      }
+      finally
+      {
+         CALLEE_KEY_LOADER.unloadCallee();
+      }
+   }
+   
+   /**
     * Loads all meta data keys of a behavior node representing {@code behavior}.
     * 
     * @param behavior the behavior whose metadata keys must be loaded
@@ -157,6 +207,11 @@
       return getIdentifierKey(this.behavior, this.behaviorType);
    }
    
+   public String getMetaDataKey(String metaData)
+   {
+      return getMetaDataKey(behavior, metaData, behaviorType);
+   }
+   
    public void loadMetaDataKeys(Collection<String> keys)
    {
       loadMetaDataKeys(behavior, behaviorType, "", advisor, keys);
@@ -277,8 +332,8 @@
          try
          {
             TreeInsertionUtil.insertObject(callInfo, calls,
-                  callInfo.getCalledClass().getName() + SEPARATOR + getIdentifierKey(
-                  callInfo.getConstructor()), CALLEE_KEY_LOADER);
+                  getCalleeIdentifierKey(callInfo.getCalledClass(),
+                        callInfo.getConstructor()), CALLEE_KEY_LOADER);
          }
          finally
          {
@@ -288,6 +343,29 @@
    }
    
    /**
+    * Updates {@code constructor} as a callee, adding a new metadata do this
+    * constructor on the graph.
+    * <p>
+    * If {@code constructor} is not a callee of this node, no action is performed.
+    * 
+    * @param constructor constructor that has a new metadata attached to it
+    * @param metaData    new metadata of {@code constructor}
+    */
+   public synchronized void updateCallee(Constructor constructor, String metaData)
+   {
+      String calleeId = BehaviorNode.getCalleeIdentifierKey(constructor.getDeclaringClass(), constructor);
+      
+      JoinPointInfo info = this.calls.searchValue(calleeId);
+      if (info != null)
+      {
+         for (String metaDataKey: getCalleeMetaDataKey(constructor, metaData))
+         {
+            calls.insert(metaDataKey, info);
+         }
+      }
+   }
+   
+   /**
     * Inserts a call joinpoint in the callee subtree.
     * 
     * @param callInfo a method call joinpoint whose caller is the behavior
@@ -302,8 +380,8 @@
          try
          {
             TreeInsertionUtil.insertObject(callInfo, calls,
-                  callInfo.getCalledClass().getName() + SEPARATOR +
-                  getIdentifierKey(callInfo.getMethod()), CALLEE_KEY_LOADER);
+                  getCalleeIdentifierKey(callInfo.getCalledClass(),
+                        callInfo.getMethod()), CALLEE_KEY_LOADER);
          }
          finally
          {
@@ -313,6 +391,30 @@
    }
    
    /**
+    * Updates {@code method} as a callee, adding a new metadata do this method on the
+    * graph.
+    * <p>
+    * If {@code method} is not a callee of this node, no action is performed.
+    * 
+    * @param method   method that has a new metadata attached to it
+    * @param metaData new metadata of {@code method}
+    */
+   public synchronized void updateCallee(Method method, String metaData)
+   {
+      String calleeId = BehaviorNode.getCalleeIdentifierKey(method.getDeclaringClass(), method);
+      
+      JoinPointInfo info = this.calls.searchValue(calleeId);
+      if (info != null)
+      {
+         for (String metaDataKey: getCalleeMetaDataKey(method.getDeclaringClass(), method, metaData))
+         {
+            calls.insert(metaDataKey, info);
+         }
+      }
+      // TODO check subtypes for overriding methods
+   }
+      
+   /**
     * Returns all callees identified by keys that match {@code calleeExpression}.
     * 
     * @param calleeExpression a search expression. This expression can follow the
@@ -344,7 +446,7 @@
       return type.getName(member) + getParameterList(member, type);
    }
    
-   private static final String getMetaDataKey(Member member, String metaData, BehaviorType type)
+   static final String getMetaDataKey(Member member, String metaData, BehaviorType type)
    {
       return type.getMetaDataName(member, metaData) + getParameterList(member, type);
    }

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CalleeMetaDataKeyLoader.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -123,6 +123,35 @@
       }
    }
    
+   /**
+    * Returns the loaded callee keys that represent {@code metaData}.
+    * 
+    * @param metaData a metadata associated with the loaded callee
+    * @return the set of keys that represent the loaded callee using {@code metaData}
+    */
+   public Collection<String> getMetaDataKeys(String metaData)
+   {
+      Collection<String> result = new ArrayList<String>();
+      synchronized (tempKeys)
+      {
+         try
+         {
+            AdvisableClassNode.loadMetaDataKeys(advisor, tempKeys);
+            String metaDataKey = BehaviorNode.getMetaDataKey(member, metaData, type);
+            result.add(className + BehaviorNode.SEPARATOR + metaDataKey);
+            for (String classMetaDataKey: tempKeys)
+            {
+               result.add(classMetaDataKey + BehaviorNode.SEPARATOR + metaDataKey);
+            }
+         }
+         finally
+         {
+            tempKeys.clear();
+         }
+      }
+      return result;
+   }
+   
    public Advisor getMetaDataContainer()
    {
       return this.advisor;

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ClassNode.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -71,6 +71,11 @@
       return getIdentifierKey(this.clazz);
    }
    
+   public String getMetaDataKey(String metaData)
+   {
+      return '@' + metaData;
+   }
+   
    public void loadMetaDataKeys(Collection<String> keys)
    {
       loadMetaDataKeys(this.getMetaDataContainer(), keys);

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeDomainData.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeDomainData.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/CompositeDomainData.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -21,6 +21,9 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
@@ -119,6 +122,36 @@
       return getComponent(advisor);
    }
    
+   @Override
+   public void updateField(Field field, String metaData)
+   {
+      super.updateField(field, metaData);
+      for (AdvisedData advisedData: components.values())
+      {
+         advisedData.updateField(field, metaData);
+      }
+   }
+   
+   @Override
+   public void updateBehavior(Constructor constructor, String metaData)
+   {
+      super.updateBehavior(constructor, metaData);
+      for (AdvisedData advisedData: components.values())
+      {
+         advisedData.updateBehavior(constructor, metaData);
+      }
+   }
+   
+   @Override
+   public void updateBehavior(Method method, String metaData)
+   {
+      super.updateBehavior(method, metaData);
+      for (AdvisedData advisedData: components.values())
+      {
+         advisedData.updateBehavior(method, metaData);
+      }
+   }
+   
    /**
     * Performs a search for field nodes matching {@code fieldExpression} on all
     * components of this domain data.

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldNode.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/FieldNode.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -77,6 +77,11 @@
       return getIdentifierKey(this.field);
    }
    
+   public String getMetaDataKey(String metaData)
+   {
+      return this.field.getType().getName() + " @" + metaData;
+   }
+   
    public void loadMetaDataKeys(Collection<String> names)
    {
       String commonPrefix = this.field.getType().getName() + " @";

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraph.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraph.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraph.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -24,6 +24,7 @@
 import java.util.Collection;
 
 import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.introduction.AnnotationIntroduction;
 import org.jboss.aop.pointcut.Pointcut;
 
 /**
@@ -40,4 +41,15 @@
     * @return a collection containing all joinpoints found during the search
     */
    public Collection<JoinPointInfo> search(Pointcut pointcut);
+   
+   /**
+    * Updates the data contained in this graph according to the metadata contained
+    * in {@code annotationOverride}.
+    * 
+    * @param annotationOverride indicate a set of methods, fields, constructors and
+    *                           classes that have acquired a new metadata, identified
+    *                           by this parameter
+    *                           
+    */
+   public void update(AnnotationIntroduction annotationOverride);
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphFactory.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphFactory.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphFactory.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -22,6 +22,7 @@
 package org.jboss.aop.joinpoint.graph;
 
 import org.jboss.aop.Domain;
+import org.jboss.aop.GeneratedAdvisorDomain;
 import org.jboss.aop.InstanceDomain;
 import org.jboss.aop.joinpoint.JoinPointRegistry;
 import org.jboss.aop.proxy.container.ProxyAdvisorDomain;
@@ -79,6 +80,10 @@
       {
          return new UnitaryJoinPointGraph((ProxyAdvisorDomain) domain);
       }
+      if (domain instanceof GeneratedAdvisorDomain)
+      {
+         return new UnitaryJoinPointGraph((GeneratedAdvisorDomain) domain);
+      }
       return new DomainJoinPointGraph(domain);
    }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphImpl.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphImpl.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/JoinPointGraphImpl.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -21,10 +21,15 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.HashSet;
 
+import org.jboss.aop.AspectManager;
 import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.introduction.AnnotationIntroduction;
 import org.jboss.aop.joinpoint.graph.tree.Tree;
 import org.jboss.aop.pointcut.Pointcut;
 
@@ -46,11 +51,18 @@
       classTree = new Tree<N>();
    }
    
-   public final Collection<JoinPointInfo> search(Pointcut pointcut)
+   public synchronized Collection<JoinPointInfo> search(Pointcut pointcut)
    {
       return this.search(getSearchKey(pointcut)); 
    }
    
+   public synchronized void update(AnnotationIntroduction annotationOverride)
+   {
+      MetaDataUpdater<N> updater = new MetaDataUpdater<N>(annotationOverride,
+            this, this.classTree);
+      updater.update();
+   }
+   
    /**
     * Inserts a class node to the root of this graph, {@link #classTree}.
     * 
@@ -103,6 +115,15 @@
       }
    }
    
+   public void update(N classNode, String metaData)
+   {
+      classTree.insert(classNode.getMetaDataKey(metaData), classNode);
+   }
+   
+   public abstract void update(N classNode, Field field, String metaData);
+   public abstract void update(N classNode, Constructor constructor, String metaData);
+   public abstract void update(N classNode, Method method, String metaData);
+   
    /**
     * Performs a search on this graph.
     * 
@@ -124,4 +145,11 @@
     * @return the search key corresponding to {@code pointcut}
     */
    protected abstract SearchKey getSearchKey(Pointcut pointcut);
+
+   /**
+    * Returns the manager whose domain is represented by this graph.
+    * 
+    * @return the manager associated with this graph
+    */
+   protected abstract AspectManager getManager();
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MainJoinPointGraph.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -22,6 +22,7 @@
 package org.jboss.aop.joinpoint.graph;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import org.jboss.aop.Advisor;
@@ -36,6 +37,8 @@
 import org.jboss.aop.MethodInfo;
 import org.jboss.aop.joinpoint.JoinPointRegistry;
 import org.jboss.aop.pointcut.Pointcut;
+import org.jboss.aop.proxy.container.InstanceProxyContainer;
+import org.jboss.aop.proxy.container.MarshalledProxyAdvisor;
 
 /**
  * The main joinpoint graph.
@@ -89,8 +92,12 @@
    
    public synchronized void register(MethodInfo info)
    {
-      getBehavior(info.getAdvisor(), info.getClazz(), info.getMethod()).
-         setExecution(info);
+      if (info.getAdvisor() != null && !(info.getAdvisor() instanceof InstanceProxyContainer)
+            && !(info.getAdvisor() instanceof MarshalledProxyAdvisor))
+      {
+         getBehavior(info.getAdvisor(), info.getClazz(), info.getMethod()).
+            setExecution(info);
+      }
    }
 
    public synchronized void register(ConByConInfo info)
@@ -144,6 +151,12 @@
       return SearchKeyParser.parse(pointcut, AspectManager.instance());
    }
    
+   @Override
+   protected AspectManager getManager()
+   {
+      return AspectManager.instance();
+   }
+   
    private BehaviorNode getBehavior(Advisor advisor, Class clazz,
          Constructor constructor)
    {
@@ -170,4 +183,43 @@
       }
       return classNode.getAdvisedData(advisor);
    }
+   
+   @Override
+   public synchronized void update(StandardClassNode classNode, String metaData)
+   {
+      super.update(classNode, metaData);
+      for (UnitaryJoinPointGraph graph: UnitaryJoinPointGraph.getInstances())
+      {
+         graph.update(classNode, metaData);
+      }
+   }
+   
+   public synchronized void update(StandardClassNode classNode, Field field, String metaData)
+   {
+      classNode.getAdvisedData().updateField(field, metaData);
+   }
+   
+   public synchronized void update(StandardClassNode classNode, Constructor constructor, String metaData)
+   {
+      classNode.getAdvisedData().updateBehavior(constructor, metaData);
+      for(StandardClassNode cn: classTree.search("*"))
+      {
+         for (BehaviorNode behaviorNode: cn.searchBehaviors("*"))
+         {
+            behaviorNode.updateCallee(constructor, metaData);
+         }
+      }
+   }
+   
+   public synchronized void update(StandardClassNode classNode, Method method, String metaData)
+   {
+      classNode.getAdvisedData().updateBehavior(method, metaData);
+      for(StandardClassNode cn: classTree.search("*"))
+      {
+         for (BehaviorNode behaviorNode: cn.searchBehaviors("*"))
+         {
+            behaviorNode.updateCallee(method, metaData);
+         }
+      }
+   }
 }
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MetaDataUpdater.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MetaDataUpdater.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/MetaDataUpdater.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.introduction.AnnotationIntroduction;
+import org.jboss.aop.joinpoint.graph.tree.Tree;
+import org.jboss.aop.pointcut.Typedef;
+import org.jboss.aop.pointcut.ast.ASTAllParameter;
+import org.jboss.aop.pointcut.ast.ASTAnd;
+import org.jboss.aop.pointcut.ast.ASTAttribute;
+import org.jboss.aop.pointcut.ast.ASTBoolean;
+import org.jboss.aop.pointcut.ast.ASTClass;
+import org.jboss.aop.pointcut.ast.ASTComposite;
+import org.jboss.aop.pointcut.ast.ASTConstructor;
+import org.jboss.aop.pointcut.ast.ASTException;
+import org.jboss.aop.pointcut.ast.ASTField;
+import org.jboss.aop.pointcut.ast.ASTHas;
+import org.jboss.aop.pointcut.ast.ASTHasField;
+import org.jboss.aop.pointcut.ast.ASTMethod;
+import org.jboss.aop.pointcut.ast.ASTNot;
+import org.jboss.aop.pointcut.ast.ASTOr;
+import org.jboss.aop.pointcut.ast.ASTParameter;
+import org.jboss.aop.pointcut.ast.ASTStart;
+import org.jboss.aop.pointcut.ast.ASTSub;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+import org.jboss.aop.pointcut.ast.SimpleNode;
+import org.jboss.aop.pointcut.ast.TypeExpressionParserVisitor;
+import org.jboss.util.NotImplementedException;
+
+/**
+ * Updates the metadata contained in a joinpoint graph accordingly to an instance of
+ * {@link #AnnotationIntroduction annotation overrides}.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class MetaDataUpdater <N extends ClassNode> implements TypeExpressionParserVisitor
+{
+   private JoinPointGraphImpl<N> graph;
+   private Tree<N> classTree;
+   private AnnotationIntroduction metaData;
+   private AspectManager manager;
+   ParserUtil util = new ParserUtil();
+   
+   /**
+    * Creates a meta data updater to update {@code graph}, adding the new meta data
+    * to it.
+    * 
+    * @param metaData  contains the metadata to be added to the graph and an
+    *                  expression identifying which elements will be affected by
+    *                  this addition
+    * @param graph     the graph that needs to be updated
+    * @param classTree the root of {@code graph}
+    */
+   public MetaDataUpdater(AnnotationIntroduction metaData,
+         JoinPointGraphImpl<N> graph, Tree<N> classTree)
+   {
+      this.metaData = metaData;
+      this.classTree = classTree;
+      this.graph = graph;
+      this.manager = graph.getManager();
+   }
+   
+   /**
+    * Performs the update proccess.
+    */
+   public void update()
+   {
+      this.visit(metaData.getTarget(), null);
+   }
+
+   public Object visit(ASTStart node, Object data)
+   {
+      return node.jjtGetChild(0).jjtAccept(this, data);
+   }
+
+   public Object visit(ASTBoolean node, Object data)
+   {
+      return node.jjtGetChild(0).jjtAccept(this, data);
+   }
+
+   public Object visit(ASTComposite node, Object data)
+   {
+      return node.jjtGetChild(0).jjtAccept(this, data);
+   }
+
+   // TODO
+   public Object visit(ASTNot node, Object data)
+   {
+      throw new NotImplementedException();
+   }
+
+   // TODO
+   public Object visit(ASTSub node, Object data)
+   {
+      throw new NotImplementedException();
+   }
+
+   // TODO
+   public Object visit(ASTAnd node, Object left)
+   {
+      throw new NotImplementedException();
+   }
+
+   // TODO
+   public Object visit(ASTOr node, Object left)
+   {
+      throw new NotImplementedException();
+   }
+
+
+   public Object visit(SimpleNode node, Object data)
+   {
+      return null;
+   }
+
+   // TODO
+   public Object visit(ASTHas node, Object data)
+   {
+      throw new NotImplementedException();
+   }
+
+   // TODO
+   public Object visit(ASTHasField node, Object data)
+   {
+      throw new NotImplementedException();
+   }
+
+   // FIXME
+   public Collection<N> visit(ASTClass node, Object data)
+   {
+      return getClassNodes(node.getClazz());
+   }
+   
+   public Collection<N> getClassNodes(ClassExpression classExpression)
+   {
+      if (classExpression.isTypedef())
+      {
+         Typedef typedef = TypedefParser.getTypedef(classExpression, manager);
+         String expression = TypedefParser.parse(typedef, manager);
+         Collection<N> result = classTree.search(expression);
+         for (Iterator<N> iterator = result.iterator(); iterator.hasNext(); )
+         {
+            ClassNode classNode = iterator.next();
+            if (!typedef.matches(classNode.getMetaDataContainer(), classNode.getClazz()))
+            {
+               iterator.remove();
+            }
+         }
+         return result;
+      }
+      if (classExpression.isInstanceOf() || classExpression.isInstanceOfAnnotated())
+      {
+         String expression = classExpression.getOriginal();
+         expression = expression.substring("$instanceof{".length(), expression.length() - 1);
+         Collection<N> nodesFound = classTree.search(expression);
+         Collection<N> result = new HashSet<N>();
+         result.addAll(nodesFound);
+         for (N cn: nodesFound)
+         {
+            addSubClasses(cn, result);
+         }
+         return result;
+      }
+      else
+      {
+         return classTree.search(classExpression.getOriginal());
+      }
+   }
+   
+   @SuppressWarnings("all")
+   private void addSubClasses(N classNode, Collection<N> classNodes)
+   {
+      for (Iterator<ClassNode> iterator = classNode.getSubtypes().iterator(); iterator.hasNext(); )
+      {
+         N subClassNode = (N) iterator.next();
+         classNodes.add(subClassNode);
+         addSubClasses(subClassNode, classNodes);
+      }
+   }
+
+   @SuppressWarnings("all")
+   public Object visit(ASTMethod node, Object data)
+   {
+      StringBuffer expression = new StringBuffer();
+      BehaviorFilter filter = util.visit(node, expression, manager);
+      for(N classNode: getClassNodes(node.getClazz()))
+      {
+         for (BehaviorNode behaviorNode: classNode.searchBehaviors(expression.toString()))
+         {
+            if (filter == null || filter.acceptMethod(behaviorNode))
+            {
+               graph.update(classNode, (Method) behaviorNode.getBehavior(),
+                     metaData.getAnnotation().getIdentifier());
+            }
+         }
+      }
+      return null;
+   }
+
+   @SuppressWarnings("all")
+   public Object visit(ASTConstructor node, Object data)
+   {
+      StringBuffer expression = new StringBuffer();
+      BehaviorFilter filter = util.parse(node, expression, manager);
+      for(N classNode: getClassNodes(node.getClazz()))
+      {
+         for (BehaviorNode behaviorNode: classNode.searchBehaviors(expression.toString()))
+         {
+            if (filter == null || filter.acceptConstructor(behaviorNode))
+            {
+               graph.update(classNode, (Constructor) behaviorNode.getBehavior(),
+                     metaData.getAnnotation().getIdentifier());
+            }
+         }
+      }
+      return null;
+   }
+
+   public Object visit(ASTField node, Object data)
+   {
+      StringBuffer expression = new StringBuffer();
+      FieldFilter filter = util.parse(node, expression, manager);
+      for(N classNode: getClassNodes(node.getClazz()))
+      {
+         for (FieldNode fieldNode: classNode.searchFields(expression.toString()))
+         {
+            if (filter == null || filter.accept(fieldNode))
+            {
+               graph.update(classNode, fieldNode.getField(),
+                     metaData.getAnnotation().getIdentifier());
+            }
+         }
+      }
+      return null;
+   }
+
+   public Object visit(ASTAttribute node, Object data)
+   {
+      return Boolean.FALSE;
+   }
+
+   public Object visit(ASTParameter node, Object data)
+   {
+      return Boolean.FALSE;
+   }
+
+   public Object visit(ASTAllParameter node, Object data)
+   {
+      return Boolean.FALSE;
+   }
+
+   public Object visit(ASTException node, Object data)
+   {
+      return Boolean.FALSE;
+   }
+   
+}

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Node.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Node.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/Node.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -52,6 +52,14 @@
    String getIdentifierKey();
    
    /**
+    * Returns the meta data key correspondent to {@code metadata}.
+    * 
+    * @param metaData a metadata attached to this node
+    * @return         the key correspondent to {@code meta data}
+    */
+   String getMetaDataKey(String metaData);
+   
+   /**
     * Loads all metadata keys that index this node in the tree it belongs.
     * <br>
     * The metadata keys are generated based on the metadata associated with the

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParserUtil.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParserUtil.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/ParserUtil.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.aop.joinpoint.graph;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.aop.pointcut.ast.ASTConstructor;
+import org.jboss.aop.pointcut.ast.ASTField;
+import org.jboss.aop.pointcut.ast.ASTMethod;
+import org.jboss.aop.pointcut.ast.ClassExpression;
+import org.jboss.aop.pointcut.ast.IdentifierExpression;
+
+/**
+ * Expression parser utility class.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class ParserUtil
+{
+   private ParameterParser parameterParser = new ParameterParser();
+   
+   /**
+    * Parses {@code node}, appending the result (a search expression that identifies
+    * one or more {@code FieldNode} instances) to {@code expression}. 
+    * 
+    * @param node       node to be parsed
+    * @param expression buffer where the node search expression will be appended
+    * @param manager    contains any pointcut and typedef references that may be
+    *                   found in {@code node}
+    * @return a filter containing extra checks to select the {@code FieldNode}
+    *         instances identified by {@code node}. If there is no need for extra-
+    *         checks, the search expression appended to {@code expression} is
+    *         enough and this method returns {@code null}.
+    */
+   public FieldFilter parse(ASTField node, StringBuffer expression, AspectManager manager)
+   {
+      ClassExpression filterTarget = parse(node.getType(), expression, manager);
+      expression.append(' ');
+      expression.append(node.getFieldIdentifier().getOriginal());
+      return filterTarget == null? null: new FieldTypeFilter(filterTarget);
+   }
+   
+   /**
+    * Parses {@code node}, appending the result (a search expression that identifies
+    * one or more {@code BehaviorNode} instances) to {@code expression}. 
+    * 
+    * @param node       node to be parsed
+    * @param expression buffer where the node search expression will be appended
+    * @param manager    contains any pointcut and typedef references that may be
+    *                   found in {@code node}
+    * @return a filter containing extra checks to select the {@code BehaviorNode}
+    *         instances identified by {@code node}. If there is no need for extra-
+    *         checks, the search expression appended to {@code expression} is
+    *         enough and this method returns {@code null}.
+    */
+   public BehaviorFilter parse(ASTConstructor node, StringBuffer expression, AspectManager manager)
+   {
+      // check identifier
+      IdentifierExpression annotationExp = node.getConstructorAnnotation();
+      if (annotationExp == null)
+      {
+         expression.append("new");
+      }
+      else
+      {
+         expression.append(annotationExp.getOriginal());
+      }
+      
+      // behaviour filter
+      return parameterParser.parse(node, manager, expression);
+   }
+   
+   /**
+    * Parses {@code node}, appending the result (a search expression that identifies
+    * one or more {@code BehaviorNode} instances) to {@code expression}. 
+    * 
+    * @param node       node to be parsed
+    * @param expression buffer where the node search expression will be appended
+    * @param manager    contains any pointcut and typedef references that may be
+    *                   found in {@code node}
+    * @return a filter containing extra checks to select the {@code BehaviorNode}
+    *         instances identified by {@code node}. If there is no need for extra-
+    *         checks, the search expression appended to {@code expression} is
+    *         enough and this method returns {@code null}.
+    */
+   public BehaviorFilter visit(ASTMethod node, StringBuffer expression, AspectManager manager)
+   {
+      // behaviour filter
+      BehaviorFilter behaviourFilter = null;
+      
+      // check return type
+      ClassExpression returnFilter = parse(node.getReturnType(), expression, manager);
+      if (returnFilter != null)
+      {
+         behaviourFilter = new ReturnTypeFilter(returnFilter);
+      }
+      expression.append(BehaviorNode.SEPARATOR).append(' ');
+      
+      // check identifier
+      IdentifierExpression identifier = node.getMethodIdentifier();
+      switch (identifier.getType())
+      {
+         case PATTERN:
+         case ANNOTATION:
+            expression.append(node.getMethodExpr());
+            break;
+         case IMPLEMENTS:
+         case IMPLEMENTING:
+            expression.append('*');
+            if (behaviourFilter != null)
+            {
+               behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter,
+                     new ImplementedMethodFilter(identifier));
+            }
+            else
+            {
+               behaviourFilter = new ImplementedMethodFilter(identifier);
+            }
+      }
+      
+      // check parameters
+      BehaviorFilter parameterFilter = parameterParser.parse(node, manager, expression);
+      if (parameterFilter != null)
+      {
+         if (behaviourFilter != null)
+         {
+            behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter, parameterFilter);
+         }
+         else
+         {
+            behaviourFilter = parameterFilter;
+         }
+      }
+      
+      // result
+      return behaviourFilter;
+   }
+   
+   /**
+    * Parses {@code type}, appending a search expression that searches for all types
+    * matched by it to {@code buffer}
+    * 
+    * @param type    the expression to be parsed
+    * @param buffer  buffer to where the parsing result will be appended
+    * @param manager contains any typedef references that may be found in {@code type}
+    * @return a class expression if any extra checks are needed in order to select
+    *         the classes that are identified by {@code type}
+    */
+   public  ClassExpression parse(ClassExpression type, StringBuffer buffer,
+         AspectManager manager)
+   {
+      // check return type
+      // should never be a package if it is a return type
+      if (type.isPackage() || type.isSimple())
+      {
+         buffer.append(type.getOriginal());
+         return null;
+      }
+      if (type.isTypedef())
+      {
+         buffer.append(TypedefParser.parse(type, manager));
+      }
+      else
+      {
+         buffer.append('*');
+      }
+      return type;
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/SearchKeyParser.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -61,7 +61,6 @@
 import org.jboss.aop.pointcut.ast.ASTWithin;
 import org.jboss.aop.pointcut.ast.ASTWithincode;
 import org.jboss.aop.pointcut.ast.ClassExpression;
-import org.jboss.aop.pointcut.ast.IdentifierExpression;
 import org.jboss.aop.pointcut.ast.PointcutExpressionParserVisitor;
 import org.jboss.aop.pointcut.ast.SimpleNode;
 
@@ -74,8 +73,8 @@
 class SearchKeyParser implements PointcutExpressionParserVisitor
 {
    private static SearchKeyParser INSTANCE = new SearchKeyParser();
-   private ParameterParser parameterParser = new ParameterParser();
    private AspectManager manager;
+   private ParserUtil util = new ParserUtil();
    
    /**
     * Parses the pointcut into a search key.
@@ -365,14 +364,7 @@
    {
       this.setClassExpression((SearchKey) data, node.getClazz());
       StringBuffer expression = new StringBuffer();
-      FieldFilter filter = null;
-      ClassExpression filterTarget = appendType(node.getType(), expression);
-      if (filterTarget != null)
-      {
-         filter = new FieldTypeFilter(filterTarget);
-      }
-      expression.append(' ');
-      expression.append(node.getFieldIdentifier().getOriginal());
+      FieldFilter filter = util.parse(node, expression, manager);
       return new FieldSearcher(expression.toString(), node.getAttributes(), filter);
    }
 
@@ -452,7 +444,7 @@
       // check target type
       if (searchKey == null)
       {
-         ClassExpression typeFilter = appendType(node.getClazz(), expression);
+         ClassExpression typeFilter = util.parse(node.getClazz(), expression, manager);
          if (typeFilter != null)
          {
             behaviourFilter = new TargetTypeFilter(typeFilter);
@@ -464,30 +456,16 @@
          this.setClassExpression(searchKey, node.getClazz());
       }
       
-      // check identifier
-      IdentifierExpression annotationExp = node.getConstructorAnnotation();
-      if (annotationExp == null)
+      BehaviorFilter utilFilter = util.parse(node, expression, manager);
+      if (behaviourFilter == null)
       {
-         expression.append("new");
+         return utilFilter;
       }
-      else
+      if (utilFilter == null)
       {
-         expression.append(annotationExp.getOriginal());
+         return behaviourFilter;
       }
-      
-      BehaviorFilter parameterFilter = parameterParser.parse(node, manager, expression);
-      if (parameterFilter != null)
-      {
-         if (behaviourFilter == null)
-         {
-            behaviourFilter = parameterFilter;
-         }
-         else
-         {
-            behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter, parameterFilter);
-         }
-      }
-      return behaviourFilter;
+      return new ConjunctiveBehaviorFilter(behaviourFilter, utilFilter);
    }
    
    private BehaviorFilter visit(ASTMethod node, StringBuffer expression, SearchKey searchKey)
@@ -498,7 +476,7 @@
       // check target type
       if(searchKey == null)
       {
-         ClassExpression typeFilter = appendType(node.getClazz(), expression);
+         ClassExpression typeFilter = util.parse(node.getClazz(), expression, manager);
          if (typeFilter != null)
          {
             behaviourFilter = new TargetTypeFilter(typeFilter);
@@ -509,83 +487,18 @@
       {
          this.setClassExpression(searchKey, node.getClazz());
       }
-      
-      // check return type
-      ClassExpression returnFilter = appendType(node.getReturnType(), expression);
-      if (returnFilter != null)
+      BehaviorFilter utilFilter = util.visit(node, expression, manager);
+      if (behaviourFilter == null)
       {
-         if (behaviourFilter == null)
-         {
-            behaviourFilter = new ReturnTypeFilter(returnFilter);
-         }
-         else
-         {
-            behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter,
-                     new ReturnTypeFilter(returnFilter));
-         }
+         return utilFilter;
       }
-      expression.append(BehaviorNode.SEPARATOR).append(' ');
-      
-      // check identifier
-      IdentifierExpression identifier = node.getMethodIdentifier();
-      switch (identifier.getType())
+      if (utilFilter == null)
       {
-         case PATTERN:
-         case ANNOTATION:
-            expression.append(node.getMethodExpr());
-            break;
-         case IMPLEMENTS:
-         case IMPLEMENTING:
-            expression.append('*');
-            if (behaviourFilter != null)
-            {
-               behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter,
-                     new ImplementedMethodFilter(identifier));
-            }
-            else
-            {
-               behaviourFilter = new ImplementedMethodFilter(identifier);
-            }
+         return behaviourFilter;
       }
-      
-      // check parameters
-      BehaviorFilter parameterFilter = parameterParser.parse(node, manager, expression);
-      if (parameterFilter != null)
-      {
-         if (behaviourFilter != null)
-         {
-            behaviourFilter = new ConjunctiveBehaviorFilter(behaviourFilter, parameterFilter);
-         }
-         else
-         {
-            behaviourFilter = parameterFilter;
-         }
-      }
-      
-      // result
-      return behaviourFilter;
+      return new ConjunctiveBehaviorFilter(behaviourFilter, utilFilter);
    }
 
-   private ClassExpression appendType(ClassExpression type, StringBuffer buffer)
-   {
-      // check return type
-      // should never be a package if it is a return type
-      if (type.isPackage() || type.isSimple())
-      {
-         buffer.append(type.getOriginal());
-         return null;
-      }
-      if (type.isTypedef())
-      {
-         buffer.append(TypedefParser.parse(type, manager));
-      }
-      else
-      {
-         buffer.append('*');
-      }
-      return type;
-   }
-   
    private void setClassExpression(SearchKey searchKey, ClassExpression classExpression)
    {
       if (classExpression.isSimple() || classExpression.isAnnotation() ||

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardClassNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardClassNode.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/StandardClassNode.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -62,7 +62,8 @@
    public AdvisedData getAdvisedData(Advisor advisor)
    {
       AdvisedData advisedData = super.getAdvisedData();
-      if (advisor instanceof InstanceAdvisor)
+      if (advisor instanceof InstanceAdvisor ||
+            (advisedData != null && advisor != advisedData.getAdvisor()))
       {
          if (advisedData == null)
          {

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/UnitaryJoinPointGraph.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/UnitaryJoinPointGraph.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/UnitaryJoinPointGraph.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -21,9 +21,21 @@
  */
 package org.jboss.aop.joinpoint.graph;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
 import org.jboss.aop.Advisor;
+import org.jboss.aop.AspectManager;
 import org.jboss.aop.Domain;
+import org.jboss.aop.GeneratedAdvisorDomain;
+import org.jboss.aop.InstanceAdvisor;
 import org.jboss.aop.InstanceDomain;
+import org.jboss.aop.JoinPointInfo;
+import org.jboss.aop.introduction.AnnotationIntroduction;
 import org.jboss.aop.joinpoint.graph.tree.Tree;
 import org.jboss.aop.pointcut.Pointcut;
 import org.jboss.aop.proxy.container.ProxyAdvisorDomain;
@@ -37,16 +49,63 @@
  */
 class UnitaryJoinPointGraph extends JoinPointGraphImpl<ClassNode>
 {
+   private enum DomainType {
+      GENERATED_ADVISOR
+      {
+         public Advisor getAdvisor(Domain domain)
+         {
+            return domain.getAdvisors().values().iterator().next().get();
+         }
+      },
+      INSTANCE_DOMAIN
+      {
+         public Advisor getAdvisor(Domain domain)
+         {
+            return ((InstanceDomain) domain).getAdvisor();
+         }
+      }
+      , PROXY_DOMAIN
+      {
+         public Advisor getAdvisor(Domain domain)
+         {
+            return ((ProxyAdvisorDomain) domain).getAdvisor();
+         }
+      };
+      
+      public abstract Advisor getAdvisor(Domain domain);
+   
+   };
+   
+   private static final Collection<UnitaryJoinPointGraph> INSTANCES =
+      new ArrayList<UnitaryJoinPointGraph>();
+   
+   public static Collection<UnitaryJoinPointGraph> getInstances()
+   {
+      return INSTANCES;
+   }
+   
    private Domain domain;
+   private DomainType domainType;
+   private boolean clonedData = false; 
    
    /**
     * Creates a graph to index the joinpoints managed by {@code domain}.
     * 
     * @param domain an unitary domain, containg a single instance advisor
     */
+   public UnitaryJoinPointGraph(GeneratedAdvisorDomain domain)
+   {
+      this(domain, DomainType.GENERATED_ADVISOR);
+   }
+   
+   /**
+    * Creates a graph to index the joinpoints managed by {@code domain}.
+    * 
+    * @param domain an unitary domain, containg a single instance advisor
+    */
    public UnitaryJoinPointGraph(InstanceDomain domain)
    {
-      this(domain, domain.getAdvisor());
+      this(domain, DomainType.INSTANCE_DOMAIN);
    }
    
    /**
@@ -56,18 +115,14 @@
     */
    public UnitaryJoinPointGraph(ProxyAdvisorDomain domain)
    {
-      this(domain, domain.getAdvisor());
+      this(domain, DomainType.PROXY_DOMAIN);
    }
    
-   private UnitaryJoinPointGraph(Domain domain, Advisor advisor)
+   private UnitaryJoinPointGraph(Domain domain, DomainType domainType)
    {
       this.domain = domain;
-      Class<?> clazz = advisor.getClazz();
-      String clazzId = ClassNode.getIdentifierKey(clazz);
-      Tree<StandardClassNode> mainGraph = MainJoinPointGraph.getInstance().classTree;
-      StandardClassNode classNode = mainGraph.searchValue(clazzId);
-      insertClassNode(new UnitaryDomainClassNode(clazz,
-            classNode.getAdvisedData(advisor)), ClassNode.getIdentifierKey(clazz));
+      this.domainType = domainType;
+      INSTANCES.add(this);
    }
    
    @Override
@@ -77,8 +132,108 @@
    }
    
    @Override
+   @SuppressWarnings("all")
+   public Collection<JoinPointInfo> search(Pointcut pointcut)
+   {
+      if (!initialise())
+      {
+         return Collections.EMPTY_LIST;
+      }
+      return super.search(pointcut);
+   }
+   
+   @Override
    protected SearchKey getSearchKey(Pointcut pointcut)
    {
       return SearchKeyParser.parse(pointcut, domain);
    }
+   
+   @Override
+   protected AspectManager getManager()
+   {
+      return domain;
+   }
+      
+   private synchronized boolean initialise()
+   {
+      if (!classTree.isEmpty())
+      {
+         return true;
+      }
+      Advisor advisor = this.domainType.getAdvisor(this.domain);
+      if (advisor == null)
+      {
+         return false;
+      }
+      Class<?> clazz = advisor.getClazz();
+      String clazzId = ClassNode.getIdentifierKey(clazz);
+      Tree<StandardClassNode> mainGraph = MainJoinPointGraph.getInstance().classTree;
+      AdvisedData advisedData = mainGraph.searchValue(clazzId).getAdvisedData(advisor);
+
+      if ((advisor.getName().contains("InstanceAdvisor") || advisor instanceof InstanceAdvisor)
+            && domain.hasOwnAnnotationOverrides())
+      {
+         advisedData = advisedData.clone();
+         clonedData = true;
+      }
+      insertClassNode(new UnitaryDomainClassNode(clazz, advisedData),
+            ClassNode.getIdentifierKey(clazz));
+      if (clonedData)
+      {
+         for (AnnotationIntroduction annOverride: domain.getOwnAnnotationOverrides())
+         {
+            update(annOverride);
+         }
+      }
+      return true;
+   }
+      
+   private void cloneData()
+   {
+      if (clonedData)
+      {
+         return;
+      }
+      this.classTree.clear();
+      this.initialise();
+   }
+   
+   public synchronized void update(ClassNode classNode, Field field, String metaData)
+   {
+      if (classTree.isEmpty())
+      {
+         return;
+      }
+      cloneData();
+      if (classNode instanceof AdvisableClassNode)
+      {
+         ((AdvisableClassNode) classNode).getAdvisedData().updateField(field, metaData);
+      }
+   }
+   
+   public synchronized void update(ClassNode classNode, Constructor constructor, String metaData)
+   {
+      if (classTree.isEmpty())
+      {
+         return;
+      }
+      cloneData();
+      if (classNode instanceof AdvisableClassNode)
+      {
+         ((AdvisableClassNode) classNode).getAdvisedData().updateBehavior(constructor, metaData);
+      }
+   }
+   
+   public synchronized void update(ClassNode classNode, Method method, String metaData)
+   {
+      if (classTree.isEmpty())
+      {
+         return;
+      }
+      cloneData();
+      if (classNode instanceof AdvisableClassNode)
+      {
+         ((AdvisableClassNode) classNode).getAdvisedData().updateBehavior(method, metaData);
+      }
+   }
 }
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/BehaviorSearcherTest.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -504,7 +504,7 @@
       searcher.setSearchType(SearchType.EXECUTION);
       searcher.search(classNode, result);  
       Util.assertCollection(result, privateMethodExec1, privateMethodExec2,
-            privateMethodExec3, calledByMethodExec);
+            privateMethodExec3);
    }
    
    public void testAttributeCall()

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/GraphInsertionTest.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -47,6 +47,7 @@
 import org.jboss.aop.joinpoint.JoinPointRegistry;
 import org.jboss.aop.joinpoint.MethodCall;
 import org.jboss.aop.joinpoint.graph.tree.Tree;
+import org.jboss.aop.pointcut.PointcutExpression;
 
 /**
  * Tests the graph insertion mechanism on all implementors of {@code JoinPointGraph}.
@@ -427,6 +428,8 @@
             (Domain) instanceAdvisor.getManager());
       assertTrue(domainGraph instanceof UnitaryJoinPointGraph);
       UnitaryJoinPointGraph unitaryGraph = (UnitaryJoinPointGraph) domainGraph;
+      // force initialization of the graph
+      unitaryGraph.search(new PointcutExpression("anyPointcut", "all(*)"));
       ClassNode objectNode = unitaryGraph.classTree.searchValue(
             ClassNode.getIdentifierKey(Object.class));
       ClassNode pojoNode = unitaryGraph.classTree.searchValue(
@@ -459,6 +462,8 @@
             (Domain) instanceAdvisor.getManager());
       assertTrue(domainGraph instanceof UnitaryJoinPointGraph);
       UnitaryJoinPointGraph unitaryGraph = (UnitaryJoinPointGraph) domainGraph;
+      // force initialization of the graph
+      unitaryGraph.search(new PointcutExpression("anyPointcut", "all(*)"));
       ClassNode objectNode = unitaryGraph.classTree.searchValue(
             ClassNode.getIdentifierKey(Object.class));
       ClassNode pojoNode = unitaryGraph.classTree.searchValue(

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/MainJoinPointGraphTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/MainJoinPointGraphTest.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/MainJoinPointGraphTest.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -341,7 +341,7 @@
             pojo3VoidMethodExec, pojo3StringMethodExec, pojo3IntLongSomeMethodExec,
             pojo3IntLongSomeMethodExec1, pojo3StringLongSomeMethodExec,
             pojo3StringLongSomeMethodExec1, pojo5CalledByConExec,
-            pojo5CalledByConExec2, pojo5CalledByMethodExec);
+            pojo5CalledByConExec2);
    }
    
    public void testComposition3() throws Exception

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java	2008-07-20 21:56:25 UTC (rev 76037)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/Pojo5.java	2008-07-20 22:23:06 UTC (rev 76038)
@@ -63,7 +63,7 @@
    public void calledByCon() throws NullPointerException, IllegalStateException {}
    
    @Mixin(interfaces={MetaDataKeyLoader.class})
-   void calledByMethod() {}
+   public static void calledByMethod() {}
 }
 
 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})




More information about the jboss-cvs-commits mailing list