[jboss-cvs] JBossAS SVN: r88328 - projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu May 7 01:57:31 EDT 2009


Author: flavia.rainone at jboss.com
Date: 2009-05-07 01:57:31 -0400 (Thu, 07 May 2009)
New Revision: 88328

Modified:
   projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceDefEntry.java
   projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceSorter.java
Log:
[JBAOP-730] Replaced the old cflow precedence algorithm by an algorithm that uses a graph to determine precedence, avoiding repetition of the same advice on the resulting overall precedence order.

Modified: projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceDefEntry.java
===================================================================
--- projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceDefEntry.java	2009-05-07 05:56:46 UTC (rev 88327)
+++ projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceDefEntry.java	2009-05-07 05:57:31 UTC (rev 88328)
@@ -72,6 +72,19 @@
       return false;
    }
    
+   public int hashCode()
+   {
+      int result = 17;
+      if (interceptorClass != null)
+      {
+         result = 37 * result + interceptorClass.hashCode();
+      }
+      if (adviceMethod != null)
+      {
+         result = 37 * result + adviceMethod.hashCode();
+      }
+      return result;
+   }
    
    public String toString()
    {

Modified: projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceSorter.java
===================================================================
--- projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceSorter.java	2009-05-07 05:56:46 UTC (rev 88327)
+++ projects/aop/branches/Branch_2_1/aop/src/main/java/org/jboss/aop/advice/PrecedenceSorter.java	2009-05-07 05:57:31 UTC (rev 88328)
@@ -22,9 +22,11 @@
 package org.jboss.aop.advice;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.LinkedHashMap;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.jboss.aop.AspectManager;
 import org.jboss.aop.util.logging.AOPLogger;
@@ -164,33 +166,15 @@
 
    public static PrecedenceDefEntry[] createOverallPrecedence(AspectManager manager)
    {
-      ArrayList<PrecedenceDefEntry> overall = new ArrayList<PrecedenceDefEntry>();
-
-      LinkedHashMap<String, PrecedenceDef> precedenceDefs = manager.getPrecedenceDefs();
-      boolean first = true;
-      for (PrecedenceDef precedenceDef : precedenceDefs.values())
-      {
-         PrecedenceDefEntry[] entries = precedenceDef.getEntries();
-
-         if (first)
-         {
-            //Populate overall with the initial precedence
-            for (int i = 0 ; i < entries.length ; i++)
-            {
-               overall.add(entries[i]);
-            }
-            first = false;
-            continue;
-         }
-
-         overall = mergePrecedenceDef(overall, precedenceDef);
-      }
-      return overall.toArray(new PrecedenceDefEntry[overall.size()]);
+      PrecedenceGraph precedenceGraph = new PrecedenceGraph(manager.getPrecedenceDefs().values());
+      return precedenceGraph.getSortedPrecedence();
    }
 
+   @Deprecated
    public static ArrayList<PrecedenceDefEntry> mergePrecedenceDef(ArrayList<PrecedenceDefEntry> overall, PrecedenceDef precedenceDef)
    {
-      //TODO This can be improved. If you have the precedences
+      // This method does not follow the improved algorithm used on PrecedenceGraph.
+      // If you have the precedences
       //		1) A, D
       //    2) C, E
       //    3) C, D
@@ -375,3 +359,144 @@
    }
 */
 }
+
+class PrecedenceGraph
+{
+   private Map<PrecedenceDefEntry, Node> nodes;
+   
+   public PrecedenceGraph(Collection<PrecedenceDef> precedenceDefs)
+   {
+      nodes = new HashMap<PrecedenceDefEntry, Node>();
+      for(PrecedenceDef precedence: precedenceDefs)
+      {
+         PrecedenceDefEntry[] entries = precedence.getEntries();
+         if (entries.length < 2)
+         {
+            continue;
+         }
+         Node node1 = createNode(entries[0]);
+         for (int i = 1; i < entries.length; i++)
+         {
+            Node node2 = createNode(entries[i]);
+            node1.addNextNode(node2);
+            node1 = node2;
+         }
+      }
+   }
+   
+   private Node createNode(PrecedenceDefEntry entry)
+   {
+      Node node = nodes.get(entry);
+      if (node == null)
+      {
+         node = new Node(entry);
+         nodes.put(entry, node);
+      }
+      return node;
+   }
+   
+   public PrecedenceDefEntry[] getSortedPrecedence()
+   {
+      PrecedenceDefEntry[] overallPrecedence = new PrecedenceDefEntry[nodes.size()];
+      int i = 0;
+      for (Node node: nodes.values())
+      {
+         // work only with the first nodes of precedence chains
+         if (node.hasPreviousNode() || node.isVisited())
+         {
+            continue;
+         }
+         i = node.addSortedPrecedence(overallPrecedence, i);
+         // TODO: add this later
+         /*if (i == overallPrecedence.length)
+         {
+            break;
+         }*/
+      }
+      return overallPrecedence;
+   }
+   
+   private static class Node
+   {
+      private PrecedenceDefEntry precedenceEntry;
+      private boolean visited;
+      
+      private Collection<Node> next;
+      private Collection<Node> previous;
+      
+      public Node(PrecedenceDefEntry precedenceEntry)
+      {
+         this.precedenceEntry = precedenceEntry;
+         this.next = new ArrayList<Node>();
+         this.previous = new ArrayList<Node>();
+      }
+      
+
+      public boolean hasPreviousNode()
+      {
+         return !this.previous.isEmpty();
+      }
+      
+      public boolean isVisited()
+      {
+         return this.visited;
+      }
+      
+      public void addNextNode(Node node)
+      {
+         if (!next.contains(node))
+         {
+            next.add(node);
+            node.previous.add(this);
+            for (Node previousNode: previous)
+            {
+               previousNode.removeEdge(node);
+            }
+         }
+      }
+      
+      public int addSortedPrecedence(PrecedenceDefEntry[] sortedPrecedence, int index)
+      {
+         this.visited = true;
+         if (!previous.isEmpty())
+         {
+            for (Node node: previous)
+            {
+               if (!node.visited)
+               {
+                  index = node.addSortedPrecedence(sortedPrecedence, index);
+               }
+            }
+         }
+         sortedPrecedence[index++] = precedenceEntry;
+         for (Node node: next)
+         {
+            if (!node.visited)
+            {
+               index = node.addSortedPrecedence(sortedPrecedence, index);
+            }
+         }
+         return index;
+      }
+      
+      private void removeEdge(Node node)
+      {
+         next.remove(node);
+         node.previous.remove(this);
+         for (Node previousNode: previous)
+         {
+            previousNode.removeEdge(node);
+         }
+      }
+      
+      public int hashCode()
+      {
+         return precedenceEntry.hashCode();
+      }
+      
+      public boolean equals(Node other)
+      {
+         return precedenceEntry.equals(other);
+      }
+   }
+}




More information about the jboss-cvs-commits mailing list