geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r776242 [1/2] - in /geronimo/sandbox/blueprint/blueprint-core/src: main/java/org/apache/geronimo/blueprint/ main/java/org/apache/geronimo/blueprint/context/ main/java/org/apache/geronimo/blueprint/utils/ main/java/org/apache/xbean/recipe/ t...
Date Tue, 19 May 2009 08:58:46 GMT
Author: gnodet
Date: Tue May 19 08:58:45 2009
New Revision: 776242

URL: http://svn.apache.org/viewvc?rev=776242&view=rev
Log:
A bit of refactoring on recipes

Added:
    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/xbean/recipe/DefaultRepository.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ValueRecipe.java   (contents, props changed)
      - copied, changed from r775978, geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ValueRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/BeanF.java
Removed:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRepository.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceAccessor.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ValueRecipe.java
Modified:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/ExtendedBlueprintContext.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintContextImpl.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectInstantiator.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleScopeServiceFactory.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/RecipeBuilder.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/TriggerService.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ArrayRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/CollectionRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/DefaultExecutionContext.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ExecutionContext.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/MapRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ObjectGraph.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/Recipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/RecipeHelper.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ReferenceNameRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/ReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
    geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml
    geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-constructor.xml

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/ExtendedBlueprintContext.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/ExtendedBlueprintContext.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/ExtendedBlueprintContext.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/ExtendedBlueprintContext.java Tue May 19 08:58:45 2009
@@ -21,6 +21,7 @@
 import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.reflect.ComponentMetadata;
 import org.osgi.service.blueprint.convert.ConversionService;
+import org.apache.geronimo.blueprint.namespace.ComponentDefinitionRegistryImpl;
 
 /**
  * TODO: javadoc
@@ -36,4 +37,7 @@
 
     <T  extends ComponentMetadata> List<T> getComponentsMetadata(Class<T> type);
 
+    ExtendedComponentDefinitionRegistry getComponentDefinitionRegistry();
+
+    List<BeanProcessor> getBeanProcessors();
 }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/AbstractServiceReferenceRecipe.java Tue May 19 08:58:45 2009
@@ -19,7 +19,6 @@
 package org.apache.geronimo.blueprint.context;
 
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -31,9 +30,9 @@
 
 import net.sf.cglib.proxy.Dispatcher;
 import net.sf.cglib.proxy.Enhancer;
-
 import org.apache.geronimo.blueprint.BlueprintConstants;
 import org.apache.geronimo.blueprint.BlueprintContextEventSender;
+import org.apache.geronimo.blueprint.ExtendedBlueprintContext;
 import org.apache.geronimo.blueprint.SatisfiableRecipe;
 import org.apache.geronimo.blueprint.utils.BundleDelegatingClassLoader;
 import org.apache.geronimo.blueprint.utils.ReflectionUtils;
@@ -44,12 +43,10 @@
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
-import org.osgi.service.blueprint.reflect.Listener;
-import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Abstract class for service reference recipes.
@@ -59,7 +56,7 @@
  */
 public abstract class AbstractServiceReferenceRecipe extends AbstractRecipe implements ServiceListener, SatisfiableRecipe {
 
-    protected final BlueprintContext blueprintContext;
+    protected final ExtendedBlueprintContext blueprintContext;
     protected final BlueprintContextEventSender sender;
     protected final ServiceReferenceMetadata metadata;
     protected final Recipe listenersRecipe;
@@ -69,7 +66,7 @@
     protected ServiceReferenceTracker tracker;
     protected boolean optional;
 
-    protected AbstractServiceReferenceRecipe(BlueprintContext blueprintContext,
+    protected AbstractServiceReferenceRecipe(ExtendedBlueprintContext blueprintContext,
                                              BlueprintContextEventSender sender,
                                              ServiceReferenceMetadata metadata,
                                              Recipe listenersRecipe) {
@@ -157,7 +154,7 @@
 
     protected void createListeners() throws ClassNotFoundException {
         if (listenersRecipe != null) {
-            listeners = (List<Listener>) listenersRecipe.create(proxyClassLoader);
+            listeners = (List<Listener>) listenersRecipe.create();
             for (Listener listener : listeners) {
                 listener.init(getAllClasses(metadata.getInterfaceNames()));
             }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintContextImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintContextImpl.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintContextImpl.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintContextImpl.java Tue May 19 08:58:45 2009
@@ -51,8 +51,9 @@
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.ExecutionContext;
 import org.apache.xbean.recipe.DefaultExecutionContext;
-import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.ReferenceNameRecipe;
+import org.apache.xbean.recipe.ReferenceRecipe;
+import org.apache.xbean.recipe.DefaultRepository;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
@@ -213,7 +214,7 @@
                         state = State.Populated;
                         break;
                     case Populated:
-                        instantiator = new BlueprintObjectInstantiator(new RecipeBuilder(this).createRepository());
+                        instantiator = new BlueprintObjectInstantiator(conversionService, new RecipeBuilder(this).createRepository());
                         checkReferences();
                         trackServiceReferences();
                         timerTask = new TimerTask() {
@@ -247,10 +248,10 @@
                     case InitialReferencesSatisfied:
                         processTypeConverters();
                         processProcessors();
-                        BlueprintObjectRepository repository = (BlueprintObjectRepository) instantiator.getRepository();
-                        BlueprintObjectRepository tmpRepo = new RecipeBuilder(this).createRepository();
+                        DefaultRepository repository = (DefaultRepository) instantiator.getRepository();
+                        DefaultRepository tmpRepo = new RecipeBuilder(this).createRepository();
 
-                        instantiator = new BlueprintObjectInstantiator(new RecipeBuilder(this).createRepository());
+                        instantiator = new BlueprintObjectInstantiator(conversionService, new RecipeBuilder(this).createRepository());
 
                         untrackServiceReferences();
                         for (String name : repository.getNames()) {
@@ -262,7 +263,7 @@
                             }
                         }
                         satisfiables = null;
-                        instantiator = new BlueprintObjectInstantiator(tmpRepo);
+                        instantiator = new BlueprintObjectInstantiator(conversionService, tmpRepo);
                         trackServiceReferences();
                         if (checkAllSatisfiables() || !waitForDependencies) {
                             state = State.InitialReferencesSatisfied2;
@@ -332,11 +333,11 @@
     }
 
     private void checkReferences() throws Exception {
-        BlueprintObjectRepository repository = (BlueprintObjectRepository) instantiator.getRepository();
+        DefaultRepository repository = (DefaultRepository) instantiator.getRepository();
         List<Recipe> recipes = new ArrayList<Recipe>();
         boolean createNewContext = !ExecutionContext.isContextSet();
         if (createNewContext) {
-            ExecutionContext.setContext(new DefaultExecutionContext(instantiator.getRepository()));
+            ExecutionContext.setContext(new DefaultExecutionContext(conversionService, instantiator.getRepository()));
         }
         try {
             for (String name : repository.getNames()) {
@@ -418,12 +419,12 @@
         if (satisfiables == null && instantiator != null) {
             boolean createNewContext = !ExecutionContext.isContextSet();
             if (createNewContext) {
-                ExecutionContext.setContext(new DefaultExecutionContext(instantiator.getRepository()));
+                ExecutionContext.setContext(new DefaultExecutionContext(conversionService, instantiator.getRepository()));
             }
             try {
                 satisfiables = new HashMap<String, List<SatisfiableRecipe>>();
                 for (String name : componentDefinitionRegistry.getComponentDefinitionNames()) {
-                    Recipe r = ((BlueprintObjectRepository) instantiator.getRepository()).getRecipe(name);
+                    Recipe r = ((DefaultRepository) instantiator.getRepository()).getRecipe(name);
                     List<SatisfiableRecipe> recipes = new ArrayList<SatisfiableRecipe>();
                     if (r instanceof SatisfiableRecipe) {
                         recipes.add((SatisfiableRecipe) r);
@@ -548,7 +549,7 @@
 
     private void destroyComponents() {
         if (instantiator != null) {
-            ((BlueprintObjectRepository)instantiator.getRepository()).destroy();
+            ((DefaultRepository)instantiator.getRepository()).destroy();
         }
         
         Map<String, Destroyable> destroyables = new HashMap<String, Destroyable>(this.destroyables);
@@ -675,7 +676,7 @@
         return conversionService;
     }
     
-    protected ComponentDefinitionRegistryImpl getComponentDefinitionRegistry() {
+    public ComponentDefinitionRegistryImpl getComponentDefinitionRegistry() {
         return componentDefinitionRegistry;
     }
         

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectInstantiator.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectInstantiator.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectInstantiator.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectInstantiator.java Tue May 19 08:58:45 2009
@@ -21,6 +21,7 @@
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.List;
 
 import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.DefaultExecutionContext;
@@ -28,14 +29,20 @@
 import org.apache.xbean.recipe.NoSuchObjectException;
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.Repository;
+import org.apache.xbean.recipe.Reference;
+import org.apache.xbean.recipe.UnresolvedReferencesException;
+import org.apache.geronimo.blueprint.utils.ConversionUtils;
+import org.osgi.service.blueprint.convert.ConversionService;
 
 /**
  */
 public class BlueprintObjectInstantiator  {
 
+    private ConversionService conversionService;
     private Repository repository;
 
-    public BlueprintObjectInstantiator(Repository repository) {
+    public BlueprintObjectInstantiator(ConversionService conversionService, Repository repository) {
+        this.conversionService = conversionService;
         this.repository = repository;
     }
     
@@ -58,15 +65,26 @@
             
             boolean createNewContext = !ExecutionContext.isContextSet();
             if (createNewContext) {
-                ExecutionContext.setContext(new DefaultExecutionContext(repository));
+                ExecutionContext.setContext(new DefaultExecutionContext(conversionService, repository));
             }
             
             try {
                 Object obj = createInstance(name);
+                try {
+                    obj = ConversionUtils.convert(obj, Object.class, conversionService);
+                } catch (Exception e) {
+                    throw new ConstructionException("Unable to convert instance " + name, e);
+                }
                 instances.put(name, obj);
             } finally {
                 if (createNewContext) {
+                    ExecutionContext context = ExecutionContext.getContext();
                     ExecutionContext.setContext(null);
+
+                    Map<String, List<Reference>> unresolvedRefs = context.getUnresolvedRefs();
+                    if (!unresolvedRefs.isEmpty()) {
+                        throw new UnresolvedReferencesException(unresolvedRefs);
+                    }
                 }
             }
         }
@@ -80,7 +98,7 @@
         }
         Object obj = recipe;
         if (recipe instanceof Recipe) {
-            obj = ((Recipe) recipe).create(Object.class, false);
+            obj = ((Recipe) recipe).create(false);
         }
         return obj;
     }

Added: 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=776242&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BlueprintObjectRecipe.java Tue May 19 08:58:45 2009
@@ -0,0 +1,796 @@
+/*
+ * 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.context;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Constructor;
+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.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.geronimo.blueprint.BeanProcessor;
+import org.apache.geronimo.blueprint.ExtendedBlueprintContext;
+import org.apache.geronimo.blueprint.ExtendedComponentDefinitionRegistry;
+import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.utils.ReflectionUtils;
+import static org.apache.xbean.recipe.RecipeHelper.toClass;
+import org.apache.xbean.recipe.AbstractRecipe;
+import org.apache.xbean.recipe.Option;
+import org.apache.xbean.recipe.Recipe;
+import org.apache.xbean.recipe.ReferenceRecipe;
+import org.apache.xbean.recipe.ConstructionException;
+
+/**
+ *
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev: 775978 $, $Date: 2009-05-18 16:55:23 +0200 (Mon, 18 May 2009) $
+ */
+public class BlueprintObjectRecipe extends AbstractRecipe {
+
+    private Class typeClass;
+    private final LinkedHashMap<String,Object> properties = new LinkedHashMap<String,Object>();
+    private final EnumSet<Option> options = EnumSet.noneOf(Option.class);
+
+    private boolean keepRecipe = false;
+    private String initMethod;
+    private String destroyMethod;
+    private List<String> explicitDependencies;
+    
+    private Recipe factory; // could be Recipe or actual object
+    private String factoryMethod;
+    private List<Object> arguments;
+    private List<Class> argTypes;
+    private boolean reorderArguments;
+
+    protected ExtendedBlueprintContext blueprintContext;
+
+    public BlueprintObjectRecipe(ExtendedBlueprintContext blueprintContext, Class typeClass) {
+        this.blueprintContext = blueprintContext;
+        this.typeClass = typeClass;
+        allow(Option.LAZY_ASSIGNMENT);
+    }
+
+    public void allow(Option option){
+        options.add(option);
+    }
+
+    public void disallow(Option option){
+        options.remove(option);
+    }
+
+    public Set<Option> getOptions() {
+        return Collections.unmodifiableSet(options);
+    }
+
+    public Object getProperty(String name) {
+        return properties.get(name);
+    }
+
+    public Map<String, Object> getProperties() {
+        return new LinkedHashMap<String, Object>(properties);
+    }
+
+    public void setProperty(String name, Object value) {
+        properties.put(name, value);
+    }
+
+    public void setAllProperties(Map<?,?> map) {
+        if (map == null) throw new NullPointerException("map is null");
+        for (Map.Entry<?, ?> entry : map.entrySet()) {
+            String name = (String) entry.getKey();
+            Object value = entry.getValue();
+            setProperty(name, value);
+        }
+    }
+
+    public void setFactoryMethod(String method) {
+        this.factoryMethod = method;
+    }
+    
+    public void setFactoryComponent(Recipe factory) {
+        this.factory = factory;
+    }
+    
+    public void setArgTypes(List<Class> argTypes) {
+        this.argTypes = argTypes;
+    }
+    
+    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;
+    }
+    
+    public boolean getKeepRecipe() {
+        return keepRecipe;
+    }
+        
+    public void setInitMethod(String initMethod) {
+        this.initMethod = initMethod;
+    }
+    
+    public String getInitMethod() {
+        return initMethod;
+    }
+    
+    public void setDestroyMethod(String destroyMethod) {
+        this.destroyMethod = destroyMethod;
+    }
+    
+    public String getDestroyMethod() {
+        return destroyMethod;
+    }
+
+    public List<String> getExplicitDependencies() {
+        return explicitDependencies;
+    }
+
+    public void setExplicitDependencies(List<String> explicitDependencies) {
+        this.explicitDependencies = explicitDependencies;
+    }
+
+    @Override
+    public List<Recipe> getNestedRecipes() {
+        List<Recipe> recipes = new ArrayList<Recipe>();
+        for (Object o : properties.values()) {
+            if (o instanceof Recipe) {
+                Recipe recipe = (Recipe) o;
+                recipes.add(recipe);
+            }
+        }
+        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; 
+    }
+
+    private void instantiateExplicitDependencies() {
+        if (explicitDependencies != null) {
+            for (String name : explicitDependencies) {
+                Recipe recipe = new ReferenceRecipe(name);
+                recipe.create(false);
+            }
+        }
+    }
+
+    private Object getInstance(boolean refAllowed) throws ConstructionException {
+        Object instance;
+        
+        // Instanciate arguments
+        List<Object> args = new ArrayList<Object>();
+        if (arguments != null) {
+            for (int i = 0; i < arguments.size(); i++) {
+                Object arg = arguments.get(i);
+                if (arg instanceof Recipe) {
+                    args.add(((Recipe) arg).create(refAllowed));
+                } else {
+                    args.add(arg);
+                }
+            }
+        }
+
+        if (factory != null) {
+            // look for instance method on factory object
+            Object factoryObj = factory.create(false);
+            // Map of matching methods
+            Map<Method, List<Object>> matches = findMatchingMethods(factoryObj.getClass(), factoryMethod, true, args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = match.getKey().invoke(factoryObj, match.getValue().toArray());
+                } catch (InvocationTargetException e) {
+                    Throwable root = e.getTargetException();
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), root);
+                } catch (Throwable e) {
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), e);
+                }
+            } else if (matches.size() == 0) {
+                throw new ConstructionException("Unable to find a matching factory method " + factoryMethod + " on class " + factoryObj.getClass() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ConstructionException("Multiple matching factory methods " + factoryMethod + " found on class " + factoryObj.getClass() + " for arguments " + args + " when instanciating bean " + getName());
+            }
+        } else if (factoryMethod != null) {
+            // Map of matching methods
+            Map<Method, List<Object>> matches = findMatchingMethods(getType(), factoryMethod, false, args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = match.getKey().invoke(null, match.getValue().toArray());
+                } catch (InvocationTargetException e) {
+                    Throwable root = e.getTargetException();
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), root);
+                } catch (Throwable e) {
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), e);
+                }
+            } else if (matches.size() == 0) {
+                throw new ConstructionException("Unable to find a matching factory method " + factoryMethod + " on class " + getType() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ConstructionException("Multiple matching factory methods " + factoryMethod + " found on class " + getType() + " for arguments " + args + " when instanciating bean " + getName());
+            }
+        } else {
+            // Map of matching constructors
+            Map<Constructor, List<Object>> matches = findMatchingConstructors(getType(), args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Constructor, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = match.getKey().newInstance(match.getValue().toArray());
+                } catch (InvocationTargetException e) {
+                    Throwable root = e.getTargetException();
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), root);
+                } catch (Throwable e) {
+                    throw new ConstructionException("Error when instanciating bean " + getName() + " of class " + getType(), e);
+                }
+            } else if (matches.size() == 0) {
+                throw new ConstructionException("Unable to find a matching constructor on class " + getType() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ConstructionException("Multiple matching constructors found on class " + getType() + " for arguments " + args + " when instanciating bean " + getName());
+            }
+        }
+        
+        return instance;
+    }
+
+    public static final boolean TCK_COMPLIANCE = true;
+
+    private Map<Method, List<Object>> findMatchingMethods(Class type, String name, boolean instance, List<Object> args, List<Class> types) {
+        Map<Method, List<Object>> matches = new HashMap<Method, List<Object>>();
+        // Get constructors
+        List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods()));
+        // Discard any signature with wrong cardinality
+        for (Iterator<Method> it = methods.iterator(); it.hasNext();) {
+            Method mth = it.next();
+            if (!mth.getName().equals(name)) {
+                it.remove();
+            } else if (mth.getParameterTypes().length != args.size()) {
+                it.remove();
+            } else if (instance ^ !Modifier.isStatic(mth.getModifiers())) {
+                it.remove();
+            }
+        }
+        // Find a direct match with no conversion
+        if (TCK_COMPLIANCE && matches.size() != 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            int bestExactMatch = -1;
+            for (Method mth : methods) {
+                boolean found = true;
+                int exactMatch = 0;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    if (types.get(i) != null) {
+                        if (!mth.getParameterTypes()[i].isAssignableFrom(types.get(i))) {
+                            found = false;
+                            break;
+                        }
+                        if (mth.getParameterTypes()[i] == types.get(i)) {
+                            exactMatch++;
+                        }
+                    } else {
+                        if (!mth.getParameterTypes()[i].isInstance(args.get(i))) {
+                            found = false;
+                            break;
+                        }
+                        if (args.get(i) != null && mth.getParameterTypes()[i] == args.get(i).getClass()) {
+                            exactMatch++;
+                        }
+                    }
+                    try {
+                        Object val = convert(args.get(i), mth.getGenericParameterTypes()[i]);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found && exactMatch >= bestExactMatch) {
+                    if (exactMatch > bestExactMatch) {
+                        bestExactMatch = exactMatch;
+                        nmatches.clear();
+                    }
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Find a direct match
+        if (matches.size() != 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    if (types.get(i) != null && types.get(i) != mth.getParameterTypes()[i]) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        Object val = convert(args.get(i), mth.getGenericParameterTypes()[i]);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering
+        if (matches.size() != 1 && reorderArguments && args.size() > 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                ArgumentMatcher matcher = new ArgumentMatcher(mth.getGenericParameterTypes());
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        return matches;
+    }
+
+    private Map<Constructor, List<Object>> findMatchingConstructors(Class type, List<Object> args, List<Class> types) {
+        Map<Constructor, List<Object>> matches = new HashMap<Constructor, List<Object>>();
+        // Get constructors
+        List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(type.getConstructors()));
+        // Discard any signature with wrong cardinality
+        for (Iterator<Constructor> it = constructors.iterator(); it.hasNext();) {
+            if (it.next().getParameterTypes().length != args.size()) {
+                it.remove();
+            }
+        }
+        // Find a direct match with no conversion
+        if (TCK_COMPLIANCE && matches.size() != 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            int bestExactMatch = -1;
+            for (Constructor cns : constructors) {
+                boolean found = true;
+                int exactMatch = 0;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    if (types.get(i) != null) {
+                        if (!toClass(cns.getParameterTypes()[i]).isAssignableFrom(types.get(i))) {
+                            found = false;
+                            break;
+                        }
+                        if (cns.getParameterTypes()[i] == types.get(i)) {
+                            exactMatch++;
+                        }
+                    } else {
+                        if (!cns.getParameterTypes()[i].isInstance(args.get(i))) {
+                            found = false;
+                            break;
+                        }
+                        if (args.get(i) != null && cns.getParameterTypes()[i] == args.get(i).getClass()) {
+                            exactMatch++;
+                        }
+                    }
+                    try {
+                        Object val = convert(args.get(i), cns.getGenericParameterTypes()[i]);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found && exactMatch >= bestExactMatch) {
+                    if (exactMatch > bestExactMatch) {
+                        bestExactMatch = exactMatch;
+                        nmatches.clear();
+                    }
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Find a direct match
+        if (matches.size() != 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    if (types.get(i) != null && types.get(i) != cns.getParameterTypes()[i]) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        Object val = convert(args.get(i), cns.getGenericParameterTypes()[i]);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering
+        if (matches.size() != 1 && reorderArguments && arguments.size() > 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                ArgumentMatcher matcher = new ArgumentMatcher(cns.getGenericParameterTypes());
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        return matches;
+    }
+
+    /**
+     * Returns init method (if any). Throws exception if the init-method was set explicitly on the bean
+     * and the method is not found on the instance.
+     */
+    protected Method getInitMethod(Object instance) throws ConstructionException {
+        Method method = null;        
+        if (initMethod == null) {
+            ExtendedComponentDefinitionRegistry registry = blueprintContext.getComponentDefinitionRegistry();
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), registry.getDefaultInitMethod());
+        } else if (initMethod.length() > 0) {
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), initMethod);
+            if (method == null) {
+                throw new ConstructionException("Component '" + getName() + "' does not have init-method: " + initMethod);
+            }
+        }
+        return method;
+    }
+
+    /**
+     * Returns destroy method (if any). Throws exception if the destroy-method was set explicitly on the bean
+     * and the method is not found on the instance.
+     */
+    public Method getDestroyMethod(Object instance) throws ConstructionException {
+        Method method = null;        
+        if (destroyMethod == null) {
+            ExtendedComponentDefinitionRegistry registry = blueprintContext.getComponentDefinitionRegistry();
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), registry.getDefaultDestroyMethod());
+        } else if (destroyMethod.length() > 0) {
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), destroyMethod);
+            if (method == null) {
+                throw new ConstructionException("Component '" + getName() + "' does not have destroy-method: " + destroyMethod);
+            }
+        }
+        return method;
+    }
+    
+    @Override
+    public List<Recipe> getConstructorRecipes() {
+        return getNestedRecipes();
+    }
+    
+    @Override
+    protected Object internalCreate(boolean lazyRefAllowed) throws ConstructionException {
+        
+        instantiateExplicitDependencies();
+
+        Object obj = getInstance(lazyRefAllowed);
+                
+        // check for init lifecycle method (if any)
+        Method initMethod = getInitMethod(obj);
+        
+        // check for destroy lifecycle method (if any)
+        getDestroyMethod(obj);
+        
+        if (allowPartial == null) {
+            allowPartial = (initMethod == null);
+        }
+        
+        if (!keepRecipe) {
+            // Add partially created object to the context
+            addObject(obj, true);
+        }
+        
+        // inject properties
+        setProperties(obj);
+
+        for (BeanProcessor processor : blueprintContext.getBeanProcessors()) {
+            obj = processor.beforeInit(obj, getName());
+        }
+        
+        // call init method
+        if (initMethod != null) {
+            try {
+                initMethod.invoke(obj);
+            } catch (InvocationTargetException e) {
+                Throwable root = e.getTargetException();
+                throw new ConstructionException("init-method generated exception", root);
+            } catch (Exception e) {
+                e.printStackTrace(); // TODO: log
+            }
+        }
+        
+        if (!keepRecipe) {
+            // Add fully created object to the context
+            addObject(obj, false);
+        }
+        
+        return obj;
+    }
+    
+    public void destroyInstance(Object obj) {
+        for (BeanProcessor processor : blueprintContext.getBeanProcessors()) {
+            processor.beforeDestroy(obj, getName());
+        }
+        try {
+            Method method = getDestroyMethod(obj);
+            if (method != null) {
+                method.invoke(obj);
+            }
+        } catch (Exception e) {
+            e.printStackTrace(); // TODO: log
+        }
+        for (BeanProcessor processor : blueprintContext.getBeanProcessors()) {
+            processor.afterDestroy(obj, getName());
+        }
+    }
+
+    @Override
+    public Destroyable getDestroyable(Object instance) {
+        Method method = getDestroyMethod(instance);
+        if (method != null) {
+            return new DestroyCallback(method, instance);
+        } else {
+            return null;
+        }
+    }
+
+    public void setProperties(Object instance) throws ConstructionException {
+        // clone the properties so they can be used again
+        Map<String,Object> propertyValues = new LinkedHashMap<String,Object>(properties);
+        setProperties(propertyValues, instance, instance.getClass());
+    }
+
+    public Class getType() {
+        return typeClass;
+    }
+
+    private void setProperties(Map<String, Object> propertyValues, Object instance, Class clazz) {
+        // set remaining properties
+        for (Map.Entry<String, Object> entry : propertyValues.entrySet()) {
+            String propertyName = entry.getKey();
+            Object propertyValue = entry.getValue();
+
+            setProperty(instance, clazz, propertyName, propertyValue);
+        }
+
+    }
+
+    private void setProperty(Object instance, Class clazz, String propertyName, Object propertyValue) {
+        String[] names = propertyName.split("\\.");
+        for (int i = 0; i < names.length - 1; i++) {
+            Method getter = getPropertyDescriptor(clazz, names[i]).getReadMethod();
+            if (getter != null) {
+                try {
+                    instance = getter.invoke(instance);
+                    clazz = instance.getClass();
+                } catch (Exception e) {
+                    Throwable t = e;
+                    if (e instanceof InvocationTargetException) {
+                        InvocationTargetException invocationTargetException = (InvocationTargetException) e;
+                        if (invocationTargetException.getCause() != null) {
+                            t = invocationTargetException.getCause();
+                        }
+                    }
+                    throw new ConstructionException("Error getting property: " + names[i] + " on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName(), t);
+                }
+            } else {
+                throw new ConstructionException("No getter for " + names[i] + " property on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName());
+            }
+        }
+        Method setter = getPropertyDescriptor(clazz, names[names.length - 1]).getWriteMethod();
+        if (setter != null) {
+            // convert the value to type of setter/field
+            Type type = setter.getGenericParameterTypes()[0];
+            // Instanciate value
+            if (propertyValue instanceof Recipe) {
+                propertyValue = ((Recipe) propertyValue).create(false);
+            }
+            try {
+                propertyValue = convert(propertyValue, type);
+            } catch (Exception e) {
+                    String valueType = propertyValue == null ? "null" : propertyValue.getClass().getName();
+                String memberType = type instanceof Class ? ((Class) type).getName() : type.toString();
+                throw new ConstructionException("Unable to convert property value" +
+                        " from " + valueType +
+                        " to " + memberType +
+                        " for injection " + setter, e);
+            }
+            try {
+                // set value
+                setter.invoke(instance, propertyValue);
+            } catch (Exception e) {
+                Throwable t = e;
+                if (e instanceof InvocationTargetException) {
+                    InvocationTargetException invocationTargetException = (InvocationTargetException) e;
+                    if (invocationTargetException.getCause() != null) {
+                        t = invocationTargetException.getCause();
+                    }
+                }
+                throw new ConstructionException("Error setting property: " + setter, t);
+            }
+        } else {
+            throw new ConstructionException("No setter for " + names[names.length - 1] + " property");
+        }
+    }
+
+    PropertyDescriptor getPropertyDescriptor(Class clazz, String name) {
+        // TODO: it seems to fail in some cases, for example if there are two setters and no getters
+        //    it should throw an exception
+        try {
+            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
+            for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) {
+                if (pd.getName().equals(name)) {
+                    return pd;
+                }
+            }
+            throw new ConstructionException("Unable to find property descriptor " + name + " on class " + clazz.getName());
+        } catch (IntrospectionException e) {
+            throw new ConstructionException("Unable to find property descriptor " + name + " on class " + clazz.getName(), e);
+        }
+    }
+
+    private static Object UNMATCHED = new Object();
+
+    private class ArgumentMatcher {
+
+        private List<TypeEntry> entries;
+
+        public ArgumentMatcher(Type[] types) {
+            entries = new ArrayList<TypeEntry>();
+            for (Type type : types) {
+                entries.add(new TypeEntry(type));
+            }
+        }
+
+        public List<Object> match(List<Object> arguments, List<Class> forcedTypes) {
+            if (find(arguments, forcedTypes)) {
+                return getArguments();
+            }
+            return null;
+        }
+
+        private List<Object> getArguments() {
+            List<Object> list = new ArrayList<Object>();
+            for (TypeEntry entry : entries) {
+                if (entry.argument == UNMATCHED) {
+                    throw new RuntimeException("There are unmatched types");
+                } else {
+                    list.add(entry.argument);
+                }
+            }
+            return list;
+        }
+
+        private boolean find(List<Object> arguments, List<Class> forcedTypes) {
+            if (entries.size() == arguments.size()) {
+                boolean matched = true;
+                for (int i = 0; i < arguments.size() && matched; i++) {
+                    matched = find(arguments.get(i), forcedTypes.get(i));
+                }
+                return matched;
+            }
+            return false;
+        }
+
+        private boolean find(Object arg, Class forcedType) {
+            for (TypeEntry entry : entries) {
+                Object val = arg;
+                if (entry.argument != UNMATCHED) {
+                    continue;
+                }
+                if (forcedType != null) {
+                    if (forcedType != entry.type) {
+                        continue;
+                    }
+                } else if (arg != null) {
+                    try {
+                        val = convert(arg, entry.type);
+                    } catch (Throwable t) {
+                        continue;
+                    }
+                }
+                entry.argument = val;
+                return true;
+            }
+            return false;
+        }
+
+    }
+
+    private static class TypeEntry {
+
+        private final Type type;
+        private Object argument;
+
+        public TypeEntry(Type type) {
+            this.type = type;
+            this.argument = UNMATCHED;
+        }
+
+    }
+
+    private static class DestroyCallback implements Destroyable {
+
+        private Method method;
+        private Object instance;
+
+        public DestroyCallback(Method method, Object instance) {
+            this.method = method;
+            this.instance = instance;
+        }
+
+        public void destroy() {
+            try {
+                method.invoke(instance);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+}

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleScopeServiceFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleScopeServiceFactory.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleScopeServiceFactory.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/BundleScopeServiceFactory.java Tue May 19 08:58:45 2009
@@ -26,6 +26,8 @@
 
 import org.apache.xbean.recipe.ObjectGraph;
 import org.apache.xbean.recipe.Repository;
+import org.apache.geronimo.blueprint.context.BlueprintObjectRecipe;
+import org.apache.xbean.recipe.DefaultRepository;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceRegistration;
@@ -74,9 +76,9 @@
   
     private Object createInstance() {
         Repository objectRepository = blueprintContext.getRepository();
-        BlueprintObjectRepository repository = new BlueprintObjectRepository((BlueprintObjectRepository)objectRepository);
+        DefaultRepository repository = new DefaultRepository((DefaultRepository)objectRepository);
         repository.set(serviceRecipe.getName(), serviceRecipe);
-        ObjectGraph graph = new ObjectGraph(repository);
+        ObjectGraph graph = new ObjectGraph(blueprintContext.getConversionService(), repository);
         return graph.create(serviceRecipe.getName());
     }
     

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/CollectionBasedServiceReferenceRecipe.java Tue May 19 08:58:45 2009
@@ -19,6 +19,7 @@
 package org.apache.geronimo.blueprint.context;
 
 import java.lang.reflect.Type;
+import java.lang.reflect.ParameterizedType;
 import java.util.AbstractCollection;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -35,11 +36,13 @@
 
 import org.apache.geronimo.blueprint.BlueprintContextEventSender;
 import org.apache.geronimo.blueprint.Destroyable;
+import org.apache.geronimo.blueprint.ExtendedBlueprintContext;
 import org.apache.geronimo.blueprint.utils.DynamicCollection;
 import org.apache.geronimo.blueprint.utils.DynamicList;
 import org.apache.geronimo.blueprint.utils.DynamicSet;
 import org.apache.geronimo.blueprint.utils.DynamicSortedList;
 import org.apache.geronimo.blueprint.utils.DynamicSortedSet;
+import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.RecipeHelper;
@@ -47,7 +50,10 @@
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.osgi.service.blueprint.context.ComponentDefinitionException;
 import org.osgi.service.blueprint.reflect.RefCollectionMetadata;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
 
 /**
  * A recipe to create a managed collection of service references
@@ -57,11 +63,13 @@
  */
 public class CollectionBasedServiceReferenceRecipe extends AbstractServiceReferenceRecipe {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(CollectionBasedServiceReferenceRecipe.class);
+
     private final RefCollectionMetadata metadata;
     private final Recipe comparatorRecipe;
     private ManagedCollection collection;
 
-    public CollectionBasedServiceReferenceRecipe(BlueprintContext blueprintContext,
+    public CollectionBasedServiceReferenceRecipe(ExtendedBlueprintContext blueprintContext,
                                                  BlueprintContextEventSender sender,
                                                  RefCollectionMetadata metadata,
                                                  Recipe listenersRecipe,
@@ -72,16 +80,23 @@
     }
 
     @Override
-    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(boolean lazyRefAllowed) throws ConstructionException {
         Comparator comparator = null;
         try {
             if (comparatorRecipe != null) {
-                comparator = (Comparator) comparatorRecipe.create(proxyClassLoader);
+                comparator = (Comparator) comparatorRecipe.create();
             } else if (metadata.getOrderingBasis() != 0) {
                 comparator = new NaturalOrderComparator();
             }
             boolean orderReferences = metadata.getOrderingBasis() == RefCollectionMetadata.ORDERING_BASIS_SERVICE_REFERENCE;
-            boolean memberReferences = isReferenceCollection(expectedType) || metadata.getMemberType() == RefCollectionMetadata.MEMBER_TYPE_SERVICE_REFERENCE;
+            Boolean memberReferences;
+            if (metadata.getMemberType() == RefCollectionMetadata.MEMBER_TYPE_SERVICE_REFERENCE) {
+                memberReferences = true;
+            } else if (metadata.getMemberType() == RefCollectionMetadata.MEMBER_TYPE_SERVICE_INSTANCE) {
+                memberReferences = false;
+            } else {
+                memberReferences = null;
+            }
             if (metadata.getCollectionType() == List.class) {
                 if (comparator != null) {
                     collection = new ManagedSortedList(memberReferences, orderReferences, comparator);
@@ -119,20 +134,6 @@
         }
     }
     
-    private boolean isReferenceCollection(Type expectedType) {
-        Class componentType = getComponentType(expectedType);
-        return ServiceReference.class.equals(componentType);
-    }
-    
-    private Class getComponentType(Type expectedType) {
-        Type[] typeParameters = RecipeHelper.getTypeParameters(Collection.class, expectedType);
-        Class componentType = Object.class;
-        if (typeParameters != null && typeParameters.length == 1 && typeParameters[0] instanceof Class) {
-            componentType = (Class) typeParameters[0];
-        }
-        return componentType;
-    }
-    
     public void stop() {
         super.stop();
         if (collection != null) {
@@ -154,7 +155,7 @@
 
     protected void track(ServiceReference reference) {
         try {
-            ServiceDispatcher dispatcher = new ServiceDispatcher(reference, collection.isMemberReferences());
+            ServiceDispatcher dispatcher = new ServiceDispatcher(reference);
             dispatcher.proxy = createProxy(dispatcher, Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)));
             synchronized (collection) {
                 collection.addDispatcher(dispatcher);
@@ -163,7 +164,7 @@
                 listener.bind(dispatcher.reference, dispatcher.proxy);
             }
         } catch (Throwable t) {
-            t.printStackTrace(); // TODO: log
+            LOGGER.info("Error tracking new service reference", t);
         }
     }
 
@@ -189,21 +190,18 @@
     }
 
 
-    public static class ServiceDispatcher implements Dispatcher, Destroyable {
+    public class ServiceDispatcher implements Dispatcher, Destroyable {
 
         public ServiceReference reference;
         public Object service;
         public Object proxy;
         
-        private final boolean memberReference;
-
-        public ServiceDispatcher(ServiceReference reference, boolean memberReference) throws Exception {
+        public ServiceDispatcher(ServiceReference reference) throws Exception {
             this.reference = reference;
-            this.memberReference = memberReference;
         }
 
         public Object getMember() {
-            if (memberReference) {
+            if (collection.isMemberReferences()) {
                 return reference;
             } else {
                 return proxy;
@@ -251,18 +249,55 @@
 
     }
 
-    public static class ManagedCollection extends AbstractCollection {
+    public static class ManagedCollection extends AbstractCollection implements ConversionUtils.Convertible {
 
-        protected final boolean references;
         protected final DynamicCollection<ServiceDispatcher> dispatchers;
+        protected Boolean references;
 
-        public ManagedCollection(boolean references, DynamicCollection<ServiceDispatcher> dispatchers) {
+        public ManagedCollection(Boolean references, DynamicCollection<ServiceDispatcher> dispatchers) {
             this.references = references;
             this.dispatchers = dispatchers;
+            LOGGER.debug("ManagedCollection references={}", references);
+        }
+
+        public Object convert(Type type) {
+            // TODO: consider creating a copy of this managed list with the same back end
+            // TODO: but suited to the requestor needs.  However this would break the contract
+            // TODO: where singletons have only a single instance created
+            LOGGER.debug("Converting ManagedCollection to {}", type);
+            if (Object.class == type) {
+                return this;
+            }
+            if (!Collection.class.isAssignableFrom(RecipeHelper.toClass(type))) {
+                throw new ComponentDefinitionException("<ref-list/> and <ref-set/> can only be converted to other collections, not " + type);
+            }
+            if (RecipeHelper.toClass(type).isInstance(this)) {
+                Boolean useRef = null;
+                if (type instanceof ParameterizedType) {
+                    Type[] args = ((ParameterizedType) type).getActualTypeArguments();
+                    if (args != null && args.length == 1) {
+                        useRef = (args[0] == ServiceReference.class);
+                    }
+                }
+                if (references == null) {
+                    references = useRef != null ? useRef : false;
+                    LOGGER.debug("ManagedCollection references={}", references);
+                } else if (useRef != null && references.booleanValue() != useRef.booleanValue()) {
+                    throw new ComponentDefinitionException("The same <ref-list/> or <ref-set/> can not be " +
+                            "injected as Collection<ServiceReference> and Collection<NotServiceReference> at the same time");
+                }
+                return this;
+            } else {
+                throw new ComponentDefinitionException("Unsupported conversion to " + type);                
+            }
         }
 
         public boolean isMemberReferences() {
-            return references;
+            if (references == null) {
+                references = false;
+            }
+            LOGGER.debug("Retrieving member in ManagedCollection references={}", references);
+            return references.booleanValue();
         }
         
         public boolean addDispatcher(ServiceDispatcher dispatcher) {
@@ -352,11 +387,11 @@
 
         protected DynamicList<ServiceDispatcher> dispatchers;
 
-        public ManagedList(boolean references) {
+        public ManagedList(Boolean references) {
             this(references,  new DynamicList<ServiceDispatcher>());
         }
 
-        protected ManagedList(boolean references, DynamicList<ServiceDispatcher> dispatchers) {
+        protected ManagedList(Boolean references, DynamicList<ServiceDispatcher> dispatchers) {
             super(references, dispatchers);
             this.dispatchers = dispatchers;
         }
@@ -473,7 +508,7 @@
 
     public static class ManagedSortedList extends ManagedList {
 
-        public ManagedSortedList(boolean references, boolean orderingReferences, Comparator comparator) {
+        public ManagedSortedList(Boolean references, boolean orderingReferences, Comparator comparator) {
             super(references, new DynamicSortedList<ServiceDispatcher>(new DispatcherComparator(comparator, orderingReferences)));
         }
 
@@ -481,11 +516,11 @@
 
     public static class ManagedSet extends ManagedCollection implements Set {
 
-        public ManagedSet(boolean references) {
+        public ManagedSet(Boolean references) {
             super(references, new DynamicServiceDispatcherSet());
         }
         
-        protected ManagedSet(boolean references, DynamicSet<ServiceDispatcher> dispatchers) {
+        protected ManagedSet(Boolean references, DynamicSet<ServiceDispatcher> dispatchers) {
             super(references, dispatchers);
         }
         
@@ -510,7 +545,7 @@
         protected final DynamicSortedSet<ServiceDispatcher> dispatchers;
         protected final Comparator comparator;
 
-        public ManagedSortedSet(boolean references, boolean orderingReferences, Comparator comparator) {
+        public ManagedSortedSet(Boolean references, boolean orderingReferences, Comparator comparator) {
             super(references, new DynamicSortedSet<ServiceDispatcher>(new DispatcherComparator(comparator, orderingReferences)));
             this.dispatchers = (DynamicSortedSet<ServiceDispatcher>) super.dispatchers;
             this.comparator =  comparator;

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/Parser.java Tue May 19 08:58:45 2009
@@ -834,8 +834,8 @@
             } else if (MEMBER_TYPE_SERVICE_REFERENCE.equals(memberType)) {
                 references.setMemberType(RefCollectionMetadata.MEMBER_TYPE_SERVICE_REFERENCE);
             }
-        } else {
-            references.setMemberType(RefCollectionMetadata.MEMBER_TYPE_SERVICE_INSTANCE);
+//        } else {
+//            references.setMemberType(RefCollectionMetadata.MEMBER_TYPE_SERVICE_INSTANCE);
         }
         if (element.hasAttribute(ORDERING_BASIS_ATTRIBUTE)) {
             String ordering = element.getAttribute(ORDERING_BASIS_ATTRIBUTE);

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/RecipeBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/RecipeBuilder.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/RecipeBuilder.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/RecipeBuilder.java Tue May 19 08:58:45 2009
@@ -27,6 +27,7 @@
 import java.util.Properties;
 
 import org.apache.geronimo.blueprint.ExtendedComponentDefinitionRegistry;
+import org.apache.geronimo.blueprint.ExtendedBlueprintContext;
 import org.apache.geronimo.blueprint.mutable.MutableMapMetadata;
 import org.apache.geronimo.blueprint.reflect.MetadataUtil;
 import org.apache.xbean.recipe.ArrayRecipe;
@@ -34,7 +35,11 @@
 import org.apache.xbean.recipe.MapRecipe;
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.ReferenceNameRecipe;
-import org.apache.xbean.recipe.Repository;
+import org.apache.xbean.recipe.ConstructionException;
+import org.apache.geronimo.blueprint.context.BlueprintObjectRecipe;
+import org.apache.xbean.recipe.ValueRecipe;
+import org.apache.xbean.recipe.ReferenceRecipe;
+import org.apache.xbean.recipe.DefaultRepository;
 import org.osgi.service.blueprint.convert.ConversionService;
 import org.osgi.service.blueprint.reflect.BeanArgument;
 import org.osgi.service.blueprint.reflect.BeanMetadata;
@@ -85,7 +90,7 @@
         this.registry = blueprintContext.getComponentDefinitionRegistry();
     }
     
-    private void addBuiltinComponents(BlueprintObjectRepository repository) {
+    private void addBuiltinComponents(DefaultRepository repository) {
         if (blueprintContext != null) {
             repository.putDefault("blueprintContext", blueprintContext);
             repository.putDefault("bundleContext", blueprintContext.getBundleContext());
@@ -94,8 +99,8 @@
         }
     }
     
-    public BlueprintObjectRepository createRepository() throws Exception {
-        BlueprintObjectRepository repository = new BlueprintObjectRepository();
+    public DefaultRepository createRepository() throws Exception {
+        DefaultRepository repository = new DefaultRepository();
         addBuiltinComponents(repository);
         
         // Create component recipes
@@ -107,7 +112,7 @@
         return repository;
     }
 
-    private void addRecipe(BlueprintObjectRepository repository, Recipe recipe) {
+    private void addRecipe(DefaultRepository repository, Recipe recipe) {
         repository.add(recipe.getName(), recipe); 
     }
 
@@ -135,7 +140,7 @@
         }
         Recipe comparatorRecipe = null;
         if (metadata.getComparator() != null) {
-            comparatorRecipe = (Recipe) getValue(metadata.getComparator(), Comparator.class);
+            comparatorRecipe = getValue(metadata.getComparator(), Comparator.class);
         }
         CollectionBasedServiceReferenceRecipe recipe = new CollectionBasedServiceReferenceRecipe(
                                                                    blueprintContext,
@@ -230,12 +235,23 @@
                 beanArguments = beanArgumentsCopy;
             }
             List<Object> arguments = new ArrayList<Object>();
+            List<Class> argTypes = new ArrayList<Class>();
             for (BeanArgument argument : beanArguments) {
                 Recipe value = getValue(argument.getValue(), null);
                 arguments.add(value);
+                String valueType = argument.getValueType();
+                if (valueType != null) {
+                    try {
+                        argTypes.add(loadClass(valueType));
+                    } catch (Throwable t) {
+                        throw new ConstructionException("Error loading class " + valueType + " when instanciating bean " + recipe.getName());
+                    }
+                } else {
+                    argTypes.add(null);
+                }
             }
             recipe.setArguments(arguments);
-            recipe.setBeanArguments(beanArguments);
+            recipe.setArgTypes(argTypes);
             recipe.setReorderArguments(!hasIndex);
         }
         recipe.setFactoryMethod(local.getFactoryMethodName());
@@ -283,7 +299,7 @@
             ValueMetadata stringValue = (ValueMetadata) v;
             Class type = loadClass(stringValue.getTypeName());
             type = (type == null) ? groupingType : type;
-            return new ValueRecipe(getConversionService(), stringValue, type);
+            return new ValueRecipe(stringValue, type);
         } else if (v instanceof RefMetadata) {
             // TODO: make it work with property-placeholders?
             String componentName = ((RefMetadata) v).getComponentId();
@@ -293,7 +309,7 @@
             Class cl = collectionMetadata.getCollectionClass();
             Class type = loadClass(collectionMetadata.getValueTypeName());
             if (cl == Object[].class) {
-                ArrayRecipe ar = new ArrayRecipe(getConversionService(), type);
+                ArrayRecipe ar = new ArrayRecipe(type);
                 for (Metadata lv : collectionMetadata.getValues()) {
                     ar.add(getValue(lv, type));
                 }
@@ -350,7 +366,7 @@
         }
     }
         
-    public static Class loadClass(BlueprintContextImpl context, String typeName) throws ClassNotFoundException {
+    public static Class loadClass(ExtendedBlueprintContext context, String typeName) throws ClassNotFoundException {
         if (typeName == null) {
             return null;
         }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/TriggerService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/TriggerService.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/TriggerService.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/TriggerService.java Tue May 19 08:58:45 2009
@@ -85,7 +85,7 @@
             if (recipe == null) {
                 return null;
             } else {
-                return (Map) recipe.create(Map.class, false);
+                return (Map) recipe.create(false);
             }
         } catch (Exception e) {
             LOGGER.debug("Failed to convert MapMetadata to Map", e);

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java Tue May 19 08:58:45 2009
@@ -32,13 +32,14 @@
 import net.sf.cglib.proxy.MethodProxy;
 
 import org.apache.geronimo.blueprint.BlueprintContextEventSender;
+import org.apache.geronimo.blueprint.ExtendedBlueprintContext;
+import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.xbean.recipe.ConstructionException;
-import org.apache.xbean.recipe.ExecutionContext;
 import org.apache.xbean.recipe.Recipe;
 import org.apache.xbean.recipe.RecipeHelper;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.context.ServiceUnavailableException;
+import org.osgi.service.blueprint.context.ComponentDefinitionException;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
 
 /**
@@ -62,7 +63,7 @@
     private volatile Object trackedService;
     private final Object monitor = new Object();
 
-    public UnaryServiceReferenceRecipe(BlueprintContext blueprintContext,
+    public UnaryServiceReferenceRecipe(ExtendedBlueprintContext blueprintContext,
                                        BlueprintContextEventSender sender,
                                        ReferenceMetadata metadata,
                                        Recipe listenersRecipe) {
@@ -71,10 +72,10 @@
     }
 
     @Override
-    protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
+    protected Object internalCreate(boolean lazyRefAllowed) throws ConstructionException {
         try {
             // Create the proxy
-            proxy = createProxy();
+            proxy = createProxy(new ServiceDispatcher(), this.metadata.getInterfaceNames());
             proxyClass = proxy.getClass();
             
             // Add partially created proxy to the context
@@ -89,25 +90,14 @@
             // Start tracking the service
             tracker.registerServiceListener(this);
             retrack();
-            
-            // Return the object
-            Class expectedClass = RecipeHelper.toClass(expectedType);
-            if (ServiceReference.class.equals(expectedClass)) {
-                return getServiceReference();
-            } else {
-                return proxy;
-            }
+
+            // Return a ServiceProxy that can injection of references or proxies can be done correctly
+            return new ServiceProxyWrapper();
         } catch (Throwable t) {
             throw new ConstructionException(t);
         }
     }
 
-    private List<Class> getSupportedTypes() throws ClassNotFoundException {
-        List<Class> list = getAllClasses(metadata.getInterfaceNames());
-        list.add(ServiceReference.class);
-        return list;
-    }
-    
     @Override
     public void stop() {
         super.stop();
@@ -117,23 +107,6 @@
         }
     }
 
-    private Object createProxy() throws Exception {
-        // TODO: we should use the bundle to load classes, not this weird proxyClassLoader
-        // TODO: find another way to handle ServiceReference injection instead of implementing the ServiceReferenceAccessor
-        // TODO: class which may not be available from the bundle classloader
-        Enhancer e = new Enhancer();
-        e.setClassLoader(proxyClassLoader);
-        e.setSuperclass(getTargetClass(metadata.getInterfaceNames()));
-        List<Class> interfaceList = getInterfaces(metadata.getInterfaceNames());
-        interfaceList.add(ServiceReferenceAccessor.class);
-        e.setInterfaces(toClassArray(interfaceList));
-        e.setInterceptDuringConstruction(false);
-        e.setCallbacks(new Callback [] {new ServiceDispatcher(), new ServiceReferenceMethodInterceptor() });
-        e.setCallbackFilter(new ServiceCallbackFilter());
-        e.setUseFactory(false);
-        return e.create();
-    }
-    
     private void retrack() {
         synchronized (monitor) {
             ServiceReference ref = tracker.getBestServiceReference();
@@ -201,15 +174,6 @@
         }
     }
     
-    private ServiceReference getServiceReference() throws InterruptedException {
-        synchronized (monitor) {
-            if (!optional) {
-                getService();
-            }           
-            return trackedServiceReference;
-        }           
-    }
-    
     public class ServiceDispatcher implements Dispatcher {
 
         public Object loadObject() throws Exception {
@@ -217,35 +181,19 @@
         }
 
     }
-    
-    public class ServiceReferenceMethodInterceptor implements MethodInterceptor {
-        
-        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
-            return getServiceReference();
-        }
-        
-    }
-    
-    private static class ServiceCallbackFilter implements CallbackFilter {
 
-        private Method getReferenceMethod;
-        
-        public ServiceCallbackFilter() throws NoSuchMethodException {
-            getReferenceMethod = ServiceReferenceAccessor.class.getMethod("getServiceReference", null);
-        }
-        
-        public int accept(Method method) {
-            if (isGetReferenceMethod(method)) {
-                // use getServiceReference callback
-                return 1;
-            } 
-            // use Dispatcher callback
-            return 0;
-        }
-        
-        private boolean isGetReferenceMethod(Method method) {
-            return getReferenceMethod.equals(method);
+    public class ServiceProxyWrapper implements ConversionUtils.Convertible {
+
+        public Object convert(Type type) throws Exception {
+            if (type == ServiceReference.class) {
+                return trackedServiceReference;
+            } else if (RecipeHelper.toClass(type).isInstance(proxy)) {
+                return proxy;
+            } else {
+                throw new ComponentDefinitionException("Unable to convert to " + type);
+            }
         }
+
     }
-        
+
 }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java Tue May 19 08:58:45 2009
@@ -26,11 +26,8 @@
 import java.util.Map;
 
 import org.osgi.service.blueprint.convert.ConversionService;
-import org.osgi.framework.ServiceReference;
-import org.apache.xbean.recipe.RecipeHelper;
 import static org.apache.xbean.recipe.RecipeHelper.toClass;
 import static org.apache.xbean.recipe.RecipeHelper.getTypeParameters;
-import org.apache.geronimo.blueprint.context.ServiceReferenceAccessor;
 
 /**
  * TODO: javadoc
@@ -42,7 +39,19 @@
 
     private ConversionUtils() { }
 
+    public static interface Convertible {
+
+        Object convert(Type type) throws Exception;
+    }
+
     public static Object convert(Object obj, Type type, ConversionService converter) throws Exception {
+        // First convert service proxies
+        if (obj instanceof Convertible) {
+            Object o = ((Convertible) obj).convert(type);
+            if (o != null) {
+                return o;
+            }
+        }
         // Handle arrays, collections and generics
         if (obj == null) {
             return null;
@@ -101,8 +110,6 @@
                 }
                 return newCol;
             }
-        } else if (type == ServiceReference.class && obj instanceof ServiceReferenceAccessor) {
-            return ((ServiceReferenceAccessor) obj).getServiceReference();
         }
         return converter.convert(obj, toClass(type));
     }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java?rev=776242&r1=776241&r2=776242&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/xbean/recipe/AbstractRecipe.java Tue May 19 08:58:45 2009
@@ -17,21 +17,24 @@
  */
 package org.apache.xbean.recipe;
 
+import java.lang.reflect.Type;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.ArrayList;
 import java.util.concurrent.atomic.AtomicLong;
-import java.lang.reflect.Type;
+
+import org.apache.geronimo.blueprint.Destroyable;
 
 public abstract class AbstractRecipe implements Recipe {
+
     private static final AtomicLong ID = new AtomicLong(1);
-    private long id;
+
+    private final long id;
     private String name;
     protected Boolean allowPartial;
 
     protected AbstractRecipe() {
-        id = ID.getAndIncrement();
+        this.id = ID.getAndIncrement();
     }
 
     public String getName() {
@@ -44,83 +47,34 @@
     }
 
     public Object create() throws ConstructionException {
-        return create(null);
-    }
-
-    public final Object create(ClassLoader classLoader) throws ConstructionException {
-        // if classloader was passed in, set it on the thread
-        ClassLoader oldClassLoader = null;
-        if (classLoader != null) {
-            oldClassLoader = Thread.currentThread().getContextClassLoader();
-            Thread.currentThread().setContextClassLoader(classLoader);
-        }
-
-        try {
-            return create(Object.class, false);
-        } finally {
-            // if we set a thread context class loader, reset it
-            if (classLoader != null) {
-                Thread.currentThread().setContextClassLoader(oldClassLoader);
-            }
-        }
+        return create(false);
     }
 
-    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
-        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
-        if (oldClassLoader == null) {
-            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-        }
+    public final Object create(boolean lazyRefAllowed) throws ConstructionException {
+        // Ensure a context has been set
+        ExecutionContext context = ExecutionContext.getContext();
 
-        // if there is no execution context, create one
-        boolean createNewContext = !ExecutionContext.isContextSet();
-        if (createNewContext) {
-            ExecutionContext.setContext(new DefaultExecutionContext());
+        // if this recipe has already been executed in this context, return the currently registered value
+        String name = getName();
+        if (name != null && context.containsCreatedObject(name)) {
+            return context.getCreatedObject(name);
         }
 
+        // execute the recipe
+        context.push(this);
         try {
-            ExecutionContext context = ExecutionContext.getContext();
-
-            // if this recipe has already been executed in this context, return the currently registered value
-            String name = getName();
-            if (name != null && context.containsCreatedObject(name)) {
-                return context.getCreatedObject(name);
-            }
-
-            // execute the recipe
-            context.push(this);
-            try {
-                return internalCreate(expectedType, lazyRefAllowed);
-            } finally {
-                Recipe popped = context.pop();
-                if (popped != this) {
-                    //noinspection ThrowFromFinallyBlock
-                    throw new IllegalStateException("Internal Error: recipe stack is corrupt:" +
-                            " Expected " + this + " to be popped of the stack but " + popped + " was");
-                }
-            }
+            return internalCreate(lazyRefAllowed);
         } finally {
-            // if we set a new execution context, remove it from the thread
-            if (createNewContext) {
-                ExecutionContext context = ExecutionContext.getContext();
-                ExecutionContext.setContext(null);
-
-                Map<String,List<Reference>> unresolvedRefs = context.getUnresolvedRefs();
-                if (!unresolvedRefs.isEmpty()) {
-                    throw new UnresolvedReferencesException(unresolvedRefs);
-                }
-            }
-
-            // if we set a thread context class loader, clear it
-            if (oldClassLoader == null) {
-                Thread.currentThread().setContextClassLoader(null);
+            Recipe popped = context.pop();
+            if (popped != this) {
+                //noinspection ThrowFromFinallyBlock
+                throw new IllegalStateException("Internal Error: recipe stack is corrupt:" +
+                        " Expected " + this + " to be popped of the stack but " + popped + " was");
             }
         }
     }
 
-    protected abstract Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException;
+    protected abstract Object internalCreate(boolean lazyRefAllowed) throws ConstructionException;
     
     public void setAllowPartial(Boolean allowPartial) {
         this.allowPartial = allowPartial;
@@ -163,4 +117,12 @@
         }
         return string + "@" + id;
     }
+
+    protected Object convert(Object obj, Type type) throws Exception {
+        return ExecutionContext.getContext().convert(obj, type);
+    }
+
+    public Destroyable getDestroyable(Object instance) {
+        return null;
+    }
 }



Mime
View raw message