geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r768446 - in /geronimo/sandbox/blueprint/blueprint-core/src: main/java/org/apache/geronimo/blueprint/context/ main/java/org/apache/geronimo/blueprint/utils/ test/java/org/apache/geronimo/blueprint/ test/java/org/apache/geronimo/blueprint/po...
Date Sat, 25 Apr 2009 01:06:44 GMT
Author: gawor
Date: Sat Apr 25 01:06:43 2009
New Revision: 768446

URL: http://svn.apache.org/viewvc?rev=768446&view=rev
Log:
constructor injection - still needs lots of testing

Added:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
  (with props)
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
  (with props)
    geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml   (with
props)
Modified:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
    geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
    geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoB.java

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java?rev=768446&r1=768445&r2=768446&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java
Sat Apr 25 01:06:43 2009
@@ -21,13 +21,23 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.xbean.recipe.ConstructionException;
+import org.apache.xbean.recipe.ExecutionContext;
 import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Recipe;
+import org.apache.xbean.recipe.RecipeHelper;
 import org.apache.xbean.recipe.ReferenceRecipe;
 import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.utils.ArgumentsMatch;
+import org.apache.geronimo.blueprint.utils.ArgumentsMatcher;
+import org.osgi.service.blueprint.reflect.BeanArgument;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
 
 /**
  *
@@ -42,11 +52,37 @@
     private Method destroyMethod;
     private List<String> explicitDependencies;
     
+    private Object factory; // could be Recipe or actual object
+    private String factoryMethod;
+    private List<Object> arguments;
+    private List<BeanArgument> beanArguments;
+    private boolean reorderArguments;
+    
     public BlueprintObjectRecipe(BlueprintContextImpl blueprintContext, Class typeName) {
         super(typeName);
         this.blueprintContext = blueprintContext;
     }
     
+    public void setFactoryMethod(String method) {
+        this.factoryMethod = method;
+    }
+    
+    public void setFactoryComponent(Object factory) {
+        this.factory = factory;
+    }
+    
+    public void setBeanArguments(List<BeanArgument> arguments) {
+        this.beanArguments = arguments;
+    }
+    
+    public void setArguments(List<Object> arguments) {
+        this.arguments = arguments;
+    }
+    
+    public void setReorderArguments(boolean reorder) {
+        this.reorderArguments = reorder;
+    }
+    
     public void setKeepRecipe(boolean keepRecipe) {
         this.keepRecipe = keepRecipe;
     }
@@ -82,17 +118,154 @@
     @Override
     public List<Recipe> getNestedRecipes() {
         List<Recipe> recipes = super.getNestedRecipes();
+        if (arguments != null) {
+            for (Object argument : arguments) {
+                if (argument instanceof Recipe) {
+                    recipes.add((Recipe)argument);
+                }
+            }
+        }
         if (explicitDependencies != null) {
             for (String name : explicitDependencies) {
                 recipes.add(new ReferenceRecipe(name));
             }
         }
-        return recipes;
+        return recipes; 
     }
 
+    private List<Object> getInitialArguments(boolean refAllowed) throws ConstructionException
{
+        List<Object> args = new ArrayList<Object>();
+        for (int i = 0; beanArguments != null && i < beanArguments.size(); i++)
{
+            BeanArgument argument = beanArguments.get(i);
+            Object obj = arguments.get(i);
+            if (obj instanceof Recipe) {
+                if (shouldPreinstantiate(argument.getValue())) {
+                    obj = RecipeHelper.convert(Object.class, obj, refAllowed);
+                    obj = convert(obj, argument.getValueType());
+                }
+            } else {
+                obj = convert(obj, argument.getValueType());
+            }
+            args.add(obj);
+        }
+
+        return args;
+    }
+    
+    private boolean shouldPreinstantiate(Metadata metadata) {
+        if (metadata instanceof ValueMetadata) {
+            ValueMetadata stringValue = (ValueMetadata) metadata;
+            return (stringValue.getTypeName() != null);
+        }
+        return true;
+    }
+    
+    private Object convert(Object source, String typeName) throws ConstructionException {
+        Class type = null;
+        try {
+            type = Instanciator.loadClass(blueprintContext, typeName);
+        } catch (ClassNotFoundException e) {
+            throw new ConstructionException("Unable to load type class " + typeName);
+        }
+        if (type != null && blueprintContext != null) {
+            try {
+                source = blueprintContext.getConversionService().convert(source, type);
+            } catch (Exception e) {
+                throw new ConstructionException("Failed to convert", e);
+            }            
+        }
+        return source;
+    }
+    
+    private List<Object> getFinalArguments(ArgumentsMatch match, boolean refAllowed)
throws ConstructionException {
+        List<Object> arguments = match.getArguments();
+        Class[] parameterTypes = match.getParameterTypes();
+        
+        List<Object> args = new ArrayList<Object>();
+        for (int i = 0; i < arguments.size(); i++) {
+            Object argument = arguments.get(i);
+            if (argument instanceof Recipe) {
+                argument = RecipeHelper.convert(parameterTypes[i], argument, refAllowed);
+            }
+            args.add(argument);
+        }
+        
+        return args;
+    }
+          
+    private Set<ArgumentsMatcher.Option> getArgumentsMatcherOptions() {
+        Set<ArgumentsMatcher.Option> options = new HashSet<ArgumentsMatcher.Option>();
+        if (reorderArguments) {
+            options.add(ArgumentsMatcher.Option.ARGUMENT_REORDER);
+        }
+        return options;
+    }
+    
+    private Object getInstance(boolean refAllowed) throws ConstructionException {
+        Object instance = null;
+        
+        Set<ArgumentsMatcher.Option> options = getArgumentsMatcherOptions();
+        List<Object> arguments = getInitialArguments(refAllowed);
+                
+        if (factory != null) {
+            // look for instance method on factory object
+            Object factoryObj = RecipeHelper.convert(Object.class, factory, refAllowed);
+            options.add(ArgumentsMatcher.Option.INSTANCE_METHODS_ONLY);
+            ArgumentsMatch match = ArgumentsMatcher.findMethod(factoryObj.getClass(), factoryMethod,
arguments, options);
+            // convert parameters
+            List<Object> args = getFinalArguments(match, refAllowed);
+            // invoke instance method
+            try {
+                instance = match.getMethod().invoke(factoryObj, args.toArray());
+            } catch (InvocationTargetException e) {
+                throw new ConstructionException(e);
+            } catch (Exception e) {
+                throw new ConstructionException(e);
+            }
+        } else if (factoryMethod != null) {
+            // look for static method on this object
+            options.add(ArgumentsMatcher.Option.STATIC_METHODS_ONLY);
+            ArgumentsMatch match = ArgumentsMatcher.findMethod(getType(), factoryMethod,
arguments, options);
+            // convert parameters
+            List<Object> args = getFinalArguments(match, refAllowed);
+            // invoke static method
+            try {
+                instance = match.getMethod().invoke(null, args.toArray());
+            } catch (InvocationTargetException e) {
+                throw new ConstructionException(e);
+            } catch (Exception e) {
+                throw new ConstructionException(e);
+            }
+        } else {
+            // look for constructor on this object
+            ArgumentsMatch match = ArgumentsMatcher.findConstructor(getType(), arguments,
options);
+            // convert parameters
+            List<Object> args = getFinalArguments(match, refAllowed);
+            // invoke constructor
+            try {
+                instance = match.getConstructor().newInstance(args.toArray());
+            } catch (InvocationTargetException e) {
+                throw new ConstructionException(e);
+            } catch (Exception e) {
+                throw new ConstructionException(e);
+            }
+        }
+        
+        return instance;
+    }
+    
     @Override
     protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException
{
-        final Object obj = super.internalCreate(expectedType, lazyRefAllowed);
+        
+        final Object obj = getInstance(lazyRefAllowed);
+        
+        // inject properties
+        setProperties(obj);
+        
+        if (getName() != null) {
+            ExecutionContext.getContext().addObject(getName(), obj);
+        }
+        
         if (initMethod != null) {
             try {
                 initMethod.invoke(obj);

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java?rev=768446&r1=768445&r2=768446&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Instanciator.java
Sat Apr 25 01:06:43 2009
@@ -21,6 +21,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -41,8 +42,10 @@
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.ReferenceRecipe;
 import org.apache.xbean.recipe.Repository;
+import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.convert.ConversionService;
 import org.osgi.service.blueprint.namespace.ComponentDefinitionRegistry;
+import org.osgi.service.blueprint.reflect.BeanArgument;
 import org.osgi.service.blueprint.reflect.ComponentMetadata;
 import org.osgi.service.blueprint.reflect.BeanMetadata;
 import org.osgi.service.blueprint.reflect.MapMetadata;
@@ -245,9 +248,27 @@
             }
             recipe.setDestroyMethod(method);
         }
-        // TODO: constructor args
-        // TODO: factory-method
-        // TODO: factory-component
+        List<BeanArgument> beanArguments = local.getArguments(); 
+        if (beanArguments != null && !beanArguments.isEmpty()) {
+            boolean hasIndex = (beanArguments.get(0).getIndex() >= 0);
+            if (hasIndex) {
+                List<BeanArgument> beanArgumentsCopy = new ArrayList<BeanArgument>(beanArguments);
+                Collections.sort(beanArgumentsCopy, new BeanArgumentComparator());
+                beanArguments = beanArgumentsCopy;
+            }
+            List<Object> arguments = new ArrayList<Object>();
+            for (BeanArgument argument : beanArguments) {
+                Object value = getValue(argument.getValue(), null);
+                arguments.add(value);
+            }
+            recipe.setArguments(arguments);
+            recipe.setBeanArguments(beanArguments);
+            recipe.setReorderArguments(!hasIndex);
+        }
+        recipe.setFactoryMethod(local.getFactoryMethodName());
+        if (local.getFactoryComponent() != null) {
+            recipe.setFactoryComponent(getValue(local.getFactoryComponent(), null));
+        }
         return recipe;
     }
 
@@ -353,20 +374,30 @@
     }
     
     private Class loadClass(String typeName) throws ClassNotFoundException {
+        return loadClass(blueprintContext, typeName);
+    }
+    
+    public static Class loadClass(BlueprintContext context, String typeName) throws ClassNotFoundException
{
         if (typeName == null) {
             return null;
         }
 
         Class clazz = primitiveClasses.get(typeName);
         if (clazz == null) {
-            if (blueprintContext == null) {
+            if (context == null) {
                 ClassLoader loader = Thread.currentThread().getContextClassLoader();
                 clazz = loader.loadClass(typeName);
             } else {
-                clazz = blueprintContext.getBundleContext().getBundle().loadClass(typeName);
+                clazz = context.getBundleContext().getBundle().loadClass(typeName);
             }
         }
         return clazz;
     }
+    
+    private static class BeanArgumentComparator implements Comparator<BeanArgument>
{
+        public int compare(BeanArgument object1, BeanArgument object2) {
+            return object1.getIndex() - object2.getIndex();
+        }        
+    }
                 
 }

Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java?rev=768446&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
(added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
Sat Apr 25 01:06:43 2009
@@ -0,0 +1,74 @@
+/**
+ * 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.geronimo.blueprint.utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ArgumentsMatch {
+
+    private Method method;
+    private Constructor constructor;
+    private List<Object> arguments;
+
+    public ArgumentsMatch(Constructor constructor, List<Object> arguments) {
+        this.constructor = constructor;
+        this.arguments = arguments;
+    }
+
+    public ArgumentsMatch(Method method, List<Object> arguments) {
+        this.method = method;
+        this.arguments = arguments;
+    }
+
+    public Constructor getConstructor() {
+        return constructor;
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public Class[] getParameterTypes() {
+        if (constructor != null) {
+            return constructor.getParameterTypes();
+        } else if (method != null) {
+            return method.getParameterTypes();
+        } else {
+            return null;
+        }
+    }
+    
+    public List<Object> getArguments() {
+        return arguments;
+    }
+
+    public String toString() {
+        return method + " " + constructor + " " + arguments;
+    }
+}
+
+

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatch.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java?rev=768446&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
(added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
Sat Apr 25 01:06:43 2009
@@ -0,0 +1,266 @@
+/**
+ * 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.geronimo.blueprint.utils;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.xbean.recipe.Recipe;
+import org.apache.xbean.recipe.RecipeHelper;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ArgumentsMatcher {
+           
+    public enum Option {
+        ARGUMENT_REORDER,
+        STATIC_METHODS_ONLY,
+        INSTANCE_METHODS_ONLY
+    }
+    
+    public static ArgumentsMatch findMethod(Class type, String name, List<Object> arguments,
Set<Option> options) { 
+        List<ArgumentsMatch> matches = new ArrayList<ArgumentsMatch>();
+        Method[] methods = type.getMethods();
+        
+        // look for matching method using the order of arguments specified    
+        for (Method method : methods) {
+            if (method.getName().equals(name) && isAcceptable(method, options)) {
+                Class[] parameterTypes = method.getParameterTypes();
+                if (isAssignable(parameterTypes, arguments)) {
+                    matches.add(new ArgumentsMatch(method, arguments));
+                }
+            }
+        }
+        
+        boolean allowReorder = options.contains(Option.ARGUMENT_REORDER); 
+        if (matches.size() == 0 && allowReorder) {
+            // we did not find any matching method, let's try re-ordering the arguments 
      
+            for (Method method : methods) {
+                if (method.getName().equals(name) && isAcceptable(method, options))
{
+                    Class[] parameterTypes = method.getParameterTypes();                
+                    if (parameterTypes.length == arguments.size()) {   
+                        ArgumentMatcher matcher = new ArgumentMatcher(method);
+                        ArgumentsMatch match = matcher.match(arguments);
+                        if (match != null) {
+                            matches.add(match);
+                        }
+                    }
+                }
+            }
+        }
+        
+        int size = matches.size();
+        if (size == 0) {
+            throw new RuntimeException("Did not find any matching method");
+        } else if (size == 1) {
+            return matches.get(0);
+        } else {
+            throw new RuntimeException("Found multiple matching methods");
+        }
+    }
+       
+    public static ArgumentsMatch findConstructor(Class type, List<Object> arguments,
Set<Option> options) { 
+        List<ArgumentsMatch> matches = new ArrayList<ArgumentsMatch>();
+        Constructor[] constructors = type.getConstructors();
+        
+        // look for matching constructor using the order of arguments specified in config
file                        
+        for (Constructor constructor : constructors) {
+            Class[] parameterTypes = constructor.getParameterTypes();
+            if (isAssignable(parameterTypes, arguments)) {
+                matches.add(new ArgumentsMatch(constructor, arguments));
+            }
+        }
+            
+        boolean allowReorder = options.contains(Option.ARGUMENT_REORDER);
+        if (matches.size() == 0 && allowReorder) {
+            // we did not find any matching constructor, let's try re-ordering the arguments
           
+            for (Constructor constructor : constructors) {
+                Class[] parameterTypes = constructor.getParameterTypes();               
  
+                if (parameterTypes.length == arguments.size()) {   
+                    ArgumentMatcher matcher = new ArgumentMatcher(constructor);
+                    ArgumentsMatch match = matcher.match(arguments);
+                    if (match != null) {
+                        matches.add(match);
+                    }                   
+                }
+            }
+        }
+        
+        int size = matches.size();
+        if (size == 0) {
+            throw new RuntimeException("Did not find any matching constrcutor");
+        } else if (size == 1) {
+            return matches.get(0);
+        } else {
+            throw new RuntimeException("Found multiple matching constructors");
+        }
+    }
+    
+    public static boolean isAssignable(Class[] parameterTypes, List<Object> arguments)
{
+        if (parameterTypes.length == arguments.size()) {
+            boolean assignable = true;
+            for (int i = 0; i < parameterTypes.length && assignable; i++) {
+                assignable = isAssignable(parameterTypes[i], arguments.get(i));
+            }
+            return assignable;
+        }
+        return false;
+    }
+    
+    public static boolean isAssignable(Class type, Object argument) {
+        if (argument == null) {
+            return true;
+        } else if (argument instanceof Recipe) {
+            Recipe recipe = (Recipe) argument;
+            return recipe.canCreate(type);
+        } else {
+            return RecipeHelper.isAssignableFrom(type, argument.getClass());
+        }
+    }
+            
+    private static boolean isAcceptable(Method method, Set<Option> options) {
+        if (options.contains(Option.STATIC_METHODS_ONLY)) {
+            return Modifier.isStatic(method.getModifiers());
+        } else if (options.contains(Option.INSTANCE_METHODS_ONLY)) {
+            return !Modifier.isStatic(method.getModifiers());
+        } else {
+            return true;
+        }
+    }
+    
+    private static class ArgumentMatcher {
+        
+        private List<TypeEntry> entries;
+        private Method method;
+        private Constructor constructor;
+        
+        public ArgumentMatcher(Constructor constructor) {
+            this.constructor = constructor;
+            buildTypes(constructor.getParameterTypes());
+        }
+        
+        public ArgumentMatcher(Method method) {
+            this.method = method;
+            buildTypes(method.getParameterTypes());
+        }
+        
+        private void buildTypes(Class[] types) {
+            entries = new ArrayList<TypeEntry>();
+            for (Class type : types) {
+                entries.add(new TypeEntry(type));
+            }
+        }
+            
+        public Method getMethod() {
+            return method;
+        }
+        
+        public Constructor getConstructor() {
+            return constructor;
+        }
+        
+        public List<Object> getArguments() {
+            List<Object> list = new ArrayList<Object>();
+            for (TypeEntry entry : entries) {
+                Object arg = entry.getArgument();
+                if (arg == null) {
+                    throw new RuntimeException("There are unmatched types");
+                } else {
+                    list.add(arg);
+                }
+            }
+            return list;
+        }
+                
+        public ArgumentsMatch match(List<Object> arguments) {
+            if (find(arguments)) {
+                List<Object> newList = getArguments();        
+                if (constructor != null) {
+                    return new ArgumentsMatch(constructor, newList);
+                } else if (method != null) {
+                    return new ArgumentsMatch(method, newList);                
+                }
+            }
+            return null;
+        }
+        
+        public boolean find(List<Object> arguments) {
+            if (entries.size() == arguments.size()) {
+                boolean matched = true;
+                for (int i = 0; i < arguments.size() && matched; i++) {
+                    matched = find(arguments.get(i));
+                }
+                return matched;
+            }
+            return false;
+        }
+        
+        private boolean find(Object arg) {
+            for (TypeEntry entry : entries) {
+                if (entry.getArgument() == null &&
+                    ArgumentsMatcher.isAssignable(entry.getType(), arg)) {
+                    entry.setArgument(arg);
+                    return true;
+                }
+            }
+            return false;
+        }
+            
+        public boolean isMatched() {
+            for (TypeEntry entry : entries) {
+                if (entry.getArgument() == null) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+         
+    private static class TypeEntry {
+        
+        private Class type;
+        private Object argument;
+        
+        public TypeEntry(Class type) {
+            this.type = type;
+        }
+        
+        public Class getType() {
+            return type;
+        }
+        
+        public void setArgument(Object arg) {
+            this.argument = arg;
+        }
+        
+        public Object getArgument() {
+            return argument;
+        }
+
+    }
+        
+}

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ArgumentsMatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java?rev=768446&r1=768445&r2=768446&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
Sat Apr 25 01:06:43 2009
@@ -136,6 +136,54 @@
         graph.createAll("c", "d");
     }
 
+    public void testConstructor() throws Exception {
+        ComponentDefinitionRegistryImpl registry = parse("/test-constructor.xml");
+        Instanciator i = new TestInstanciator(registry);
+        Repository repository = i.createRepository();
+        ObjectGraph graph = new ObjectGraph(repository);
+        
+        Object obj1 = graph.create("pojoA");
+        assertNotNull(obj1);
+        assertTrue(obj1 instanceof PojoA);
+        PojoA pojoa = (PojoA) obj1;
+        
+        Object obj2 = graph.create("pojoB");
+        assertNotNull(obj2);
+        assertTrue(obj2 instanceof PojoB);
+        PojoB pojob = (PojoB) obj2;
+        
+        assertEquals(URI.create("urn:myuri"), pojob.getUri());
+        assertEquals(10, pojob.getNumber());
+        
+        assertEquals(pojob, pojoa.getPojob());
+        assertEquals(new BigInteger("10"), pojoa.getNumber());
+        
+        Object obj3 = graph.create("pojoC");
+        assertNotNull(obj3);
+        assertTrue(obj3 instanceof PojoB);
+        pojob = (PojoB) obj3;
+        
+        assertEquals(URI.create("urn:myuri-static"), pojob.getUri());
+        assertEquals(15, pojob.getNumber());
+        
+        Object obj4 = graph.create("pojoD");
+        assertNotNull(obj4);
+        assertTrue(obj4 instanceof PojoB);
+        pojob = (PojoB) obj4;
+        
+        assertEquals(URI.create("urn:myuri-static"), pojob.getUri());
+        assertEquals(15, pojob.getNumber());
+        
+        Object obj5 = graph.create("pojoE");
+        assertNotNull(obj5);
+        assertTrue(obj5 instanceof PojoB);
+        pojob = (PojoB) obj5;
+        
+        assertEquals(URI.create("urn:myuri-dynamic"), pojob.getUri());
+        assertEquals(20, pojob.getNumber());
+
+    }
+    
     private static class TestInstanciator extends Instanciator {
         ConversionServiceImpl conversionService = new ConversionServiceImpl();
         ComponentDefinitionRegistryImpl registry;

Modified: geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoB.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoB.java?rev=768446&r1=768445&r2=768446&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoB.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoB.java
Sat Apr 25 01:06:43 2009
@@ -24,12 +24,14 @@
 
     private URI uri;
     private boolean initCalled;
-
+    private int number;
+    
     public PojoB() {
     }
-
-    public PojoB(URI uri) {
+    
+    public PojoB(URI uri, int number) {
         this.uri = uri;
+        this.number = number;
     }
 
     public URI getUri() {
@@ -47,4 +49,16 @@
     public boolean getInitCalled() {
         return initCalled;
     }
+    
+    public int getNumber() {
+        return number;
+    }
+    
+    public static PojoB createStatic(URI uri, int number) {
+        return new PojoB(URI.create(uri + "-static"), number);
+    }
+    
+    public PojoB createDynamic(URI uri, int number) {
+        return new PojoB(URI.create(uri + "-dynamic"), number);
+    }
 }

Added: geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml?rev=768446&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml Sat
Apr 25 01:06:43 2009
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 ../../main/resources/org/apache/geronimo/blueprint/blueprint.xsd"
+            default-availability="mandatory"
+            default-init-method = "init"
+            default-destroy-method = "destroy" >
+
+    <bean id="pojoB" class="org.apache.geronimo.blueprint.pojos.PojoB">
+        <argument value="urn:myuri" />
+        <argument value="10" />
+    </bean>
+    
+    <bean id="pojoA" class="org.apache.geronimo.blueprint.pojos.PojoA">
+        <argument ref="pojoB" />
+        <property name="number">
+            <value type="java.math.BigInteger">10</value>
+        </property>
+    </bean>
+
+    <bean id="pojoC" class="org.apache.geronimo.blueprint.pojos.PojoB" factory-method
= "createStatic" >
+        <argument><value type="int">15</value></argument>
+        <argument value="urn:myuri" />
+    </bean>
+    
+    <bean id="pojoD" class="org.apache.geronimo.blueprint.pojos.PojoB" factory-method
= "createStatic" >
+        <argument value="15" index = "1" />
+        <argument value="urn:myuri" index = "0" />
+    </bean>
+    
+    <!--  TODO: class is not needed when factory-component is specified -->
+    <bean id="pojoE" class="org.apache.geronimo.blueprint.pojos.PojoB" 
+          factory-method = "createDynamic" factory-component = "pojoB" >
+        <argument><value type="int">20</value></argument>
+        <argument value="urn:myuri" />
+    </bean>
+    
+</blueprint>

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml



Mime
View raw message