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

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Jan 12 20:01:10 EST 2008


Author: flavia.rainone at jboss.com
Date: 2008-01-12 20:01:10 -0500 (Sat, 12 Jan 2008)
New Revision: 68925

Added:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/MultiValueLeafNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SingleValueLeafNode.java
Modified:
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java
   projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java
   projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java
Log:
[JBAOP-503] Added support to multiple values per key.

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java	2008-01-12 23:05:43 UTC (rev 68924)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/InternalNode.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -74,7 +74,7 @@
       }
       else
       {
-         Node<E> newNode = new LeafNode<E>(insertionKey.toKeyPart(), value); 
+         Node<E> newNode = new SingleValueLeafNode<E>(insertionKey.toKeyPart(), value); 
          children.fillSlot(newNode);
          keyPart.newSuffix(newNode.keyPart);
       }

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java	2008-01-12 23:05:43 UTC (rev 68924)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/LeafNode.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -21,16 +21,12 @@
  */
 package org.jboss.aop.joinpoint.graph.tree;
 
-import java.util.Collection;
-
 import org.jboss.aop.joinpoint.graph.tree.insertion.InsertionKey;
-import org.jboss.aop.joinpoint.graph.tree.search.Flags;
-import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
 
 
 /**
  * Leaf node of the tree, represents a unique key in the tree and contains the
- * value identified by this key.
+ * value(s) identified by this key.
  * <p>
  * Refer to the <i>Internal Tree Structure</i> section of
  * {@link org.jboss.aop.joinpoint.graph.tree} for more information.
@@ -40,25 +36,18 @@
  * @see Node
  * @see Tree
  */
-class LeafNode<E> extends Node<E>
+abstract class LeafNode<E> extends Node<E>
 {
    /**
-    * The value contained in this leaf.
-    */
-   private E value;
-   
-   /**
     * Constructor. Creates a node representing a unique key in the tree, and
-    * containing the value identified by this key.
+    * containing the value(s) identified by this key.
     * 
     * @param keyPart the part of the key that is uncommon to the other keys
     *                in the tree.
-    * @param value   the value identified by the key.
     */
-   public LeafNode(KeyPart keyPart, E value)
+   protected LeafNode(KeyPart keyPart)
    {
       super(keyPart);
-      this.value = value;
    }
 
    /**
@@ -71,7 +60,7 @@
       if (insertionKey.getNextChar() != InsertionKey.INSERTION_COMPLETE)
       {
          // creates a new leaf for the insertion key
-         Node<E> leafNode = new LeafNode<E>(insertionKey.toKeyPart(), value);
+         Node<E> leafNode = new SingleValueLeafNode<E>(insertionKey.toKeyPart(), value);
          // this leaf will contain only an empty key end
          KeyPart fatherKeyPart = this.keyPart;
          this.keyPart = KeyPart.EMPTY_KEY_END; // TODO this may generate more than one EMPTY KEY PART in a row... is this a problem?
@@ -80,32 +69,15 @@
          return newNode;
       }
       // if this leaf  represents a key equal to the key to be inserted...
-      // just redefine value
-      this.value = value;
-      return this;
+      // just add the value
+      return insertValue(value);
    }
 
-   public E searchValue(SearchKey searchKey)
-   {
-      char nextChar = searchKey.matches(super.keyPart);
-      if (nextChar == Flags.POSITIVE)
-      {
-         return value;
-      }
-      return null;
-   }
-   
-   public void search(Collection<E> result, SearchKey searchKey)
-   {
-      char nextChar = searchKey.matches(super.keyPart);
-      if (nextChar == Flags.POSITIVE)
-      {
-         result.add(value);
-      }
-   }
-   
-   public String toString()
-   {
-      return "(" + this.keyPart + ", " + this.value + ")";
-   }
+   /**
+    * Adds a new value to this leaf.
+    * 
+    * @param value the new value to be inserted in this leaf
+    * @return      the new leaf node after insertion
+    */
+   protected abstract LeafNode<E> insertValue(E value);
 }
\ No newline at end of file

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/MultiValueLeafNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/MultiValueLeafNode.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/MultiValueLeafNode.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -0,0 +1,95 @@
+/*
+ * 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.tree;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+/**
+ * A leaf node that contains two or more values.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class MultiValueLeafNode<E> extends LeafNode<E>
+{
+   /**
+    * The value contained in this leaf.
+    */
+   private List<E> values;
+   
+   /**
+    * Constructor. Creates a node representing a unique key in the tree, and
+    * containing two values identified by this key.
+    * 
+    * @param keyPart the part of the key that is uncommon to the other keys
+    *                in the tree
+    * @param value1  one of the values identified by the key
+    * @param value2  one of the values identified by the key
+    */
+   MultiValueLeafNode(KeyPart keyPart, E value1, E value2)
+   {
+      super(keyPart);
+      this.values = new ArrayList<E>(2);
+      this.values.add(value1);
+      this.values.add(value2);
+   }
+   
+   protected LeafNode<E> insertValue(E value)
+   {
+      this.values.add(value);
+      return this;
+   }
+   
+   public E searchValue(SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      if (nextChar == Flags.POSITIVE)
+      {
+         throw new RuntimeException();
+      }
+      return null;
+   }
+   
+   public void search(Collection<E> result, SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      if (nextChar == Flags.POSITIVE)
+      {
+         result.addAll(this.values);
+      }
+   }
+   
+   public String toString()
+   {
+      String result = "(" + this.keyPart + ", [" + values.get(0);
+      for (int i = 1; i < values.size(); i++)
+      {
+         result +=", " + values.get(i);
+      }
+      result +="])";
+      return result;
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java	2008-01-12 23:05:43 UTC (rev 68924)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Node.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -99,7 +99,7 @@
          return internalInsert(insertionKey, value);
       }
       // otherwise, create a leaf with the insertion key unmatched part
-      Node<E> leafNode = new LeafNode<E>(insertionKey.toKeyPart(), value);
+      Node<E> leafNode = new SingleValueLeafNode<E>(insertionKey.toKeyPart(), value);
       // and create a new internal node, containing the common prefix as
       // its data, and this node and the created node as contents
       Node<E> newNode = new InternalNode<E>(commonKeyPart, this, leafNode);

Added: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SingleValueLeafNode.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SingleValueLeafNode.java	                        (rev 0)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/SingleValueLeafNode.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -0,0 +1,83 @@
+/*
+ * 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.tree;
+
+import java.util.Collection;
+
+import org.jboss.aop.joinpoint.graph.tree.search.Flags;
+import org.jboss.aop.joinpoint.graph.tree.search.SearchKey;
+
+/**
+ * A leaf node that contains a single value.
+ * 
+ * @author  <a href="flavia.rainone at jboss.com">Flavia Rainone</a>
+ */
+class SingleValueLeafNode<E> extends LeafNode<E>
+{
+   /**
+    * The value contained in this leaf.
+    */
+   private E value;
+   
+   /**
+    * Constructor. Creates a node representing a unique key in the tree, and
+    * containing the value identified by this key.
+    * 
+    * @param keyPart the part of the key that is uncommon to the other keys
+    *                in the tree.
+    * @param value   the value identified by the key.
+    */
+   SingleValueLeafNode(KeyPart keyPart, E value)
+   {
+      super(keyPart);
+      this.value = value;
+   }
+   
+   protected LeafNode<E> insertValue(E value)
+   {
+      return new MultiValueLeafNode(this.keyPart, this.value, value);
+   }
+   
+   public E searchValue(SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      if (nextChar == Flags.POSITIVE)
+      {
+         return value;
+      }
+      return null;
+   }
+   
+   public void search(Collection<E> result, SearchKey searchKey)
+   {
+      char nextChar = searchKey.matches(super.keyPart);
+      if (nextChar == Flags.POSITIVE)
+      {
+         result.add(value);
+      }
+   }
+   
+   public String toString()
+   {
+      return "(" + this.keyPart + ", " + this.value + ")";
+   }
+}
\ No newline at end of file

Modified: projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java	2008-01-12 23:05:43 UTC (rev 68924)
+++ projects/aop/branches/joinpoint_graph/aop/src/main/org/jboss/aop/joinpoint/graph/tree/Tree.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -169,7 +169,7 @@
    {
       public <E> void insert(InsertionKey insertionKey, E value)
       {
-         root = new LeafNode<E>(insertionKey.toKeyPart(), value);
+         root = new SingleValueLeafNode<E>(insertionKey.toKeyPart(), value);
          state = new NotEmptyState();
          
       }

Modified: projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java
===================================================================
--- projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java	2008-01-12 23:05:43 UTC (rev 68924)
+++ projects/aop/branches/joinpoint_graph/aop/src/test/org/jboss/aop/joinpoint/graph/tree/TreeInsertionTest.java	2008-01-13 01:01:10 UTC (rev 68925)
@@ -22,14 +22,8 @@
 package org.jboss.aop.joinpoint.graph.tree;
 
 import java.lang.reflect.Field;
+import java.util.List;
 
-import org.jboss.aop.joinpoint.graph.tree.InternalNode;
-import org.jboss.aop.joinpoint.graph.tree.KeyPart;
-import org.jboss.aop.joinpoint.graph.tree.LeafNode;
-import org.jboss.aop.joinpoint.graph.tree.Node;
-import org.jboss.aop.joinpoint.graph.tree.SlotCollection;
-import org.jboss.aop.joinpoint.graph.tree.Tree;
-
 import junit.framework.TestCase;
 
 /**
@@ -43,6 +37,7 @@
    private Field treeStateField;
    private Field rootField;
    private Field valueField;
+   private Field valuesField;
    private Field childrenField;
    
    public void setUp() throws Exception
@@ -51,8 +46,10 @@
       treeStateField.setAccessible(true);
       rootField = Tree.class.getDeclaredField("root");
       rootField.setAccessible(true);
-      valueField = LeafNode.class.getDeclaredField("value");
+      valueField = SingleValueLeafNode.class.getDeclaredField("value");
       valueField.setAccessible(true);
+      valuesField = MultiValueLeafNode.class.getDeclaredField("values");
+      valuesField.setAccessible(true);
       childrenField = InternalNode.class.getDeclaredField("children");
       childrenField.setAccessible(true);
       this.tree = new Tree<String>();
@@ -75,6 +72,40 @@
             "different"};
       assertChildLeafNode(root, 'o', secondKeyElements, "OTHER");
    }
+   
+   public void testSameKey1() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      tree.insert("the.key", "THE");
+      assertTreeState(Tree.NotEmptyState.class);
+      String[] firstKeyElements = new String[] {"the", "key"};
+      assertRootLeafNode('t', firstKeyElements, "THE");
+      
+      tree.insert("the.key", "OTHER");
+      assertRootLeafNode('t', firstKeyElements, new String[]{"THE", "OTHER"});
+   }
+   
+   public void testSameKey2() throws Exception
+   {
+      assertTreeState(Tree.EmptyState.class);
+      tree.insert("the.key", "THE");
+      assertTreeState(Tree.NotEmptyState.class);
+      String[] firstKeyElements = new String[] {"the", "key"};
+      assertRootLeafNode('t', firstKeyElements, "THE");
+      
+      tree.insert("the.other.key", "OTHER");
+      Node root = getRoot();
+      assertInternalNode(root, 't', new String[]{"the"}, 2, 3);
+      assertChildLeafNode(root, 'k', new String[]{"key"}, "THE");
+      assertChildLeafNode(root, 'o', new String[]{"other", "key"}, "OTHER");
+      
+      tree.insert("the.other.key", "OTHER");
+      root = getRoot();
+      assertInternalNode(root, 't', new String[]{"the"}, 2, 3);
+      assertChildLeafNode(root, 'k', new String[]{"key"}, "THE");
+      assertChildLeafNode(root, 'o', new String[]{"other", "key"},
+            new String[]{"OTHER", "OTHER"});
+   }
 
    public void testElementLengthRanges() throws Exception
    {
@@ -3437,6 +3468,21 @@
    {
       this.assertLeafNode(getRoot(), first, elements, value);
    }
+   
+   /**
+    * Retrieves the root child node identified by <code>first</code>, and
+    * asserts this child node as a leaf and its data.
+    * 
+    * @param first     the expected first character of the child node key part
+    * @param elements  the expected elements contained in the child node key
+    *                  part
+    * @param values    the expected values contained in the child node
+    */
+   private void assertRootLeafNode(char first, String[] elements,
+         Object[] values) throws Exception
+   {
+      this.assertLeafNode(getRoot(), first, elements, values);
+   }
 
    /**
     * Retrieves the child node of <code>superNode</code>, identified by <code>
@@ -3455,8 +3501,24 @@
    }
    
    /**
-    * Asserts the leaf node <code>node</code> data.
+    * Retrieves the child node of <code>superNode</code>, identified by <code>
+    * first</code>, and asserts this child node as a leaf and its data.
     * 
+    * @param superNode the node whose child is the leaf node to be asserted
+    * @param first     the expected first character of the child node key part
+    * @param elements  the expected elements contained in the child node key
+    *                  part
+    * @param values    the expected value contained in the child node
+    */
+   private void assertChildLeafNode(Node superNode, char first,
+         String[] elements, Object[] values) throws Exception
+   {
+      assertLeafNode(getChildNode(superNode, first), first, elements, values);
+   }
+   
+   /**
+    * Asserts the single value leaf node <code>node</code> data.
+    * 
     * @param node     the leaf node whose data will be asserted
     * @param first    the expected first character of the <code>node</code> key
     *                 part
@@ -3473,6 +3535,29 @@
    }
    
    /**
+    * Asserts the multi value leaf node <code>node</code> data.
+    * 
+    * @param node     the leaf node whose data will be asserted
+    * @param first    the expected first character of the <code>node</code> key
+    *                 part
+    * @param elements the expected elements contained in the <code>node</code>
+    *                 key part
+    * @param values   the expected values contained in <code>node</code>
+    */
+   private void assertLeafNode(Node node, char first, String[] elements,
+         Object[] values) throws Exception
+   {
+      assertTrue("Node isn't a leaf", node instanceof LeafNode);
+      Util.assertKeyPart(node.keyPart, first, elements);
+      List<Object> leafValues = (List<Object>) valuesField.get(node);
+      assertEquals(values.length, leafValues.size());
+      for (int i = 0; i < values.length; i++)
+      {
+         assertSame(values[i], leafValues.get(i));
+      }
+   }
+   
+   /**
     * Asserts the internal node <code>node</code> data.
     * 
     * @param node               the internal node whose data will be asserted   




More information about the jboss-cvs-commits mailing list