diff --git a/pom.xml b/pom.xml
index 895acf7..c8d6880 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,105 +1,184 @@
- 4.0.0
-
-
- org.sonatype.oss
- oss-parent
- 9
-
-
- org.kametic
- universalvisitor
- 1.0
- jar
-
- Universal Visitor
-
- http://kametic.org/universalvisitor
-
-
- Universal Visitor is tiny but powerful library allowing to easily "visit"
- an object graph and extracting information with a simple Map/Reduce API.
-
-
- 2014
-
-
-
- LGPL 3.0
- http://www.gnu.org/copyleft/lesser.html
-
-
-
-
-
- Epo Jemba
- epo.jemba@kametic.com
- Kametic
- www.kametic.com
-
- Developer
- Owner
-
-
-
- Pierre Thirouin
- pierre.thirouin@gmail.com
-
- Developer
-
-
-
-
-
- UTF-8
- 1.6
- 1.6
-
-
-
-
- junit
- junit
- 4.10
- test
-
-
- org.assertj
- assertj-core
- 1.6.1
- test
-
-
-
-
-
- ${basedir}/src/main/resources
- true
-
-
- ${basedir}
- META-INF
-
- LICENSE
- NOTICE
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
-
-
-
-
-
-
- https://github.com/kametic/universalvisitor
- scm:git:git://github.com/kametic/universalvisitor.git
- scm:git:git@github.com:kametic/universalvisitor.git
- HEAD
-
+ 4.0.0
+
+ org.kametic
+ universalvisitor
+ 1.0.2-SNAPSHOT
+ jar
+
+ Universal Visitor
+
+ http://kametic.org/universalvisitor
+
+
+ Universal Visitor is tiny but powerful library allowing to easily "visit"
+ an object graph and extracting information with a simple Map/Reduce API.
+
+
+ 2014
+
+
+
+ LGPL 3.0
+ http://www.gnu.org/copyleft/lesser.html
+
+
+
+
+
+ Epo Jemba
+ epo.jemba@kametic.com
+ Kametic
+ www.kametic.com
+
+ Developer
+ Owner
+
+
+
+ Pierre Thirouin
+ pierre.thirouin@gmail.com
+
+ Developer
+
+
+
+
+
+ UTF-8
+ 1.6
+ 1.6
+
+ 1.6.5
+ 1.6
+ 2.10.3
+ 2.2.1
+ 2.5.2
+
+
+
+
+ junit
+ junit
+ 4.10
+ test
+
+
+ org.assertj
+ assertj-core
+ 1.6.1
+ test
+
+
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+
+
+ ${basedir}/src/main/resources
+ true
+
+
+ ${basedir}
+ META-INF
+
+ LICENSE
+ NOTICE
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ ${maven-release-plugin.version}
+
+ true
+ false
+ release
+ deploy
+
+
+
+
+
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ ${maven-source-plugin.version}
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ ${maven-javadoc-plugin.version}
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ ${maven-gpg-plugin.version}
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ ${nexus-staging-maven-plugin.version}
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+
+
+
+
+
+
+ https://github.com/kametic/universalvisitor
+ scm:git:git://github.com/kametic/universalvisitor.git
+ scm:git:git@github.com:kametic/universalvisitor.git
+ HEAD
+
diff --git a/src/main/java/org/kametic/universalvisitor/UniversalVisitor.java b/src/main/java/org/kametic/universalvisitor/UniversalVisitor.java
index 43876a1..8d375e4 100644
--- a/src/main/java/org/kametic/universalvisitor/UniversalVisitor.java
+++ b/src/main/java/org/kametic/universalvisitor/UniversalVisitor.java
@@ -16,47 +16,30 @@
*/
package org.kametic.universalvisitor;
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.Set;
-
-import org.kametic.universalvisitor.api.Filter;
-import org.kametic.universalvisitor.api.Job;
-import org.kametic.universalvisitor.api.MapReduce;
-import org.kametic.universalvisitor.api.Mapper;
-import org.kametic.universalvisitor.api.Metadata;
-import org.kametic.universalvisitor.api.Node;
-import org.kametic.universalvisitor.api.Reducer;
+import org.kametic.universalvisitor.api.*;
import org.kametic.universalvisitor.core.JobDefault;
import org.kametic.universalvisitor.core.MapReduceDefault;
import org.kametic.universalvisitor.core.NodeDefault;
+import java.lang.reflect.*;
+import java.util.*;
+
/**
* UniversalVisitor is the main entrypoint. With it you can visit any object graph instance.
*
* It will first visit the object graph then produces a linked list of {@link Node}.
+ *
*
- * The Map Reduce pattern will then be applied from this linked list. Users can create their Map Reduce jobs by using the API provided.
+ * The Map Reduce pattern will then be applied from this linked list. Users can create their Map Reduce jobs by using the API provided.
+ *
*
- * {@link Mapper} : a mapper from the Map Reduce design pattern
- * {@link Reducer} : a reducer from the Map Reduce design pattern
- * {@link Job} : a coherent set of one {@link Mapper} and one or more {@link Reducer}s
- * {@link MapReduce} : a coherent set of one {@link Mapper} and one or more {@link Reducer}s
- * {@link Job} : a set of {@link MapReduce}
+ * {@link Mapper} : a mapper from the Map Reduce design pattern
+ * {@link Reducer} : a reducer from the Map Reduce design pattern
+ * {@link Job} : a coherent set of one {@link Mapper} and one or more {@link Reducer}s
+ * {@link MapReduce} : a coherent set of one {@link Mapper} and one or more {@link Reducer}s
+ * {@link Job} : a set of {@link MapReduce}
*
- *
- *
+ *
* @author Epo Jemba
* @author Pierre Thirouin
*/
@@ -120,34 +103,31 @@ public void visit(Object o, Filter filter, MapReduce... mapReduces)
visit(o, filter, new JobDefault(mapReduces));
}
- @SuppressWarnings({
- "rawtypes"
- })
- public void visit(AnnotatedElement ae, Filter filter, Job job)
- {
+ @SuppressWarnings({ "rawtypes" })
+ public void visit(AnnotatedElement ae, Filter filter, Job job){
Set cache = new HashSet();
- ChainedNode node = ChainedNode.createRoot();
+ //ChainedNode Changed to linkedList (perf issues when accessing last element fix)
+ Queue nodes = new LinkedList();
if (filter == null)
{
filter = Filter.TRUE;
}
-
- recursiveVisit(ae, cache, node, filter);
- doMapReduce(job, node);
+ //The currentLevel is set at "-1" before the recursive instead of creating a dummy Node
+ recursiveVisit(ae, cache, nodes, filter, -1);
+ doMapReduce(job, nodes);
}
/**
- * @param job
- * @param node
- * @return
+ * @param job the job
+ * @param nodes the nodes
*/
@SuppressWarnings({
"unchecked", "rawtypes"
})
- private void doMapReduce(Job> job, ChainedNode node)
- {
- for (node = node.next; node != null; node = node.next)
- {
+ private void doMapReduce(Job> job, Queue nodes)
+ {
+ for (LocalNode node : nodes)
+ {
for (MapReduce mapReduce : job.mapReduces())
{
if (mapReduce.getMapper().handle(node.annotatedElement()))
@@ -170,69 +150,37 @@ public void visit(Object o, Filter filter, Job job)
{
Set cache = new HashSet();
-
- ChainedNode node = ChainedNode.createRoot();
+ //Changed to linkedList of LocalNode instead of the ChainedNode (perf issues fix)
+ Queue nodes = new LinkedList();
if (filter == null)
{
filter = Filter.TRUE;
}
- recursiveVisit(o, cache, node, filter);
+ recursiveVisit(o, cache, nodes, filter, -1);
- doMapReduce(job, node);
+ doMapReduce(job, nodes);
}
- private static class ChainedNode extends NodeDefault
- {
- ChainedNode next;
+ //ChainedNode changed to localNode due to performance issues
+ private static class LocalNode extends NodeDefault
+ {
- protected ChainedNode(Object instance, AnnotatedElement annotatedElement, int level, ChainedNode next)
- {
+ protected LocalNode(Object instance, AnnotatedElement annotatedElement, int level)
+ {
super(instance, annotatedElement, level);
- this.next = next;
}
- private void next(ChainedNode node)
- {
- if (next != null)
- {
- throw new IllegalStateException("next pair can not be set twice.");
- }
- next = node;
- }
- public static ChainedNode createRoot()
- {
- return new ChainedNode(new Object(), null, -1, null);
- }
-
- public ChainedNode append(Object o, AnnotatedElement ao, int level, Metadata metadata)
- {
-
- next(new ChainedNode(o, ao, level, null).metadata(metadata));
-
- return next;
- }
@Override
- public ChainedNode metadata(Metadata metadata)
+ public LocalNode metadata(Metadata metadata)
{
- return (ChainedNode) super.metadata(metadata);
+ return (LocalNode) super.metadata(metadata);
}
- public ChainedNode last()
- {
- if (next != null)
- {
- return next.last();
- }
- else
- {
- return this;
- }
- }
@Override
public String toString()
@@ -243,13 +191,12 @@ public String toString()
indentation += "\t";
} // instance()=
String rep = String.format(
- "%sChainedNode [ %s@%s , level=%s , annotatedElement=%s] \n%s",
+ "%sLocalNode [ %s@%s , level=%s , annotatedElement=%s] \n",
indentation,
instance().getClass().getSimpleName(),
Integer.toHexString(instance().hashCode()),
level(),
- annotatedElement(),
- next);
+ annotatedElement());
return rep;
// return "ChainedNode [instance()=" + instance() + ", level()="
@@ -302,11 +249,9 @@ public String toString()
// }
// }
- private void recursiveVisit(Object object, Set cache, ChainedNode node, Filter filter)
+ private void recursiveVisit(Object object, Set cache, Queue nodes, Filter filter, int currentLevel)
{
-
- int currentLevel = node.level() + 1;
-
+ currentLevel ++;
if (!cache.contains(object))
{
@@ -318,26 +263,26 @@ private void recursiveVisit(Object object, Set cache, ChainedNode node,
}
else if (Collection.class.isAssignableFrom(object.getClass()))
{
- visitAllCollection((Collection>) object, cache, node, currentLevel, filter);
+ visitAllCollection((Collection>) object, cache, nodes, currentLevel, filter);
}
else if (object.getClass().isArray())
{
- visitAllArray(object, cache, node, currentLevel, filter);
+ visitAllArray(object, cache, nodes, currentLevel, filter);
}
else if (Map.class.isAssignableFrom(object.getClass()))
{
- visitAllMap((Map, ?>) object, cache, node, currentLevel, filter);
+ visitAllMap((Map, ?>) object, cache, nodes, currentLevel, filter);
}
else
{
- visitObject(object, cache, node, currentLevel, filter);
+ visitObject(object, cache, nodes, currentLevel, filter);
}
}
}
- private void visitObject(Object object, Set cache, ChainedNode node, int currentLevel, Filter filter)
+ private void visitObject(Object object, Set cache, Queue nodes, int currentLevel, Filter filter)
{
- visitObject(object, cache, node, currentLevel, filter, null);
+ visitObject(object, cache, nodes, currentLevel, filter, null);
}
// private void visitConstructor(Constructor ae, Set cache, ChainedNode node, int
@@ -395,15 +340,14 @@ private void visitObject(Object object, Set cache, ChainedNode node, int
// }
// }
- private void visitObject(Object object, Set cache, ChainedNode node, int currentLevel, Filter filter, Metadata metadata)
- {
+ private void visitObject(Object object, Set cache, Queue nodes, int currentLevel, Filter filter, Metadata metadata)
+ {
Class extends Object> currentClass = object.getClass();
if (!isJdkMember(currentClass))
{
- ChainedNode current = node;
Class>[] family = getAllInterfacesAndClasses(currentClass);
for (Class> elementClass : family)
{ // We iterate over all the family tree of the current class
@@ -415,7 +359,7 @@ private void visitObject(Object object, Set cache, ChainedNode node, int
{
if (!isJdkMember(c) && !c.isSynthetic())
{
- current = current.append(object, c, currentLevel, metadata);
+ nodes.add(new LocalNode(object, c, currentLevel).metadata(metadata));
}
}
//
@@ -423,7 +367,7 @@ private void visitObject(Object object, Set cache, ChainedNode node, int
{
if (!isJdkMember(m) && !m.isSynthetic())
{
- current = current.append(object, m, currentLevel, metadata);
+ nodes.add(new LocalNode(object, m, currentLevel).metadata(metadata));
}
}
@@ -431,15 +375,14 @@ private void visitObject(Object object, Set cache, ChainedNode node, int
{
if (!isJdkMember(f) && !f.isSynthetic())
{
+ nodes.add(new LocalNode(object, f, currentLevel).metadata(metadata));
- current = current.append(object, f, currentLevel, metadata);
if (filter != null && filter.retains(f))
{
Object deeperObject = readField(f, object);
- recursiveVisit(deeperObject, cache, current, filter);
- current = current.last();
+ recursiveVisit(deeperObject, cache, nodes, filter, currentLevel);
}
}
}
@@ -449,9 +392,8 @@ private void visitObject(Object object, Set cache, ChainedNode node, int
}
}
- private void visitAllCollection(Collection> collection, Set cache, ChainedNode node, int currentLevel, Filter filter)
- {
- ChainedNode current = node;
+ private void visitAllCollection(Collection> collection, Set cache, Queue nodes, int currentLevel, Filter filter)
+ {
boolean indexable = collection instanceof List || collection instanceof Queue;
@@ -463,45 +405,38 @@ private void visitAllCollection(Collection> collection, Set cache, Cha
{
if (indexable)
{
- visitObject(value, cache, current, currentLevel, filter, new Metadata(i));
+ visitObject(value, cache, nodes, currentLevel, filter, new Metadata(i));
}
else
{
- visitObject(value, cache, current, currentLevel, filter);
+ visitObject(value, cache, nodes, currentLevel, filter);
}
- current = current.last();
}
}
}
- private void visitAllArray(Object arrayObject, Set cache, ChainedNode node, int currentLevel, Filter filter)
+ private void visitAllArray(Object arrayObject, Set cache, Queue nodes, int currentLevel, Filter filter)
{
- ChainedNode current = node;
-
int l = Array.getLength(arrayObject);
for (int i = 0; i < l; i++)
{
Object value = Array.get(arrayObject, i);
if (value != null)
{
- visitObject(value, cache, current, currentLevel, filter, new Metadata(i));
- current = current.last();
+ visitObject(value, cache, nodes, currentLevel, filter, new Metadata(i));
}
}
}
- private void visitAllMap(Map, ?> values, Set cache, ChainedNode pair, int currentLevel, Filter filter)
+ private void visitAllMap(Map, ?> values, Set cache, Queue nodes, int currentLevel, Filter filter)
{
- ChainedNode current = pair;
for (Object thisKey : values.keySet())
{
Object value = values.get(thisKey);
if (value != null)
{
- visitObject(thisKey, cache, current, currentLevel, filter);
- current = current.last();
- visitObject(value, cache, current, currentLevel, filter, new Metadata(thisKey));
- current = current.last();
+ visitObject(thisKey, cache, nodes, currentLevel, filter);
+ visitObject(value, cache, nodes, currentLevel, filter, new Metadata(thisKey));
}
}
}
@@ -539,8 +474,7 @@ private Object readField(Field f, Object instance)
/**
* Returns all the interfaces and classes implemented or extended by a class.
*
- * @param clazz
- * The class to search from.
+ * @param clazz The class to search from.
* @return The array of classes and interfaces found.
*/
private Class>[] getAllInterfacesAndClasses(Class> clazz)
@@ -554,8 +488,7 @@ private Class>[] getAllInterfacesAndClasses(Class> clazz)
* This method walks up the inheritance hierarchy to make sure we get every class/interface extended or
* implemented by classes.
*
- * @param classes
- * The classes array used as search starting point.
+ * @param classes The classes array used as search starting point.
* @return the found classes and interfaces.
*/
@SuppressWarnings("unchecked")
diff --git a/src/main/java/org/kametic/universalvisitor/api/MapReduce.java b/src/main/java/org/kametic/universalvisitor/api/MapReduce.java
index c032732..9578a7c 100644
--- a/src/main/java/org/kametic/universalvisitor/api/MapReduce.java
+++ b/src/main/java/org/kametic/universalvisitor/api/MapReduce.java
@@ -19,16 +19,17 @@
/**
* A MapReduce of T represents :
*
- * one Mapper of <T>
- * one ore more Reducer of <T,?>
+ * one Mapper of <T>
+ * one ore more Reducer of <T,?>
*
* It has a method aggregate() whose purpose is to aggregate all the reduction into one Aggregation.
*
* MapReduceDefault is the implementation we supply.
- *
+ *
+ *
* @author epo.jemba
*
- * @param
+ * @param the object type to map/reduce
*/
public interface MapReduce
{
diff --git a/src/main/java/org/kametic/universalvisitor/api/Mapper.java b/src/main/java/org/kametic/universalvisitor/api/Mapper.java
index 93ec7d1..b70818e 100644
--- a/src/main/java/org/kametic/universalvisitor/api/Mapper.java
+++ b/src/main/java/org/kametic/universalvisitor/api/Mapper.java
@@ -22,7 +22,8 @@
* A Mapper will "map" all the AnnotatedElement of the visited object graph, it will allows.
*
* All results of the map(Node) method will be then given to one or more Reducers.
- *
+ *
+ *
* @author Epo Jemba
* @author Pierre Thirouin
*/
@@ -40,7 +41,7 @@ public interface Mapper
/**
* The implementation of the actual mapping given the node in parameter.
*
- * @param node
+ * @param node the node
* @return the actual result of the Map.
*/
O map(Node node);
diff --git a/src/main/java/org/kametic/universalvisitor/api/Metadata.java b/src/main/java/org/kametic/universalvisitor/api/Metadata.java
index 9fb74dd..d2deada 100644
--- a/src/main/java/org/kametic/universalvisitor/api/Metadata.java
+++ b/src/main/java/org/kametic/universalvisitor/api/Metadata.java
@@ -20,8 +20,8 @@
*
* Metadata is the object held by the Node that keeps metadata like
*
- * if needed the index, if the element is inside an array or alist.
- * if needed the key, if the element is inside a Map.
+ * if needed the index, if the element is inside an array or alist.
+ * if needed the key, if the element is inside a Map.
*
*
* @author epo.jemba@kametic.com
@@ -43,7 +43,7 @@ public Metadata()
/**
* Constructor with a key as parameter.
*
- * @param key
+ * @param key the key
*/
public Metadata(Object key)
{
@@ -53,7 +53,7 @@ public Metadata(Object key)
/**
* Constructor with an index as parameter.
*
- * @param index
+ * @param index the index
*/
public Metadata(int index)
{
diff --git a/src/main/java/org/kametic/universalvisitor/api/Node.java b/src/main/java/org/kametic/universalvisitor/api/Node.java
index 922d6ae..f2fcb56 100644
--- a/src/main/java/org/kametic/universalvisitor/api/Node.java
+++ b/src/main/java/org/kametic/universalvisitor/api/Node.java
@@ -19,15 +19,15 @@
import java.lang.reflect.AnnotatedElement;
/**
- *
* A node is the element type of the internal linked list created during the visit of the object graph.
*
- * It has :
+ * It has:
+ *
*
- * the visited annotated element : Field, Method, Constructor, Class or Package.
- * the Metadata associated with the node.
- * the level inside the graph visited it starts with 0.
- * the instance of the visited annotated element.
+ * the visited annotated element : Field, Method, Constructor, Class or Package.
+ * the Metadata associated with the node.
+ * the level inside the graph visited it starts with 0.
+ * the instance of the visited annotated element.
*
*
* @author epo.jemba@kametic.com
diff --git a/src/test/java/org/nuunframework/universalvisitor/UniversalVisitorTest.java b/src/test/java/org/nuunframework/universalvisitor/UniversalVisitorTest.java
index 2fcad99..f53f6c0 100644
--- a/src/test/java/org/nuunframework/universalvisitor/UniversalVisitorTest.java
+++ b/src/test/java/org/nuunframework/universalvisitor/UniversalVisitorTest.java
@@ -1,32 +1,12 @@
package org.nuunframework.universalvisitor;
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
import org.junit.Before;
import org.junit.Test;
import org.kametic.universalvisitor.UniversalVisitor;
-import org.kametic.universalvisitor.api.Filter;
-import org.kametic.universalvisitor.api.MapReduce;
-import org.kametic.universalvisitor.api.Mapper;
-import org.kametic.universalvisitor.api.Metadata;
-import org.kametic.universalvisitor.api.Node;
-import org.kametic.universalvisitor.api.Reducer;
+import org.kametic.universalvisitor.api.*;
import org.kametic.universalvisitor.core.MapReduceDefault;
import org.nuunframework.universalvisitor.sample.Alphabet;
-import org.nuunframework.universalvisitor.sample.collections.H;
-import org.nuunframework.universalvisitor.sample.collections.I;
-import org.nuunframework.universalvisitor.sample.collections.J;
-import org.nuunframework.universalvisitor.sample.collections.K;
-import org.nuunframework.universalvisitor.sample.collections.L;
+import org.nuunframework.universalvisitor.sample.collections.*;
import org.nuunframework.universalvisitor.sample.issues.Issue1;
import org.nuunframework.universalvisitor.sample.issues.Issue2;
import org.nuunframework.universalvisitor.sample.levels.L1;
@@ -40,6 +20,17 @@
import org.nuunframework.universalvisitor.sample.simple.B;
import org.nuunframework.universalvisitor.sample.simple.C;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
/**
*
*
@@ -48,21 +39,13 @@ public class UniversalVisitorTest
{
UniversalVisitor underTest;
-
A a;
-
D d;
-
H h;
-
M m;
-
N n;
-
Issue1 issue1;
-
Issue2 issue2;
-
L1 l1;
@SuppressWarnings("serial")
@@ -251,7 +234,6 @@ public void issue1()
public void issue2()
{
CountMapper nopMap = new CountMapper();
- // System.out.println("============================== ISSUE2 ===================================");
underTest.visit(issue2, nopMap);
assertThat(nopMap.methods).contains(
@@ -266,7 +248,6 @@ public void issue2()
"parentProtected",
"parentPackage",
"parentPublic");
- // System.out.println(nopMap.methods);
assertThat(nopMap.fields).contains(
"interface1F",
"interface2F",
@@ -279,8 +260,6 @@ public void issue2()
"parentProtected",
"parentPackage",
"parentPublic");
- // System.out.println(nopMap.fields);
- System.out.println(nopMap.node);
}
@Test
@@ -290,6 +269,37 @@ public void checkLevel()
underTest.visit(l1, mapper);
}
+
+ @Test
+ public void performance_test() {
+ P p = new P();
+ p.k = new K();
+ p.j = new J();
+ p.os = new ArrayList();
+ for (int i = 0; i < 10000; i++) {
+ O o = new O();
+ o.k = new K();
+ o.j = new J();
+ o.p = new P();
+ o.p.j = new J();
+ o.p.os = new ArrayList() {
+ {
+ add(new O());
+ add(new O());
+ }
+ };
+ p.os.add(o);
+ }
+
+ MyPredicate predicate = new MyPredicate();
+ MyMapper mapper = new MyMapper();
+ SumReducer reducer = new SumReducer();
+
+ underTest.visit(p, predicate, mapper, reducer);
+
+ assertThat(mapper.getMaxLevel()).isEqualTo(3);
+ }
+
class CheckLevelMap implements Mapper
{
@@ -324,13 +334,10 @@ public Void map(Node node)
{
metadata = new Metadata();
}
- System.out.println(indentation + "|" + node.level() + "|" + " " + f.getName() + metadata + value + " from "
- + f.getDeclaringClass().getSimpleName());
}
if (node.annotatedElement() instanceof Constructor)
{
Constructor> c = (Constructor>) node.annotatedElement();
- System.out.println(indentation + "|" + node.level() + "|" + node.metadata() + " " + c.getDeclaringClass().getSimpleName() + "()");
}
return null;
@@ -349,7 +356,6 @@ public boolean handle(AnnotatedElement object)
@Override
public Void map(Node node)
{
- System.out.println("Current Node : " + node.annotatedElement());
return null;
}
@@ -414,7 +420,6 @@ public Void map(Node node)
try
{
value = (Integer) f.get(node.instance());
- System.out.println("value " + value);
f.set(node.instance(), value * 10);
}
catch (IllegalArgumentException e)
@@ -473,7 +478,6 @@ static class MyMapper implements Mapper
@Override
public Integer map(Node node)
{
- System.out.println("node " + node.annotatedElement() + " -> " + node.instance() + " type = " + node.instance().getClass());
counter++;
maxLevel = Math.max(maxLevel, node.level());
diff --git a/src/test/java/org/nuunframework/universalvisitor/sample/collections/O.java b/src/test/java/org/nuunframework/universalvisitor/sample/collections/O.java
new file mode 100644
index 0000000..5ff25e7
--- /dev/null
+++ b/src/test/java/org/nuunframework/universalvisitor/sample/collections/O.java
@@ -0,0 +1,11 @@
+package org.nuunframework.universalvisitor.sample.collections;
+
+import org.nuunframework.universalvisitor.sample.Alphabet;
+
+@Alphabet
+public class O {
+
+ public K k;
+ public J j;
+ public P p;
+}
diff --git a/src/test/java/org/nuunframework/universalvisitor/sample/collections/P.java b/src/test/java/org/nuunframework/universalvisitor/sample/collections/P.java
new file mode 100644
index 0000000..d708d65
--- /dev/null
+++ b/src/test/java/org/nuunframework/universalvisitor/sample/collections/P.java
@@ -0,0 +1,12 @@
+package org.nuunframework.universalvisitor.sample.collections;
+
+import java.util.Collection;
+
+import org.nuunframework.universalvisitor.sample.Alphabet;
+
+@Alphabet
+public class P {
+ public Collection os;
+ public K k;
+ public J j;
+}