geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject svn commit: r772671 - in /geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint: ./ context/
Date Thu, 07 May 2009 15:03:20 GMT
Author: gawor
Date: Thu May  7 15:03:19 2009
New Revision: 772671

URL: http://svn.apache.org/viewvc?rev=772671&view=rev
Log:
track service references (top-level and inner) without instantiating recipes

Added:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceTracker.java
  (with props)
Modified:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/SatisfiableRecipe.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/CollectionBasedServiceReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/UnaryServiceReferenceRecipe.java

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/SatisfiableRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/SatisfiableRecipe.java?rev=772671&r1=772670&r2=772671&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/SatisfiableRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/SatisfiableRecipe.java
Thu May  7 15:03:19 2009
@@ -43,6 +43,8 @@
 
     }
 
+    void start();
+    
     boolean isSatisfied();
 
     void registerListener(SatisfactionListener listener);

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=772671&r1=772670&r2=772671&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
Thu May  7 15:03:19 2009
@@ -18,34 +18,35 @@
  */
 package org.apache.geronimo.blueprint.context;
 
-import java.util.List;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Set;
-import java.util.Map;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Collection;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.sf.cglib.proxy.Dispatcher;
+import net.sf.cglib.proxy.Enhancer;
 
-import org.apache.xbean.recipe.AbstractRecipe;
-import org.apache.xbean.recipe.Recipe;
-import org.apache.xbean.recipe.ConstructionException;
-import org.apache.geronimo.blueprint.BlueprintContextEventSender;
 import org.apache.geronimo.blueprint.BlueprintConstants;
+import org.apache.geronimo.blueprint.BlueprintContextEventSender;
 import org.apache.geronimo.blueprint.Destroyable;
 import org.apache.geronimo.blueprint.SatisfiableRecipe;
-import org.apache.geronimo.blueprint.utils.ReflectionUtils;
 import org.apache.geronimo.blueprint.utils.BundleDelegatingClassLoader;
-import org.osgi.service.blueprint.context.BlueprintContext;
-import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
+import org.apache.geronimo.blueprint.utils.ReflectionUtils;
+import org.apache.xbean.recipe.AbstractRecipe;
+import org.apache.xbean.recipe.ConstructionException;
+import org.apache.xbean.recipe.Recipe;
 import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceEvent;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.Dispatcher;
+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;
 
 /**
  * Abstract class for service reference recipes.
@@ -62,9 +63,7 @@
     protected List<Listener> listeners;
     private String filter;
     protected final ClassLoader proxyClassLoader;
-
-    private boolean satisfied;
-    private final List<SatisfactionListener> satisfactionListeners = new CopyOnWriteArrayList<SatisfactionListener>();
+    protected ServiceReferenceTracker tracker;
 
     protected AbstractServiceReferenceRecipe(BlueprintContext blueprintContext,
                                              BlueprintContextEventSender sender,
@@ -78,23 +77,29 @@
         // so that the created proxy can access cglib classes.
         this.proxyClassLoader = new BundleDelegatingClassLoader(blueprintContext.getBundleContext().getBundle(),
                                                                 getClass().getClassLoader());
+        
+        boolean optional = (metadata.getAvailability() == ReferenceMetadata.OPTIONAL_AVAILABILITY);
+        this.tracker = new ServiceReferenceTracker(blueprintContext.getBundleContext(), getOsgiFilter(),
optional);
     }
 
+    public void start() {
+        try {
+            tracker.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public void destroy() {
+        tracker.close();
+    }
+    
     public void registerListener(SatisfactionListener listener) {
-        satisfactionListeners.add(listener);
+        tracker.registerListener(new SatisfactionListenerWrapper(this, listener));
     }
 
     public boolean isSatisfied() {
-        return satisfied;
-    }
-
-    protected final void setSatisfied(boolean satisfied) {
-        if (this.satisfied != satisfied) {
-            this.satisfied = satisfied;
-            for (SatisfactionListener listener : satisfactionListeners) {
-                listener.notifySatisfaction(this);
-            }
-        }
+        return tracker.isSatisfied();
     }
 
     protected String getOsgiFilter() {
@@ -223,6 +228,22 @@
 
     protected abstract void untrack(ServiceReference reference);
 
+    private class SatisfactionListenerWrapper implements ServiceReferenceTracker.SatisfactionListener
{
+
+        SatisfiableRecipe recipe;
+        SatisfiableRecipe.SatisfactionListener listener;
+        
+        public SatisfactionListenerWrapper(SatisfiableRecipe recipe, SatisfiableRecipe.SatisfactionListener
listener) {
+            this.recipe = recipe;
+            this.listener = listener;
+        }
+        
+        public void notifySatisfaction(ServiceReferenceTracker satisfiable) {
+            this.listener.notifySatisfaction(recipe);
+        }
+        
+    }
+    
     public static class Listener {
 
         /* Inject by ObjectRecipe */

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=772671&r1=772670&r2=772671&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
Thu May  7 15:03:19 2009
@@ -205,7 +205,7 @@
                         RecipeBuilder i = new RecipeBuilder(this);
                         Repository repository = i.createRepository(componentDefinitionRegistry);
                         instantiator = new BlueprintObjectInstantiator(repository);
-                        instanciateServiceReferences();
+                        trackServiceReferences();
                         if (checkAllSatisfiables() || !waitForDependencies) {
                             state = State.InitialReferencesSatisfied;
                         } else {
@@ -303,7 +303,7 @@
                 this.beanProcessors.add((BeanProcessor) obj);
             }
         }
-
+        
         // TODO: need to destroy all those objects at the end
     }
 
@@ -351,17 +351,17 @@
         }
     }
 
-    private void instanciateServiceReferences() {
+    private void trackServiceReferences() {
         Map<String, List<SatisfiableRecipe>> dependencies = getSatisfiableDependenciesMap();
         List<String> satisfiables = new ArrayList<String>();
         for (String name : dependencies.keySet()) {
             for (SatisfiableRecipe satisfiable : dependencies.get(name)) {
-                satisfiables.add(satisfiable.getName());
                 satisfiable.registerListener(this);
+                satisfiable.start();
+                satisfiables.add(satisfiable.getName());
             }
         }
-        LOGGER.debug("Instanciating service references: {}", satisfiables);
-        instantiator.createAll(satisfiables);
+        LOGGER.debug("Tracking service references: {}", satisfiables);
     }
 
     private boolean checkAllSatisfiables() {
@@ -416,6 +416,8 @@
                 if (!local.isLazyInit() && BeanMetadata.SCOPE_SINGLETON.equals(scope))
{
                     components.add(name);
                 }
+            } else if (components instanceof ServiceReferenceMetadata) {
+                components.add(name);
             }
         }
         LOGGER.debug("Instantiating components: {}", components);

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=772671&r1=772670&r2=772671&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
Thu May  7 15:03:19 2009
@@ -19,32 +19,32 @@
 package org.apache.geronimo.blueprint.context;
 
 import java.lang.reflect.Type;
+import java.util.AbstractCollection;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Iterator;
 import java.util.RandomAccess;
-import java.util.SortedSet;
 import java.util.Set;
-import java.util.AbstractCollection;
-import java.util.ArrayList;
+import java.util.SortedSet;
 
 import net.sf.cglib.proxy.Dispatcher;
-import org.apache.geronimo.blueprint.Destroyable;
+
 import org.apache.geronimo.blueprint.BlueprintContextEventSender;
-import org.apache.geronimo.blueprint.utils.DynamicSortedList;
+import org.apache.geronimo.blueprint.Destroyable;
+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.DynamicCollection;
 import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.ExecutionContext;
 import org.apache.xbean.recipe.Recipe;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.reflect.RefCollectionMetadata;
 
@@ -58,9 +58,7 @@
 
     private final RefCollectionMetadata metadata;
     private final Recipe comparatorRecipe;
-    private Comparator comparator;
     private ManagedCollection collection;
-    private final boolean optional;
 
     public CollectionBasedServiceReferenceRecipe(BlueprintContext blueprintContext,
                                                  BlueprintContextEventSender sender,
@@ -70,10 +68,6 @@
         super(blueprintContext, sender, metadata, listenersRecipe);
         this.metadata = metadata;
         this.comparatorRecipe = comparatorRecipe;
-        this.optional = metadata.getAvailability() == RefCollectionMetadata.OPTIONAL_AVAILABILITY;
-        if (this.optional) {
-            setSatisfied(true);
-        }
     }
 
     public boolean canCreate(Type type) {
@@ -81,6 +75,7 @@
     }
 
     protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException
{
+        Comparator comparator = null;
         try {
             if (comparatorRecipe != null) {
                 comparator = (Comparator) comparatorRecipe.create(proxyClassLoader);
@@ -114,18 +109,17 @@
             }
 
             // Start tracking the service
-            blueprintContext.getBundleContext().addServiceListener(this, getOsgiFilter());
+            tracker.registerListener(this);
             retrack();
-
+            
             return collection;
         } catch (Throwable t) {
-            t.printStackTrace();
             throw new ConstructionException(t);
         }
     }
-
+    
     public void destroy() {
-        blueprintContext.getBundleContext().removeServiceListener(this);
+        super.destroy();
         List<ServiceDispatcher> dispatchers = new ArrayList<ServiceDispatcher>(collection.getDispatchers());
         for (ServiceDispatcher dispatcher : dispatchers) {
             untrack(dispatcher.reference);
@@ -133,15 +127,11 @@
     }
 
     private void retrack() {
-        try {
-            ServiceReference[] refs = blueprintContext.getBundleContext().getServiceReferences(null,
getOsgiFilter());
-            if (refs != null) {
-                for (ServiceReference ref : refs) {
-                    track(ref);
-                }
+        List<ServiceReference> refs = tracker.getServiceReferences();
+        if (refs != null) {
+            for (ServiceReference ref : refs) {
+                track(ref);
             }
-        } catch (InvalidSyntaxException e) {
-            // Ignore, should never happen
         }
     }
 
@@ -151,9 +141,6 @@
             dispatcher.proxy = createProxy(dispatcher, Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)));
             synchronized (collection) {
                 collection.addDispatcher(dispatcher);
-                if (!optional) {
-                    setSatisfied(!collection.isEmpty());
-                }
             }
             for (Listener listener : listeners) {
                 listener.bind(dispatcher.reference, dispatcher.proxy);
@@ -171,9 +158,6 @@
             }
             synchronized (collection) {
                 collection.removeDispatcher(dispatcher);
-                if (!optional) {
-                    setSatisfied(!collection.isEmpty());
-                }
             }
             dispatcher.destroy();
         }

Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceTracker.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceTracker.java?rev=772671&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceTracker.java
(added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/context/ServiceReferenceTracker.java
Thu May  7 15:03:19 2009
@@ -0,0 +1,206 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author <a href="mailto:dev@geronimo.apache.org">Apache Geronimo Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ServiceReferenceTracker implements ServiceListener {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceReferenceTracker.class);
+    
+    private BundleContext context;
+    private String filter;
+    private boolean optional;
+    private boolean satisfied;
+    private List<ServiceReference> referenceSet;
+    
+    private List<ServiceListener> serviceListeners = new CopyOnWriteArrayList<ServiceListener>();
+    private List<SatisfactionListener> satisfactionListeners = new CopyOnWriteArrayList<SatisfactionListener>();
+    
+    public ServiceReferenceTracker(BundleContext context, String filter, boolean optional)
{   
+        this.context = context;
+        this.filter = filter;
+        this.optional = optional;
+        
+        this.satisfied = false;
+        this.referenceSet = new ArrayList<ServiceReference>();
+    }
+    
+    public synchronized void start() throws InvalidSyntaxException {        
+        context.addServiceListener(this, filter);
+        ServiceReference[] references = context.getServiceReferences(null, filter);
+        if (references != null) {
+            for (ServiceReference reference : references) {
+                referenceSet.add(reference);
+            }
+        }
+        satisfied = (optional) ? true : !referenceSet.isEmpty();       
+    }
+    
+    public void close() {
+        context.removeServiceListener(this);
+        referenceSet.clear();
+        satisfactionListeners.clear();
+    }
+    
+    public boolean isSatisfied() {
+        return satisfied;
+    }
+    
+    public int size() {
+        return referenceSet.size();
+    }
+    
+    public void serviceChanged(ServiceEvent event) {
+        int eventType = event.getType();
+        switch (eventType) {
+            case ServiceEvent.REGISTERED:
+                serviceAdded(event);
+                break;
+            case ServiceEvent.MODIFIED:
+                serviceModified(event);
+                break;
+            case ServiceEvent.UNREGISTERING:
+                serviceRemoved(event);
+                break;
+        }
+    }
+    
+    protected synchronized void serviceAdded(ServiceEvent event) {
+        ServiceReference ref = event.getServiceReference();
+        referenceSet.add(ref);
+        notifyServiceListeners(event);
+        if (!optional) {
+            setSatisfied(true);
+        }
+    }
+    
+    protected synchronized void serviceRemoved(ServiceEvent event) {
+        ServiceReference ref = event.getServiceReference();
+        referenceSet.remove(ref);
+        notifyServiceListeners(event);
+        if (!optional && referenceSet.isEmpty()) {
+            setSatisfied(false);
+        }
+    }
+    
+    protected void serviceModified(ServiceEvent event) { 
+        ServiceReference ref = event.getServiceReference();
+        notifyServiceListeners(event);
+    }
+       
+    protected void setSatisfied(boolean satisfied) {
+        if (this.satisfied != satisfied) {
+            this.satisfied = satisfied;
+            for (SatisfactionListener listener : satisfactionListeners) {
+                listener.notifySatisfaction(this);
+                LOGGER.debug("Service reference with filter {} satisfied {}", filter, this.satisfied);
+            }
+        }
+    }
+    
+    protected void notifyServiceListeners(ServiceEvent event) {
+        for (ServiceListener listener : serviceListeners) {
+            listener.serviceChanged(event);
+        }
+    }
+    
+    public synchronized List<ServiceReference> getServiceReferences() {
+        return new ArrayList<ServiceReference>(referenceSet);
+    }
+    
+    public synchronized ServiceReference getBestServiceReference() {
+        int length = (referenceSet == null) ? 0 : referenceSet.size();
+        if (length == 0) { /* if no service is being tracked */
+            return null;
+        }
+        int index = 0;
+        if (length > 1) { /* if more than one service, select highest ranking */
+            int rankings[] = new int[length];
+            int count = 0;
+            int maxRanking = Integer.MIN_VALUE;
+            for (int i = 0; i < length; i++) {
+                Object property = referenceSet.get(i).getProperty(Constants.SERVICE_RANKING);
+                int ranking = (property instanceof Integer) ? ((Integer) property).intValue()
: 0;
+                rankings[i] = ranking;
+                if (ranking > maxRanking) {
+                    index = i;
+                    maxRanking = ranking;
+                    count = 1;
+                } else {
+                    if (ranking == maxRanking) {
+                        count++;
+                    }
+                }
+            }
+            if (count > 1) { /* if still more than one service, select lowest id */
+                long minId = Long.MAX_VALUE;
+                for (int i = 0; i < length; i++) {
+                    if (rankings[i] == maxRanking) {
+                        long id = ((Long) (referenceSet.get(i).getProperty(Constants.SERVICE_ID))).longValue();
+                        if (id < minId) {
+                            index = i;
+                            minId = id;
+                        }
+                    }
+                }
+            }
+        }
+        return referenceSet.get(index);
+    }
+    
+    public void registerListener(ServiceListener listener) {
+        serviceListeners.add(listener);
+    }
+    
+    public void unregisterListener(ServiceListener listener) {
+        serviceListeners.remove(listener);
+    }
+    
+    public void registerListener(SatisfactionListener listener) {
+        satisfactionListeners.add(listener);
+    }
+    
+    public void unregisterListener(SatisfactionListener listener) {
+        satisfactionListeners.remove(listener);
+    }
+    
+    
+    public interface SatisfactionListener {
+
+        void notifySatisfaction(ServiceReferenceTracker satisfiable);
+
+    }
+}

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

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

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

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=772671&r1=772670&r2=772671&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
Thu May  7 15:03:19 2009
@@ -19,19 +19,16 @@
 package org.apache.geronimo.blueprint.context;
 
 import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
 import java.util.HashSet;
+import java.util.Set;
 
 import net.sf.cglib.proxy.Dispatcher;
+
 import org.apache.geronimo.blueprint.BlueprintContextEventSender;
 import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.ExecutionContext;
 import org.apache.xbean.recipe.Recipe;
-import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Constants;
 import org.osgi.service.blueprint.context.BlueprintContext;
 import org.osgi.service.blueprint.context.ServiceUnavailableException;
 import org.osgi.service.blueprint.reflect.ReferenceMetadata;
@@ -55,7 +52,6 @@
     private volatile ServiceReference trackedServiceReference;
     private volatile Object trackedService;
     private final Object monitor = new Object();
-    private final boolean optional;
 
     public UnaryServiceReferenceRecipe(BlueprintContext blueprintContext,
                                        BlueprintContextEventSender sender,
@@ -63,10 +59,6 @@
                                        Recipe listenersRecipe) {
         super(blueprintContext,  sender, metadata, listenersRecipe);
         this.metadata = metadata;
-        this.optional = metadata.getAvailability() == ReferenceMetadata.OPTIONAL_AVAILABILITY;
-        if (this.optional) {
-            setSatisfied(true);
-        }
     }
 
     protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException
{
@@ -82,13 +74,12 @@
             }
 
             // Start tracking the service
-            blueprintContext.getBundleContext().addServiceListener(this, getOsgiFilter());
+            tracker.registerListener(this);
             retrack();
-
+            
             // Return the object
             return obj;
         } catch (Throwable t) {
-            t.printStackTrace();
             throw new ConstructionException(t);
         }
     }
@@ -96,64 +87,19 @@
     public boolean canCreate(Type type) {
         return true;
     }
-
+    
     public void destroy() {
-        blueprintContext.getBundleContext().removeServiceListener(this);
+        super.destroy();
         unbind();
     }
 
-    private ServiceReference getBestServiceReference(ServiceReference[] references) {
-        int length = (references == null) ? 0 : references.length;
-        if (length == 0) { /* if no service is being tracked */
-            return null;
-        }
-        int index = 0;
-        if (length > 1) { /* if more than one service, select highest ranking */
-            int rankings[] = new int[length];
-            int count = 0;
-            int maxRanking = Integer.MIN_VALUE;
-            for (int i = 0; i < length; i++) {
-                Object property = references[i].getProperty(Constants.SERVICE_RANKING);
-                int ranking = (property instanceof Integer) ? ((Integer) property).intValue()
: 0;
-                rankings[i] = ranking;
-                if (ranking > maxRanking) {
-                    index = i;
-                    maxRanking = ranking;
-                    count = 1;
-                } else {
-                    if (ranking == maxRanking) {
-                        count++;
-                    }
-                }
-            }
-            if (count > 1) { /* if still more than one service, select lowest id */
-                long minId = Long.MAX_VALUE;
-                for (int i = 0; i < length; i++) {
-                    if (rankings[i] == maxRanking) {
-                        long id = ((Long) (references[i].getProperty(Constants.SERVICE_ID))).longValue();
-                        if (id < minId) {
-                            index = i;
-                            minId = id;
-                        }
-                    }
-                }
-            }
-        }
-        return references[index];
-    }
-
     private void retrack() {
         synchronized (monitor) {
-            try {
-                ServiceReference[] refs = blueprintContext.getBundleContext().getServiceReferences(null,
getOsgiFilter());
-                ServiceReference ref = getBestServiceReference(refs);
-                if (ref != null) {
-                    bind(ref);
-                } else {
-                    unbind();
-                }
-            } catch (InvalidSyntaxException e) {
-                // Ignore, should never happen
+            ServiceReference ref = tracker.getBestServiceReference();
+            if (ref != null) {
+                bind(ref);
+            } else {
+                unbind();
             }
         }
     }
@@ -173,12 +119,10 @@
             }
             trackedServiceReference = ref;
             trackedService = blueprintContext.getBundleContext().getService(trackedServiceReference);
+            monitor.notifyAll();
             for (Listener listener : listeners) {
                 listener.bind(trackedServiceReference, trackedService);
             }
-            if (!optional) {
-                setSatisfied(true);
-            }
         }
     }
 
@@ -191,9 +135,6 @@
                 blueprintContext.getBundleContext().ungetService(trackedServiceReference);
                 trackedServiceReference = null;
                 trackedService = null;
-                if (!optional) {
-                    setSatisfied(false);
-                }
             }
         }
     }



Mime
View raw message