geronimo-xbean-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r630652 - in /geronimo/xbean/trunk/xbean-reflect/src: main/java/org/apache/xbean/recipe/ test/java/org/apache/xbean/recipe/
Date Sun, 24 Feb 2008 18:26:14 GMT
Author: dain
Date: Sun Feb 24 10:26:12 2008
New Revision: 630652

URL: http://svn.apache.org/viewvc?rev=630652&view=rev
Log:
Improved generic type detection

Added:
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/AbstractObjectGraphTest.java
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphNestedTest.java
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphReferenceTest.java
      - copied, changed from r617547, geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphTest.java
Removed:
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphTest.java
Modified:
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Construction.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionStrategy.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstruction.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstructionStrategy.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Recipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/RecipeHelper.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Reference.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/UnsetPropertiesRecipe.java
    geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ReferenceTest.java

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java Sun Feb 24 10:26:12 2008
@@ -21,6 +21,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
+import java.lang.reflect.Type;
 
 public abstract class AbstractRecipe implements Recipe {
     private static final AtomicLong ID = new AtomicLong(1);
@@ -66,7 +67,7 @@
         }
     }
 
-    public final Object create(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    public final Object create(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         if (expectedType == null) throw new NullPointerException("expectedType is null");
 
         // assure there is a valid thread context class loader
@@ -120,7 +121,7 @@
         }
     }
 
-    protected abstract Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException;
+    protected abstract Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException;
 
     public List<Recipe> getNestedRecipes() {
         return Collections.emptyList();

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/AllPropertiesRecipe.java Sun Feb 24 10:26:12 2008
@@ -19,13 +19,14 @@
 
 import java.util.Map;
 import java.util.Properties;
+import java.lang.reflect.Type;
 
 public class AllPropertiesRecipe extends AbstractRecipe {
-    public boolean canCreate(Class type) {
-        return type.isAssignableFrom(Properties.class);
+    public boolean canCreate(Type type) {
+        return RecipeHelper.isAssignable(type, Properties.class);
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         Recipe outerRecipe = RecipeHelper.getCaller();
         if (!(outerRecipe instanceof ObjectRecipe)) {
             throw new ConstructionException("UnsetPropertiesRecipe can only be nested in an ObjectRecipe: outerRecipe=" + outerRecipe);

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java Sun Feb 24 10:26:12 2008
@@ -105,12 +105,12 @@
         return Collections.emptyList();
     }
 
-    public boolean canCreate(Class expectedType) {
+    public boolean canCreate(Type expectedType) {
         Class myType = getType(expectedType);
-        return expectedType.isAssignableFrom(myType);
+        return RecipeHelper.isAssignable(expectedType, myType);
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         Class type = getType(expectedType);
 
         if (!RecipeHelper.hasDefaultConstructor(type)) {
@@ -135,10 +135,10 @@
         }
 
         // get component type
-        Class<?> componentType = Object.class;
+        Type componentType = Object.class;
         Type[] typeParameters = RecipeHelper.getTypeParameters(Collection.class, expectedType);
         if (typeParameters != null && typeParameters.length == 1 && typeParameters[0] instanceof Class) {
-            componentType = (Class<?>) typeParameters[0];
+            componentType = typeParameters[0];
         }
 
         boolean refAllowed = options.contains(Option.LAZY_ASSIGNMENT);
@@ -166,8 +166,9 @@
         return instance;
     }
 
-    private Class getType(Class expectedType) {
-        Class type = expectedType;
+    private Class getType(Type expectedType) {
+        Class expectedClass = RecipeHelper.toClass(expectedType);
+        Class type = expectedClass;
         if (typeClass != null || typeName != null) {
             type = typeClass;
             if (type == null) {
@@ -180,19 +181,19 @@
 
             // if expectedType is a subclass of the assigned type,
             // we use it assuming it has a default constructor
-            if (type.isAssignableFrom(expectedType) && RecipeHelper.hasDefaultConstructor(expectedType)) {
-                type = expectedType;
+            if (type.isAssignableFrom(expectedClass) && RecipeHelper.hasDefaultConstructor(expectedClass)) {
+                type = expectedClass;
             }
         }
 
         // no type explicitly set
         if (RecipeHelper.hasDefaultConstructor(type)) {
-            return expectedType;
-        } else if (expectedType.isAssignableFrom(SortedSet.class)) {
+            return expectedClass;
+        } else if (expectedClass.isAssignableFrom(SortedSet.class)) {
             return TreeSet.class;
-        } else if (expectedType.isAssignableFrom(Set.class)) {
+        } else if (expectedClass.isAssignableFrom(Set.class)) {
             return LinkedHashSet.class;
-        } else if (expectedType.isAssignableFrom(List.class)) {
+        } else if (expectedClass.isAssignableFrom(List.class)) {
             return ArrayList.class;
         } else {
             return ArrayList.class;

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Construction.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Construction.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Construction.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Construction.java Sun Feb 24 10:26:12 2008
@@ -17,12 +17,13 @@
  */
 package org.apache.xbean.recipe;
 
+import java.lang.reflect.Type;
 import java.util.List;
 
 public interface Construction {
     List<String> getParameterNames();
 
-    List<Class> getParameterTypes();
+    List<Type> getParameterTypes();
 
     Object create(Object... parameters) throws ConstructionException;
 

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionStrategy.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionStrategy.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionStrategy.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ConstructionStrategy.java Sun Feb 24 10:26:12 2008
@@ -17,6 +17,8 @@
  */
 package org.apache.xbean.recipe;
 
+import java.lang.reflect.Type;
+
 public interface ConstructionStrategy {
-    Construction getConstruction(ObjectRecipe recipe, Class expectedType) throws ConstructionException;
+    Construction getConstruction(ObjectRecipe recipe, Type expectedType) throws ConstructionException;
 }

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java Sun Feb 24 10:26:12 2008
@@ -106,15 +106,15 @@
         }
     }
 
-    public void addReference(String name, Reference reference) {
-        Object value = repository.get(name);
+    public void addReference(Reference reference) {
+        Object value = repository.get(reference.getName());
         if (value != null && !(value instanceof Recipe)) {
             reference.set(value);
         } else {
-            List<Reference> list = unresolvedRefs.get(name);
+            List<Reference> list = unresolvedRefs.get(reference.getName());
             if (list == null) {
                 list = new ArrayList<Reference>();
-                unresolvedRefs.put(name, list);
+                unresolvedRefs.put(reference.getName(), list);
             }
             list.add(reference);
         }

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExecutionContext.java Sun Feb 24 10:26:12 2008
@@ -90,14 +90,13 @@
     public abstract void addObject(String name, Object object);
 
     /**
-     * Adds a reference to an object with the specified name.  If an object is already registered under
-     * the specified name, the reference will immedately be set.  Otherwise, the reference will be set
-     * when an object is added with the specified name.
+     * Adds a reference to an object to this context.  If an object is already registered under
+     * the referenced name, the reference will immedately be set.  Otherwise, the reference will be set
+     * when an object is added with the referenced name.
      *
-     * @param name the name of the referenced object instance
      * @param reference the reference to set
      */
-    public abstract void addReference(String name, Reference reference);
+    public abstract void addReference(Reference reference);
 
     /**
      * Gets the unresolved references by name.

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstruction.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstruction.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstruction.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstruction.java Sun Feb 24 10:26:12 2008
@@ -20,6 +20,7 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -49,15 +50,15 @@
         return new ArrayList<String>(Arrays.asList(parameterNames));
     }
 
-    public List<Class> getParameterTypes() {
+    public List<Type> getParameterTypes() {
         if (constructor == null && staticFactory == null) {
             throw new ConstructionException("InstanceFactory has not been initialized");
         }
 
         if (staticFactory != null) {
-            return new ArrayList<Class>(Arrays.asList(staticFactory.getParameterTypes()));
+            return new ArrayList<Type>(Arrays.asList(staticFactory.getGenericParameterTypes()));
         }
-        return new ArrayList<Class>(Arrays.asList(constructor.getParameterTypes()));
+        return new ArrayList<Type>(Arrays.asList(constructor.getGenericParameterTypes()));
     }
 
     public Object create(Object... parameters) throws ConstructionException {

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstructionStrategy.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstructionStrategy.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstructionStrategy.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ExplicitConstructionStrategy.java Sun Feb 24 10:26:12 2008
@@ -20,9 +20,10 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 
 public class ExplicitConstructionStrategy implements ConstructionStrategy {
-    public Construction getConstruction(ObjectRecipe recipe, Class expectedType) throws ConstructionException {
+    public Construction getConstruction(ObjectRecipe recipe, Type expectedType) throws ConstructionException {
         Class type = recipe.getType();
 
         //
@@ -59,8 +60,8 @@
         // if expectedType is a subclass of the assigned type, we create
         // the sub class instead
         Class consturctorClass;
-        if (type.isAssignableFrom(expectedType)) {
-            consturctorClass = expectedType;
+        if (RecipeHelper.isAssignable(type, expectedType)) {
+            consturctorClass = RecipeHelper.toClass(expectedType);
         } else {
             consturctorClass = type;
         }

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/MapRecipe.java Sun Feb 24 10:26:12 2008
@@ -111,12 +111,12 @@
         return Collections.emptyList();
     }
 
-    public boolean canCreate(Class type) {
+    public boolean canCreate(Type type) {
         Class myType = getType(type);
-        return type.isAssignableFrom(myType);
+        return RecipeHelper.isAssignable(type, myType);
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         Class mapType = getType(expectedType);
 
         if (!RecipeHelper.hasDefaultConstructor(mapType)) {
@@ -136,15 +136,15 @@
         Map instance = (Map) o;
 
         // get component type
-        Class<?> keyType = Object.class;
-        Class<?> valueType = Object.class;
+        Type keyType = Object.class;
+        Type valueType = Object.class;
         Type[] typeParameters = RecipeHelper.getTypeParameters(Collection.class, expectedType);
         if (typeParameters != null && typeParameters.length == 2) {
             if (typeParameters[0] instanceof Class) {
-                keyType = (Class<?>) typeParameters[0];
+                keyType = typeParameters[0];
             }
             if (typeParameters[1] instanceof Class) {
-                valueType = (Class<?>) typeParameters[1];
+                valueType = typeParameters[1];
             }
         }
 
@@ -182,7 +182,8 @@
         return instance;
     }
 
-    private Class getType(Class expectedType) {
+    private Class getType(Type expectedType) {
+        Class expectedClass = RecipeHelper.toClass(expectedType);
         if (typeClass != null || typeName != null) {
             Class type = typeClass;
             if (type == null) {
@@ -195,18 +196,17 @@
 
             // if expectedType is a subclass of the assigned type,
             // we use it assuming it has a default constructor
-            if (type.isAssignableFrom(expectedType) && RecipeHelper.hasDefaultConstructor(expectedType)) {
-                return expectedType;
+            if (type.isAssignableFrom(expectedClass) && RecipeHelper.hasDefaultConstructor(expectedClass)) {
+                return expectedClass;
             }
-            return type;
         }
 
         // no type explicitly set
-        if (RecipeHelper.hasDefaultConstructor(expectedType)) {
-            return expectedType;
-        } else if (expectedType.isAssignableFrom(SortedMap.class)) {
+        if (RecipeHelper.hasDefaultConstructor(expectedClass)) {
+            return expectedClass;
+        } else if (expectedClass.isAssignableFrom(SortedMap.class)) {
             return TreeMap.class;
-        } else if (expectedType.isAssignableFrom(ConcurrentMap.class)) {
+        } else if (expectedClass.isAssignableFrom(ConcurrentMap.class)) {
             return ConcurrentHashMap.class;
         } else {
             return LinkedHashMap.class;

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectGraph.java Sun Feb 24 10:26:12 2008
@@ -111,12 +111,13 @@
         // construct the graph
         Map<String, Node> nodes = new LinkedHashMap<String, Node>();
         for (String name : names) {
-            if (!nodes.containsKey(name)) {
-                Object object = repository.get(name);
-                if (object instanceof Recipe) {
-                    Recipe recipe = (Recipe) object;
-                    createNode(name, recipe,  nodes);
+            Object object = repository.get(name);
+            if (object instanceof Recipe) {
+                Recipe recipe = (Recipe) object;
+                if (!recipe.getName().equals(name)) {
+                    throw new ConstructionException("Recipe '" + name + "' returned from the repository has name '" + name + "'");
                 }
+                createNode(name, recipe,  nodes);
             }
         }
 
@@ -188,21 +189,29 @@
     }
 
     private Node createNode(String name, Recipe recipe, Map<String, Node> nodes) {
+        // if node already exists, verify that the exact same recipe instnace is used for both
+        if (nodes.containsKey(name)) {
+            Node node = nodes.get(name);
+            if (node.recipe != recipe) {
+                throw new ConstructionException("The name '" + name +"' is assigned to multiple recipies");
+            }
+            return node;
+        }
+
+        // create the node
         Node node = new Node();
         node.name = name;
         node.recipe = recipe;
         nodes.put(name, node);
 
+        // link in the references
         LinkedList<Recipe> nestedRecipes = new LinkedList<Recipe>(recipe.getNestedRecipes());
         LinkedList<Recipe> constructorRecipes = new LinkedList<Recipe>(recipe.getConstructorRecipes());
         while (!nestedRecipes.isEmpty()) {
             Recipe nestedRecipe = nestedRecipes.removeFirst();
             String nestedName = nestedRecipe.getName();
             if (nestedName != null) {
-                Node nestedNode = nodes.get(nestedName);
-                if (nestedNode == null) {
-                    nestedNode = createNode(nestedName, nestedRecipe, nodes);
-                }
+                Node nestedNode = createNode(nestedName, nestedRecipe, nodes);
 
                 // if this is a constructor recipe, we need to add a reference link
                 if (constructorRecipes.contains(nestedRecipe)) {
@@ -262,8 +271,8 @@
             constructedObject.put(name, object);
         }
 
-        public void addReference(String name, Reference reference) {
-            executionContext.addReference(name, reference);
+        public void addReference(Reference reference) {
+            executionContext.addReference(reference);
         }
 
         public Map<String, List<Reference>> getUnresolvedRefs() {

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ObjectRecipe.java Sun Feb 24 10:26:12 2008
@@ -20,6 +20,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.LinkedHashMap;
@@ -249,12 +250,12 @@
         }
     }
 
-    public boolean canCreate(Class type) {
+    public boolean canCreate(Type type) {
         Class myType = getType();
-        return type.isAssignableFrom(myType) || type.isAssignableFrom(myType);
+        return RecipeHelper.isAssignable(type, myType) || RecipeHelper.isAssignable(type, myType);
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         unsetProperties.clear();
         // load the type class
         Class typeClass = getType();
@@ -402,11 +403,11 @@
         }
     }
 
-    private Object[] extractConstructorArgs(Map propertyValues, List<String> argNames, List<Class> argTypes) {
+    private Object[] extractConstructorArgs(Map propertyValues, List<String> argNames, List<Type> argTypes) {
         Object[] parameters = new Object[argNames.size()];
         for (int i = 0; i < argNames.size(); i++) {
             Property name = new Property(argNames.get(i));
-            Class type = argTypes.get(i);
+            Type type = argTypes.get(i);
 
             Object value;
             if (propertyValues.containsKey(name)) {
@@ -415,12 +416,12 @@
                     throw new ConstructionException("Invalid and non-convertable constructor parameter type: " +
                             "name=" + name + ", " +
                             "index=" + i + ", " +
-                            "expected=" + type.getName() + ", " +
+                            "expected=" + RecipeHelper.toClass(type).getName() + ", " +
                             "actual=" + (value == null ? "null" : value.getClass().getName()));
                 }
                 value = RecipeHelper.convert(type, value, false);
             } else {
-                value = getDefaultValue(type);
+                value = getDefaultValue(RecipeHelper.toClass(type));
             }
 
 
@@ -451,7 +452,7 @@
     }
 
     public static interface Member {
-        Class getType();
+        Type getType();
         void setValue(Object instance, Object value) throws Exception;
     }
 
@@ -462,8 +463,8 @@
             this.setter = method;
         }
 
-        public Class getType() {
-            return setter.getParameterTypes()[0];
+        public Type getType() {
+            return setter.getGenericParameterTypes()[0];
         }
 
         public void setValue(Object instance, Object value) throws Exception {
@@ -482,8 +483,8 @@
             this.field = field;
         }
 
-        public Class getType() {
-            return field.getType();
+        public Type getType() {
+            return field.getGenericType();
         }
 
         public void setValue(Object instance, Object value) throws Exception {

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Recipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Recipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Recipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Recipe.java Sun Feb 24 10:26:12 2008
@@ -18,6 +18,7 @@
 
 import java.io.Serializable;
 import java.util.List;
+import java.lang.reflect.Type;
 
 /**
  * @version $Rev: 6680 $ $Date: 2005-12-24T04:38:27.427468Z $
@@ -27,11 +28,11 @@
 
     float getPriority();
 
-    boolean canCreate(Class type);
+    boolean canCreate(Type type);
 
     Object create() throws ConstructionException;
     Object create(ClassLoader classLoader) throws ConstructionException;
-    Object create(Class expectedType, boolean lazyRefAllowed) throws ConstructionException;
+    Object create(Type expectedType, boolean lazyRefAllowed) throws ConstructionException;
 
     List<Recipe> getNestedRecipes();
 

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/RecipeHelper.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/RecipeHelper.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/RecipeHelper.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/RecipeHelper.java Sun Feb 24 10:26:12 2008
@@ -23,6 +23,8 @@
 import java.lang.reflect.Type;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.TypeVariable;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Array;
 import java.util.Comparator;
 import java.util.Map;
 import java.util.List;
@@ -86,7 +88,8 @@
         return entries;
     }
 
-    public static boolean isInstance(Class type, Object instance) {
+    public static boolean isInstance(Type t, Object instance) {
+        Class type = toClass(t);
         if (type.isPrimitive()) {
             // for primitives the insance can't be null
             if (instance == null) {
@@ -118,12 +121,12 @@
         return instance == null || type.isInstance(instance);
     }
 
-    public static boolean isConvertable(Class type, Object propertyValue) {
+    public static boolean isConvertable(Type type, Object propertyValue) {
         if (propertyValue instanceof Recipe) {
             Recipe recipe = (Recipe) propertyValue;
             return recipe.canCreate(type);
         }
-        return (propertyValue instanceof String && PropertyEditors.canConvert(type));
+        return (propertyValue instanceof String && PropertyEditors.canConvert(toClass(type)));
     }
 
     public static boolean isAssignableFrom(Class expected, Class actual) {
@@ -155,7 +158,7 @@
         return expected.isAssignableFrom(actual);
     }
 
-    public static Object convert(Class expectedType, Object value, boolean lazyRefAllowed) {
+    public static Object convert(Type expectedType, Object value, boolean lazyRefAllowed) {
         if (value instanceof Recipe) {
             Recipe recipe = (Recipe) value;
             value = recipe.create(expectedType, lazyRefAllowed);
@@ -163,7 +166,7 @@
 
         if (value instanceof String && (expectedType != Object.class)) {
             String stringValue = (String) value;
-            value = PropertyEditors.getValue(expectedType, stringValue);
+            value = PropertyEditors.getValue(toClass(expectedType), stringValue);
         }
         return value;
     }
@@ -180,6 +183,29 @@
             }
         }
         return true;
+    }
+
+    public static boolean isAssignable(Type expectedType, Type actualType) {
+        Class expectedClass = toClass(expectedType);
+        Class actualClass = toClass(actualType);
+        return expectedClass.isAssignableFrom(actualClass);
+    }
+
+    public static Class toClass(Type type) {
+        // GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType
+        if (type instanceof Class) {
+            Class clazz = (Class) type;
+            return clazz;
+        } else if (type instanceof GenericArrayType) {
+            GenericArrayType arrayType = (GenericArrayType) type;
+            Class componentType = toClass(arrayType.getGenericComponentType());
+            return Array.newInstance(componentType, 0).getClass();
+        } else if (type instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) type;
+            return toClass(parameterizedType.getRawType());
+        } else {
+            return Object.class;
+        }
     }
 
     public static class RecipeComparator implements Comparator<Object> {

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Reference.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Reference.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Reference.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/Reference.java Sun Feb 24 10:26:12 2008
@@ -26,9 +26,26 @@
  * property on the source object of the reference.
  */
 public class Reference {
+    private final String name;
     private boolean resolved;
     private Object instance;
     private Action action;
+
+    /**
+     * Create a reference to the specified name.
+     * @param name the name of the referenced object
+     */
+    public Reference(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Gets the name of the referenced object.
+     * @return name the name of the referenced object
+     */
+    public String getName() {
+        return name;
+    }
 
     /**
      * Has this reference been resolved?

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java Sun Feb 24 10:26:12 2008
@@ -19,6 +19,7 @@
 
 import java.util.Collections;
 import java.util.List;
+import java.lang.reflect.Type;
 
 public class ReferenceRecipe extends AbstractRecipe {
     private String referenceName;
@@ -56,7 +57,7 @@
         return getNestedRecipes();
     }
 
-    public boolean canCreate(Class type) {
+    public boolean canCreate(Type type) {
         if (referenceName == null) {
             throw new ConstructionException("Reference name has not been set");
         }
@@ -72,7 +73,7 @@
         }
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         if (referenceName == null) {
             throw new ConstructionException("Reference name has not been set");
         }
@@ -86,15 +87,15 @@
                         " and a lazy reference not allowed");
             }
 
-            Reference reference = new Reference();
-            context.addReference(referenceName, reference);
+            Reference reference = new Reference(referenceName);
+            context.addReference(reference);
             object = reference;
         } else {
             object = context.getObject(referenceName);
             if (object instanceof Recipe) {
                 if (lazyRefAllowed) {
-                    Reference reference = new Reference();
-                    context.addReference(referenceName, reference);
+                    Reference reference = new Reference(referenceName);
+                    context.addReference(reference);
                     object = reference;
                 } else {
                     Recipe recipe = (Recipe) object;
@@ -117,11 +118,10 @@
     }
 
     private static class WrapperReference extends Reference {
-        private final String name;
         private final Reference delegate;
 
         private WrapperReference(String name, Reference delegate) {
-            this.name = name;
+            super(name);
             this.delegate = delegate;
         }
 
@@ -139,7 +139,7 @@
             }
 
             // add to execution context
-            ExecutionContext.getContext().addObject(name, object);
+            ExecutionContext.getContext().addObject(getName(), object);
 
             delegate.set(object);
         }

Modified: geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/UnsetPropertiesRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/UnsetPropertiesRecipe.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/UnsetPropertiesRecipe.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/main/java/org/apache/xbean/recipe/UnsetPropertiesRecipe.java Sun Feb 24 10:26:12 2008
@@ -19,17 +19,18 @@
 
 import java.util.Map;
 import java.util.Properties;
+import java.lang.reflect.Type;
 
 public class UnsetPropertiesRecipe extends AbstractRecipe {
     public float getPriority() {
         return 100;
     }
 
-    public boolean canCreate(Class type) {
-        return type.isAssignableFrom(Properties.class);
+    public boolean canCreate(Type type) {
+        return RecipeHelper.isAssignable(type, Properties.class);
     }
 
-    protected Object internalCreate(Class expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
         Recipe outerRecipe = RecipeHelper.getCaller();
         if (!(outerRecipe instanceof ObjectRecipe)) {
             throw new ConstructionException("UnsetPropertiesRecipe can only be nested in an ObjectRecipe: outerRecipe=" + outerRecipe);

Added: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/AbstractObjectGraphTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/AbstractObjectGraphTest.java?rev=630652&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/AbstractObjectGraphTest.java (added)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/AbstractObjectGraphTest.java Sun Feb 24 10:26:12 2008
@@ -0,0 +1,402 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.xbean.recipe;
+
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+public abstract class AbstractObjectGraphTest extends TestCase {
+    public void testCreateSingle() {
+        Repository repository = createNewRepository();
+        ObjectGraph graph = new ObjectGraph(repository);
+
+        Object actual = graph.create("Radiohead");
+        assertNotNull("actual is null", actual);
+        assertTrue("actual should be an instance of Artist", actual instanceof Artist);
+        Artist radiohead = (Artist)actual;
+        assertEquals(new Artist("Radiohead"), radiohead);
+
+        // multiple calls should result in same object
+        assertSame(radiohead, graph.create("Radiohead"));
+    }
+
+    public void testCreateNested() {
+        Album expectedBends = createBends();
+
+        Repository repository = createNewRepository();
+        ObjectGraph graph = new ObjectGraph(repository);
+
+        Object actual = graph.create("Bends");
+        assertNotNull("actual is null", actual);
+        assertTrue("actual should be an instance of Album", actual instanceof Album);
+        Album actualBends = (Album)actual;
+        assertEquals(expectedBends, actualBends);
+
+        // we should get the same values out of the graph
+        assertSame(actualBends, graph.create("Bends"));
+        assertSame(actualBends.getArtist(), graph.create("Radiohead"));
+        assertSame(actualBends.getSongs().get(0), graph.create("High and Dry"));
+        assertSame(actualBends.getSongs().get(1), graph.create("Fake Plastic Trees"));
+    }
+
+    public void testCreateAll() {
+        Album expectedBends = createBends();
+
+        Repository repository = createNewRepository();
+        ObjectGraph graph = new ObjectGraph(repository);
+
+        Map<String,Object> created = graph.createAll("Bends");
+        assertNotNull("created is null", created);
+        assertEquals(4, created.size());
+
+        Object actual = created.get("Bends");
+        assertNotNull("actual is null", actual);
+        assertTrue("actual should be an instance of Album", actual instanceof Album);
+        Album actualBends = (Album)actual;
+        assertEquals(expectedBends, actualBends);
+
+        // we should get the same values out of the graph
+        assertSame(actualBends, graph.create("Bends"));
+        assertSame(created.get("Radiohead"), graph.create("Radiohead"));
+        assertSame(created.get("High and Dry"), graph.create("High and Dry"));
+        assertSame(created.get("Fake Plastic Trees"), graph.create("Fake Plastic Trees"));
+
+        // verify nested objects in actualBends are the same objects in the created map
+        assertSame(actualBends.getArtist(), created.get("Radiohead"));
+        assertSame(actualBends.getSongs().get(0), created.get("High and Dry"));
+        assertSame(actualBends.getSongs().get(1), created.get("Fake Plastic Trees"));
+    }
+
+    public void testCreateAllGroupings() {
+        ObjectGraph graph = new ObjectGraph(createNewRepository());
+        Map<String,Object> created = graph.createAll("Radiohead");
+        assertEquals(Arrays.asList("Radiohead"), new ArrayList<String>(created.keySet()));
+
+        graph = new ObjectGraph(createNewRepository());
+        created = graph.createAll("Fake Plastic Trees");
+        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
+
+        graph = new ObjectGraph(createNewRepository());
+        created = graph.createAll("Fake Plastic Trees", "Fake Plastic Trees", "Fake Plastic Trees");
+        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
+
+        graph = new ObjectGraph(createNewRepository());
+        created = graph.createAll("Fake Plastic Trees", "Radiohead");
+        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
+
+        graph = new ObjectGraph(createNewRepository());
+        created = graph.createAll("Bends");
+        assertEquals(Arrays.asList("Radiohead", "Bends", "High and Dry", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
+
+        graph = new ObjectGraph(createNewRepository());
+        created = graph.createAll("Radiohead");
+        assertEquals(Arrays.asList("Radiohead"), new ArrayList<String>(created.keySet()));
+        created = graph.createAll("Bends");
+        assertEquals(Arrays.asList("Bends", "High and Dry", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
+    }
+
+    public void testCreateUnknown() {
+        ObjectGraph graph = new ObjectGraph(createNewRepository());
+        try {
+            graph.create("Unknown");
+            fail("Expected NoSuchObjectException");
+        } catch (NoSuchObjectException expected) {
+            assertEquals(expected.getName(), "Unknown");
+        }
+
+        try {
+            graph.createAll("Unknown");
+            fail("Expected NoSuchObjectException");
+        } catch (NoSuchObjectException expected) {
+            assertEquals(expected.getName(), "Unknown");
+        }
+
+        try {
+            graph.createAll("Radiohead", "Unknown");
+            fail("Expected NoSuchObjectException");
+        } catch (NoSuchObjectException expected) {
+            assertEquals(expected.getName(), "Unknown");
+        }
+
+        try {
+            graph.createAll("Unknown", "Radiohead");
+            fail("Expected NoSuchObjectException");
+        } catch (NoSuchObjectException expected) {
+            assertEquals(expected.getName(), "Unknown");
+        }
+    }
+
+    public void testCircularDependency() {
+        Repository repository = createNewRepository();
+        ObjectRecipe recipe = (ObjectRecipe) repository.get("Radiohead");
+        recipe.setConstructorArgNames(new String[] {"name", "albums"});
+        recipe.setProperty("albums", new CollectionRecipe(Arrays.asList(new ReferenceRecipe("Bends"))));
+
+        ObjectGraph graph = new ObjectGraph(repository);
+        try {
+            graph.create("Bends");
+            fail("Expected CircularDependencyException");
+        } catch (CircularDependencyException expected) {
+            assertCircularity(Arrays.asList(repository.get("Bends"), repository.get("Radiohead"), repository.get("Bends")),
+                    expected.getCircularDependency());
+        }
+
+
+        repository = createNewRepository();
+        recipe = (ObjectRecipe) repository.get("Radiohead");
+        recipe.setConstructorArgNames(new String[] {"name", "albums"});
+        recipe.setProperty("albums", new CollectionRecipe(Arrays.asList(repository.get("Bends"))));
+
+        graph = new ObjectGraph(repository);
+        try {
+            graph.create("Bends");
+            fail("Expected CircularDependencyException");
+        } catch (CircularDependencyException expected) {
+            assertCircularity(Arrays.asList(repository.get("Bends"), repository.get("Radiohead"), repository.get("Bends")),
+                    expected.getCircularDependency());
+        }
+    }
+
+    public void testInvalidGraph() {
+        Repository repository = createNewRepository();
+        ObjectRecipe bends = (ObjectRecipe) repository.get("Bends");
+        bends.setName("Other");
+
+        ObjectGraph graph = new ObjectGraph(repository);
+        try {
+//            graph.create("Bends");
+//            fail("Expected ConstructionException");
+        } catch (ConstructionException expected) {
+        }
+
+        //
+        // Multiple recipies with the same name
+        //
+        repository = createNewRepository();
+
+        ObjectRecipe radiohead = new ObjectRecipe(Artist.class, new String[]{"name"});
+        radiohead.setName("Radiohead");
+        radiohead.setProperty("name", "Radiohead");
+        repository.add("Radiohead", radiohead);
+        bends = (ObjectRecipe) repository.get("Bends");
+        bends.setProperty("artist", radiohead);
+
+        radiohead = new ObjectRecipe(Artist.class, new String[]{"name"});
+        radiohead.setName("Radiohead");
+        radiohead.setProperty("name", "Radiohead");
+        repository.add("Radiohead", radiohead);
+        ObjectRecipe highAndDry = (ObjectRecipe) repository.get("High and Dry");
+        highAndDry.setProperty("composer", radiohead);
+
+        graph = new ObjectGraph(repository);
+        try {
+            graph.create("Bends");
+            fail("Expected ConstructionException");
+        } catch (ConstructionException expected) {
+        }
+    }
+
+    protected abstract Repository createNewRepository();
+
+    private Album createBends() {
+        Artist radiohead = new Artist("Radiohead");
+        Album bends = new Album("Bends", radiohead);
+        Song highAndDry = new Song("High and Dry", radiohead);
+        Song fakePlasticTrees = new Song("Fake Plastic Trees", radiohead);
+
+        bends.setSongs(Arrays.asList(highAndDry, fakePlasticTrees));
+
+        return bends;
+    }
+
+    public static void assertCircularity(List<?> expected, List<?> actual) {
+//        if (expected.size() != actual.size()) {
+//            // this will fail, with nice message
+//            assertEquals(expected, actual);
+//        }
+
+        List<Object> newActual = new ArrayList<Object>(actual.subList(0, actual.size() -1));
+
+        Object start = expected.get(0);
+        int index = actual.indexOf(start);
+        if (index > 0) Collections.rotate(newActual, index);
+        newActual.add(start);
+
+
+        assertEquals(expected, newActual);
+//
+//
+//        if (index < 1) {
+//            // acutal list already starts at the same object as the expected list
+//            assertEquals(expected, actual);
+//        } else {
+//            // create a new actual list rotated at the
+////            List<Object> newActual = new ArrayList<Object>(actual.size());
+////            newActual.addAll(actual.subList(index, actual.size()));
+////            newActual.addAll(actual.subList(1, index));
+////            newActual.add(start);
+////            assertEquals(expected, newActual);
+//        }
+    }
+
+    public static class Album {
+        private final String name;
+        private final Artist artist;
+        private List<Song> songs;
+
+        public Album(String name, Artist artist) {
+            if (name == null) throw new NullPointerException("name is null");
+            if (artist == null) throw new NullPointerException("artist is null");
+            this.name = name;
+            this.artist = artist;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Artist getArtist() {
+            return artist;
+        }
+
+        public List<Song> getSongs() {
+            return songs;
+        }
+
+        public void setSongs(List<Song> songs) {
+            this.songs = songs;
+        }
+
+        public String toString() {
+            return "[Album: " + name + " - " + artist.getName() + "]";
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Album album = (Album) o;
+
+            return name.equals(album.name) &&
+                    artist.equals(album.artist) &&
+                    !(songs != null ? !songs.equals(album.songs) : album.songs != null);
+
+        }
+
+        public int hashCode() {
+            int result;
+            result = name.hashCode();
+            result = 31 * result + artist.hashCode();
+            result = 31 * result + (songs != null ? songs.hashCode() : 0);
+            return result;
+        }
+    }
+
+    public static class Song {
+        private final String name;
+        private final Artist composer;
+
+        public Song(String name, Artist composer) {
+            if (name == null) throw new NullPointerException("name is null");
+            if (composer == null) throw new NullPointerException("composer is null");
+            this.name = name;
+            this.composer = composer;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Artist getComposer() {
+            return composer;
+        }
+
+        public String toString() {
+            return "[Song: " + name + " - " + composer.name + "]";
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Song song = (Song) o;
+
+            return name.equals(song.name) && composer.equals(song.composer);
+        }
+
+        public int hashCode() {
+            int result;
+            result = name.hashCode();
+            result = 31 * result + composer.hashCode();
+            return result;
+        }
+    }
+
+    public static class Artist {
+        private final String name;
+        private final Set<Album> albums = new HashSet<Album>();
+
+        public Artist(String name) {
+            if (name == null) throw new NullPointerException("name is null");
+            this.name = name;
+        }
+
+        public Artist(String name, Set<Album> albums) {
+            if (name == null) throw new NullPointerException("name is null");
+            this.name = name;
+            this.albums.addAll(albums);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Set<Album> getAlbums() {
+            return albums;
+        }
+
+        public void setAlbums(Set<Album> albums) {
+            this.albums.clear();
+            this.albums.addAll(albums);
+        }
+
+        public String toString() {
+            return "[Artist: " + name + "]";
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Artist artist = (Artist) o;
+
+            return name.equals(artist.name);
+        }
+
+        public int hashCode() {
+            return name.hashCode();
+        }
+    }
+}

Added: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphNestedTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphNestedTest.java?rev=630652&view=auto
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphNestedTest.java (added)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphNestedTest.java Sun Feb 24 10:26:12 2008
@@ -0,0 +1,54 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.xbean.recipe;
+
+import java.util.Arrays;
+
+public class ObjectGraphNestedTest extends AbstractObjectGraphTest {
+    protected Repository createNewRepository() {
+        Repository repository = new DefaultRepository();
+
+        ObjectRecipe radiohead = new ObjectRecipe(Artist.class, new String[]{"name"});
+        radiohead.setName("Radiohead");
+        radiohead.setProperty("name", "Radiohead");
+        repository.add("Radiohead", radiohead);
+
+        ObjectRecipe highAndDry = new ObjectRecipe(Song.class, new String[]{"name", "composer"});
+        highAndDry.setName("High and Dry");
+        highAndDry.setProperty("name", "High and Dry");
+        highAndDry.setProperty("composer", radiohead);
+        repository.add("High and Dry", highAndDry);
+
+        ObjectRecipe fakePlasticTrees = new ObjectRecipe(Song.class, new String[]{"name", "composer"});
+        fakePlasticTrees.setName("Fake Plastic Trees");
+        fakePlasticTrees.setProperty("name", "Fake Plastic Trees");
+        fakePlasticTrees.setProperty("composer", radiohead);
+        repository.add("Fake Plastic Trees", fakePlasticTrees);
+
+        ObjectRecipe bends = new ObjectRecipe(Album.class, new String[]{"name", "artist"});
+        bends.setName("Bends");
+        bends.setProperty("name", "Bends");
+        bends.setProperty("artist", radiohead);
+        bends.setProperty("songs", new CollectionRecipe(Arrays.asList(highAndDry, fakePlasticTrees)));
+        bends.setProperty("artist", radiohead);
+        repository.add("Bends", bends);
+
+        return repository;
+    }
+
+}
\ No newline at end of file

Copied: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphReferenceTest.java (from r617547, geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphTest.java)
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphReferenceTest.java?p2=geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphReferenceTest.java&p1=geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphTest.java&r1=617547&r2=630652&rev=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphTest.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ObjectGraphReferenceTest.java Sun Feb 24 10:26:12 2008
@@ -17,171 +17,10 @@
  */
 package org.apache.xbean.recipe;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
-import junit.framework.TestCase;
-
-public class ObjectGraphTest extends TestCase {
-    public void testCreateSingle() {
-        Repository repository = createNewRepository();
-        ObjectGraph graph = new ObjectGraph(repository);
-
-        Object actual = graph.create("Radiohead");
-        assertNotNull("actual is null", actual);
-        assertTrue("actual should be an instance of Artist", actual instanceof Artist);
-        Artist radiohead = (Artist)actual;
-        assertEquals(new Artist("Radiohead"), radiohead);
-
-        // multiple calls should result in same object
-        assertSame(radiohead, graph.create("Radiohead"));
-    }
-
-    public void testCreateNested() {
-        Album expectedBends = createBends();
-
-        Repository repository = createNewRepository();
-        ObjectGraph graph = new ObjectGraph(repository);
-
-        Object actual = graph.create("Bends");
-        assertNotNull("actual is null", actual);
-        assertTrue("actual should be an instance of Album", actual instanceof Album);
-        Album actualBends = (Album)actual;
-        assertEquals(expectedBends, actualBends);
-
-        // we should get the same values out of the graph
-        assertSame(actualBends, graph.create("Bends"));
-        assertSame(actualBends.getArtist(), graph.create("Radiohead"));
-        assertSame(actualBends.getSongs().get(0), graph.create("High and Dry"));
-        assertSame(actualBends.getSongs().get(1), graph.create("Fake Plastic Trees"));
-    }
-
-    public void testCreateAll() {
-        Album expectedBends = createBends();
-
-        Repository repository = createNewRepository();
-        ObjectGraph graph = new ObjectGraph(repository);
-
-        Map<String,Object> created = graph.createAll("Bends");
-        assertNotNull("created is null", created);
-        assertEquals(4, created.size());
-
-        Object actual = created.get("Bends");
-        assertNotNull("actual is null", actual);
-        assertTrue("actual should be an instance of Album", actual instanceof Album);
-        Album actualBends = (Album)actual;
-        assertEquals(expectedBends, actualBends);
-
-        // we should get the same values out of the graph
-        assertSame(actualBends, graph.create("Bends"));
-        assertSame(created.get("Radiohead"), graph.create("Radiohead"));
-        assertSame(created.get("High and Dry"), graph.create("High and Dry"));
-        assertSame(created.get("Fake Plastic Trees"), graph.create("Fake Plastic Trees"));
-
-        // verify nested objects in actualBends are the same objects in the created map
-        assertSame(actualBends.getArtist(), created.get("Radiohead"));
-        assertSame(actualBends.getSongs().get(0), created.get("High and Dry"));
-        assertSame(actualBends.getSongs().get(1), created.get("Fake Plastic Trees"));
-    }
-
-    public void testCreateAllGroupings() {
-        ObjectGraph graph = new ObjectGraph(createNewRepository());
-        Map<String,Object> created = graph.createAll("Radiohead");
-        assertEquals(Arrays.asList("Radiohead"), new ArrayList<String>(created.keySet()));
-
-        graph = new ObjectGraph(createNewRepository());
-        created = graph.createAll("Fake Plastic Trees");
-        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
-
-        graph = new ObjectGraph(createNewRepository());
-        created = graph.createAll("Fake Plastic Trees", "Fake Plastic Trees", "Fake Plastic Trees");
-        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
-
-        graph = new ObjectGraph(createNewRepository());
-        created = graph.createAll("Fake Plastic Trees", "Radiohead");
-        assertEquals(Arrays.asList("Radiohead", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
-
-        graph = new ObjectGraph(createNewRepository());
-        created = graph.createAll("Bends");
-        assertEquals(Arrays.asList("Radiohead", "Bends", "High and Dry", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
-
-        graph = new ObjectGraph(createNewRepository());
-        created = graph.createAll("Radiohead");
-        assertEquals(Arrays.asList("Radiohead"), new ArrayList<String>(created.keySet()));
-        created = graph.createAll("Bends");
-        assertEquals(Arrays.asList("Bends", "High and Dry", "Fake Plastic Trees"), new ArrayList<String>(created.keySet()));
-    }
-
-    public void testCreateUnknown() {
-        ObjectGraph graph = new ObjectGraph(createNewRepository());
-        try {
-            graph.create("Unknown");
-            fail("Expected NoSuchObjectException");
-        } catch (NoSuchObjectException expected) {
-            assertEquals(expected.getName(), "Unknown");
-        }
-
-        try {
-            graph.createAll("Unknown");
-            fail("Expected NoSuchObjectException");
-        } catch (NoSuchObjectException expected) {
-            assertEquals(expected.getName(), "Unknown");
-        }
-
-        try {
-            graph.createAll("Radiohead", "Unknown");
-            fail("Expected NoSuchObjectException");
-        } catch (NoSuchObjectException expected) {
-            assertEquals(expected.getName(), "Unknown");
-        }
-
-        try {
-            graph.createAll("Unknown", "Radiohead");
-            fail("Expected NoSuchObjectException");
-        } catch (NoSuchObjectException expected) {
-            assertEquals(expected.getName(), "Unknown");
-        }
-    }
-
-    public void testCircularDependency() {
-        Repository repository = createNewRepository();
-        ObjectRecipe recipe = (ObjectRecipe) repository.get("Radiohead");
-        recipe.setConstructorArgNames(new String[] {"name", "albums"});
-        recipe.setProperty("albums", new CollectionRecipe(Arrays.asList(new ReferenceRecipe("Bends"))));
-
-        ObjectGraph graph = new ObjectGraph(repository);
-        try {
-            graph.create("Bends");
-            fail("Expected CircularDependencyException");
-        } catch (CircularDependencyException expected) {
-            assertCircularity(Arrays.asList(repository.get("Bends"), repository.get("Radiohead"), repository.get("Bends")),
-                    expected.getCircularDependency());
-        }
-
-
-        repository = createNewRepository();
-        recipe = (ObjectRecipe) repository.get("Radiohead");
-        recipe.setConstructorArgNames(new String[] {"name", "albums"});
-        recipe.setProperty("albums", new CollectionRecipe(Arrays.asList(repository.get("Bends"))));
-
-        graph = new ObjectGraph(repository);
-        try {
-            graph.create("Bends");
-            fail("Expected CircularDependencyException");
-        } catch (CircularDependencyException expected) {
-            assertCircularity(Arrays.asList(repository.get("Bends"), repository.get("Radiohead"), repository.get("Bends")),
-                    expected.getCircularDependency());
-        }
-
-
-    }
-
-    private Repository createNewRepository() {
+public class ObjectGraphReferenceTest extends AbstractObjectGraphTest {
+    protected Repository createNewRepository() {
         Repository repository = new DefaultRepository();
 
         ObjectRecipe bends = new ObjectRecipe(Album.class, new String[]{"name", "artist"});
@@ -211,216 +50,5 @@
         fakePlasticTrees.setProperty("composer", new ReferenceRecipe("Radiohead"));
         repository.add("Fake Plastic Trees", fakePlasticTrees);
         return repository;
-    }
-
-    private Repository XcreateNewRepository() {
-        Repository repository = new DefaultRepository();
-
-        ObjectRecipe radiohead = new ObjectRecipe(Artist.class, new String[]{"name"});
-        radiohead.setName("Radiohead");
-        radiohead.setProperty("name", "Radiohead");
-        repository.add("Radiohead", radiohead);
-
-        ObjectRecipe highAndDry = new ObjectRecipe(Song.class, new String[]{"name", "composer"});
-        highAndDry.setName("High and Dry");
-        highAndDry.setProperty("name", "High and Dry");
-        highAndDry.setProperty("composer", radiohead);
-        repository.add("High and Dry", highAndDry);
-
-        ObjectRecipe fakePlasticTrees = new ObjectRecipe(Song.class, new String[]{"name", "composer"});
-        fakePlasticTrees.setName("Fake Plastic Trees");
-        fakePlasticTrees.setProperty("name", "Fake Plastic Trees");
-        fakePlasticTrees.setProperty("composer", radiohead);
-        repository.add("Fake Plastic Trees", fakePlasticTrees);
-
-        ObjectRecipe bends = new ObjectRecipe(Album.class, new String[]{"name", "artist"});
-        bends.setName("Bends");
-        bends.setProperty("name", "Bends");
-        bends.setProperty("artist", radiohead);
-        bends.setProperty("songs", new CollectionRecipe(Arrays.asList(highAndDry, fakePlasticTrees)));
-        bends.setProperty("artist", radiohead);
-        repository.add("Bends", bends);
-
-        return repository;
-    }
-
-    private Album createBends() {
-        Artist radiohead = new Artist("Radiohead");
-        Album bends = new Album("Bends", radiohead);
-        Song highAndDry = new Song("High and Dry", radiohead);
-        Song fakePlasticTrees = new Song("Fake Plastic Trees", radiohead);
-
-        bends.setSongs(Arrays.asList(highAndDry, fakePlasticTrees));
-
-        return bends;
-    }
-
-    public static class Album {
-        private final String name;
-        private final Artist artist;
-        private List<Song> songs;
-
-        public Album(String name, Artist artist) {
-            if (name == null) throw new NullPointerException("name is null");
-            if (artist == null) throw new NullPointerException("artist is null");
-            this.name = name;
-            this.artist = artist;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Artist getArtist() {
-            return artist;
-        }
-
-        public List<Song> getSongs() {
-            return songs;
-        }
-
-        public void setSongs(List<Song> songs) {
-            this.songs = songs;
-        }
-
-        public String toString() {
-            return "[Album: " + name + " - " + artist.getName() + "]";
-        }
-
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            Album album = (Album) o;
-
-            return name.equals(album.name) &&
-                    artist.equals(album.artist) &&
-                    !(songs != null ? !songs.equals(album.songs) : album.songs != null);
-
-        }
-
-        public int hashCode() {
-            int result;
-            result = name.hashCode();
-            result = 31 * result + artist.hashCode();
-            result = 31 * result + (songs != null ? songs.hashCode() : 0);
-            return result;
-        }
-    }
-
-    public static class Song {
-        private final String name;
-        private final Artist composer;
-
-        public Song(String name, Artist composer) {
-            if (name == null) throw new NullPointerException("name is null");
-            if (composer == null) throw new NullPointerException("composer is null");
-            this.name = name;
-            this.composer = composer;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Artist getComposer() {
-            return composer;
-        }
-
-        public String toString() {
-            return "[Song: " + name + " - " + composer.name + "]";
-        }
-
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            Song song = (Song) o;
-
-            return name.equals(song.name) && composer.equals(song.composer);
-        }
-
-        public int hashCode() {
-            int result;
-            result = name.hashCode();
-            result = 31 * result + composer.hashCode();
-            return result;
-        }
-    }
-
-    public static class Artist {
-        private final String name;
-        private final Set<Album> albums = new HashSet<Album>();
-
-        public Artist(String name) {
-            if (name == null) throw new NullPointerException("name is null");
-            this.name = name;
-        }
-
-        public Artist(String name, Set<Album> albums) {
-            if (name == null) throw new NullPointerException("name is null");
-            this.name = name;
-            this.albums.addAll(albums);
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public Set<Album> getAlbums() {
-            return albums;
-        }
-
-        public void setAlbums(Set<Album> albums) {
-            this.albums.clear();
-            this.albums.addAll(albums);
-        }
-
-        public String toString() {
-            return "[Artist: " + name + "]";
-        }
-
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-
-            Artist artist = (Artist) o;
-
-            return name.equals(artist.name);
-        }
-
-        public int hashCode() {
-            return name.hashCode();
-        }
-    }
-
-    public static void assertCircularity(List<?> expected, List<?> actual) {
-//        if (expected.size() != actual.size()) {
-//            // this will fail, with nice message
-//            assertEquals(expected, actual);
-//        }
-
-        List<Object> newActual = new ArrayList<Object>(actual.subList(0, actual.size() -1));
-
-        Object start = expected.get(0);
-        int index = actual.indexOf(start);
-        if (index > 0) Collections.rotate(newActual, index);
-        newActual.add(start);
-
-
-        assertEquals(expected, newActual);
-//
-//
-//        if (index < 1) {
-//            // acutal list already starts at the same object as the expected list
-//            assertEquals(expected, actual);
-//        } else {
-//            // create a new actual list rotated at the
-////            List<Object> newActual = new ArrayList<Object>(actual.size());
-////            newActual.addAll(actual.subList(index, actual.size()));
-////            newActual.addAll(actual.subList(1, index));
-////            newActual.add(start);
-////            assertEquals(expected, newActual);
-//        }
     }
 }

Modified: geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ReferenceTest.java
URL: http://svn.apache.org/viewvc/geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ReferenceTest.java?rev=630652&r1=630651&r2=630652&view=diff
==============================================================================
--- geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ReferenceTest.java (original)
+++ geronimo/xbean/trunk/xbean-reflect/src/test/java/org/apache/xbean/recipe/ReferenceTest.java Sun Feb 24 10:26:12 2008
@@ -24,7 +24,7 @@
 
 public class ReferenceTest extends TestCase {
     public void testReference() {
-        Reference reference = new Reference();
+        Reference reference = new Reference("fruit");
         TestAction action = new TestAction();
         reference.setAction(action);
 
@@ -50,7 +50,7 @@
     }
 
     public void testNullReference() {
-        Reference reference = new Reference();
+        Reference reference = new Reference("fruit");
         TestAction action = new TestAction();
         reference.setAction(action);
 
@@ -77,11 +77,11 @@
 
     public void testContext() {
         DefaultExecutionContext context = new DefaultExecutionContext();
-        Reference reference = new Reference();
+        Reference reference = new Reference("fruit");
         TestAction action = new TestAction();
         reference.setAction(action);
 
-        context.addReference("fruit", reference);
+        context.addReference(reference);
 
         assertFalse(reference.isResolved());
         assertNull(reference.get());
@@ -100,11 +100,11 @@
 
     public void testNullContext() {
         DefaultExecutionContext context = new DefaultExecutionContext();
-        Reference reference = new Reference();
+        Reference reference = new Reference("fruit");
         TestAction action = new TestAction();
         reference.setAction(action);
 
-        context.addReference("fruit", reference);
+        context.addReference(reference);
 
         assertFalse(reference.isResolved());
         assertNull(reference.get());



Mime
View raw message