geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject [02/51] [abbrv] geronimo-yoko git commit: Cache outbound connections with reference counting.
Date Sun, 19 Feb 2017 01:49:19 GMT
http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/PNode.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/PNode.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/PNode.java
new file mode 100644
index 0000000..9ee2fdf
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/PNode.java
@@ -0,0 +1,7 @@
+package org.apache.yoko.util.concurrent;
+
+interface PNode<T> {
+    NNode<T> next();
+    
+    void next(NNode<T> nnode);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/ReferenceCountedCache.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/ReferenceCountedCache.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/ReferenceCountedCache.java
new file mode 100644
index 0000000..b031a3a
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/ReferenceCountedCache.java
@@ -0,0 +1,124 @@
+package org.apache.yoko.util.concurrent;
+
+import org.apache.yoko.util.*;
+
+import java.lang.ref.ReferenceQueue;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+public class ReferenceCountedCache<K, V> implements Cache<K,V> {
+
+    private final ConcurrentMap<K, CountedEntry<K, V>> map = new ConcurrentHashMap<>();
+    private final Fifa<CountedEntry<K, V>> idleEntries = new ConcurrentFifo<>();
+    private volatile int threshold;
+    private volatile int sweep;
+    private final Cleaner<V> cleaner;
+    private final ReferenceQueue<Reference<V>> gcQueue;
+
+    /**
+     * Create a new cache
+     * @param cleaner   the object to use to clean entries
+     * @param threshold the number of values above which to start cleaning up
+     * @param sweep     the number of unused values to clear up
+     */
+    public ReferenceCountedCache(Cleaner<V> cleaner, int threshold, int sweep) {
+        this.threshold = threshold;
+        this.sweep = sweep;
+        this.cleaner = cleaner;
+        gcQueue = new ReferenceQueue<>();
+    }
+
+    @Override
+    public int size() {
+        return map.size();
+    }
+
+    @Override
+    public int idleCount() {
+        return idleEntries.size();
+    }
+
+    @Override
+    public Reference<V> get(K key) {
+        CountedEntry<K, V> entry = map.get(key);
+        if (entry == null) return null;
+        return entry == null ? null : track(entry.obtain());
+    }
+
+    @Override
+    public Reference<V> getOrCreate(K key, KeyedFactory<K, V> valueFactory) {
+        CountedEntry<K,V>.ValueReference result;
+        do {
+            CountedEntry<K, V> entry = map.get(key);
+            if (entry == null) {
+                // try putting a new entry in the map
+                CountedEntry<K, V> newEntry = new CountedEntry<>(key, idleEntries);
+                entry = map.putIfAbsent(key, newEntry);
+                if (entry == null) {
+                    // this thread won the race to create the new entry
+                    V value = null;
+                    try {
+                        value = valueFactory.create(key);
+                        return track(newEntry.setValue(value));
+                    } finally {
+                        if (value == null) {
+                            // create() threw an exception, so clean up
+                            // and make sure no-one else tries to use this entry
+                            newEntry.abort();
+                            map.remove(key, newEntry);
+                        }
+                    }
+                }
+            }
+            result = entry.obtain();
+        } while (result == null); // the entry was cleared - try again
+        return track(result);
+    }
+
+    protected CountedEntry<K,V>.ValueReference track(CountedEntry<K,V>.ValueReference ref) {return ref;}
+
+    @Override
+    public final Reference<V> getOrCreate(K key, final Factory<V> factory) {
+        return getOrCreate(key, new KeyedFactory<K, V>() {
+            @Override
+            public V create(K key) {
+                return factory.create();
+            }
+        });
+    }
+
+    @Override
+    public void remove(Reference<V> ref) {remove(((CountedEntry<K,V>.ValueReference) ref).invalidateAndGetEntry());}
+
+    protected void remove(CountedEntry<K,V> entry) {if (entry != null) map.remove(entry.key, entry);}
+
+    @Override
+    public int clean() {
+        if (size() <= threshold) return 0;
+        int removed = 0;
+        while (removed < sweep) {
+            CountedEntry<K, V> e = idleEntries.peek();
+            if (e == null) break;
+            V clearedValue = e.clear();
+            if (clearedValue == null) continue;
+            if (!!!map.remove(e.key, e))
+                throw new IllegalStateException("Entry already removed");
+            cleaner.clean(clearedValue);
+            removed++;
+        }
+        return removed;
+    }
+
+    @Override
+    public Map<K, V> snapshot() {
+        Map<K, V> result = new HashMap<>();
+        for (Map.Entry<K,CountedEntry<K, V>> entry : map.entrySet()) {
+            try (Reference<V> ref = entry.getValue().obtain()){
+                result.put(entry.getKey(), ref.get());
+            } catch (NullPointerException ignored) {}
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/StrongNode.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/StrongNode.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/StrongNode.java
new file mode 100644
index 0000000..b870ca4
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/StrongNode.java
@@ -0,0 +1,29 @@
+package org.apache.yoko.util.concurrent;
+
+final class StrongNode<T> implements VNode<T> {
+    private final T value;
+    private PNode<T> prev;
+    private NNode<T> next;
+    
+    StrongNode(T value) {this.value = value;}
+    public PNode<T> prev() {return prev;}
+    public NNode<T> next() {return next;}
+    public void prev(PNode<T> pnode) {prev = pnode;}
+    public void next(NNode<T> nnode) {next = nnode;}
+    public T get() {return value;}
+
+    public void insertAfter(PNode<T> pnode) {
+        NNode<T> nnode = pnode.next();
+        this.next = nnode;
+        this.prev = pnode;
+        nnode.prev(this);
+        pnode.next(this);
+    }
+
+    public void delete() {
+        this.prev.next(this.next);
+        this.next.prev(this.prev);
+        this.prev = null;
+        this.next = null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/VNode.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/VNode.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/VNode.java
new file mode 100644
index 0000000..1aef732
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/VNode.java
@@ -0,0 +1,10 @@
+package org.apache.yoko.util.concurrent;
+
+public interface VNode<T> extends PNode<T>, NNode<T> {
+    T get();
+
+    void insertAfter(PNode<T> pnode);
+
+    void delete();
+
+}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakConcurrentFifo.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakConcurrentFifo.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakConcurrentFifo.java
new file mode 100644
index 0000000..3dd9592
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakConcurrentFifo.java
@@ -0,0 +1,73 @@
+package org.apache.yoko.util.concurrent;
+
+import org.apache.yoko.util.KeyedFactory;
+import org.apache.yoko.util.Sequential;
+
+import java.lang.ref.ReferenceQueue;
+
+public class WeakConcurrentFifo<T> extends ConcurrentFifo<T> {
+    private final ReferenceQueue<T> refQueue = new ReferenceQueue<>();
+    private final KeyedFactory<? super T, Runnable> cleanupFactory;
+
+    WeakConcurrentFifo() {
+        this(NoOpRunnableFactory.INSTANCE);
+    }
+
+    WeakConcurrentFifo(KeyedFactory<? super T, Runnable> cleanupFactory) {
+        this.cleanupFactory = cleanupFactory;
+    }
+
+    @Override
+    public int size() {
+        cleanup();
+        return super.size();
+    }
+
+    @Override
+    public T peek() {
+        cleanup();
+        return super.peek();
+    }
+
+    @Override
+    public Place<T> put(T elem) {
+        cleanup();
+        return super.put(elem);
+    }
+
+    @Override
+    public T remove() {
+        cleanup();
+        return super.remove();
+    }
+
+    @Override
+    protected VNode<T> createNode(T elem) {
+        return new WeakNode<>(elem, refQueue, cleanupFactory.create(elem));
+    }
+
+    private void cleanup() {
+        do {
+            @SuppressWarnings("unchecked")
+            WeakNode<T> wn = (WeakNode<T>) refQueue.poll();
+            if (wn == null) return;
+            cleanup(wn);
+        } while (true);
+    }
+
+    private void cleanup(WeakNode<T> wn) {
+        RESPIN: do {
+            PNode<T> prev = wn.prev();
+            if (prev == null) return; // this node is already removed
+            synchronized (prev) {
+                if (wn.prev() != prev) continue RESPIN; // something changed!
+                synchronized (wn) {
+                    wn.delete();
+                    size.decrementAndGet();
+                    wn.cleanup.run();
+                    return;
+                }
+            }
+        } while (true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakCountedCache.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakCountedCache.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakCountedCache.java
new file mode 100644
index 0000000..6c0dffe
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakCountedCache.java
@@ -0,0 +1,35 @@
+package org.apache.yoko.util.concurrent;
+
+import org.apache.yoko.util.KeyedFactory;
+
+public class WeakCountedCache<K, V> extends ReferenceCountedCache<K, V> {
+    private final WeakConcurrentFifo<CountedEntry<K,V>.ValueReference> referenceTracker
+            = new WeakConcurrentFifo<>(new CleanupFactory());
+
+    /**
+     * Create a new cache
+     *
+     * @param cleaner   the object to use to clean entries
+     * @param threshold the number of values above which to start cleaning up
+     * @param sweep     the number of unused values to clear up
+     */
+    public WeakCountedCache(Cleaner<V> cleaner, int threshold, int sweep) {
+        super(cleaner, threshold, sweep);
+    }
+
+    @Override
+    protected CountedEntry<K,V>.ValueReference track(CountedEntry<K,V>.ValueReference ref) {
+        if (ref != null)
+            referenceTracker.put(ref);
+        return ref;
+    }
+
+    private final class CleanupFactory implements KeyedFactory<CountedEntry<K,V>.ValueReference, Runnable> {
+        public Runnable create(CountedEntry<K, V>.ValueReference key) {
+            // Do NOT keep the key around, since this must only be held weakly.
+            // Instead, keep the closer task so we can clean up after the key is collected.
+            // Subsequent calls to close do nothing, so it's safe to run this multiple times.
+            return key.getCloserTask();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakNode.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakNode.java b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakNode.java
new file mode 100644
index 0000000..1235b5f
--- /dev/null
+++ b/yoko-util/src/main/java/org/apache/yoko/util/concurrent/WeakNode.java
@@ -0,0 +1,34 @@
+package org.apache.yoko.util.concurrent;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+final class WeakNode<T> extends WeakReference<T> implements VNode<T> {
+    final Runnable cleanup;
+    private PNode<T> prev;
+    private NNode<T> next;
+
+    WeakNode(T value, ReferenceQueue<T> q, Runnable cleanup) {
+        super(value, q);
+        this.cleanup = cleanup;
+    }
+    public PNode<T> prev() {return prev;}
+    public NNode<T> next() {return next;}
+    public void prev(PNode<T> pnode) {prev = pnode;}
+    public void next(NNode<T> nnode) {next = nnode;}
+
+    public void insertAfter(PNode<T> pnode) {
+        NNode<T> nnode = pnode.next();
+        this.next = nnode;
+        this.prev = pnode;
+        nnode.prev(this);
+        pnode.next(this);
+    }
+
+    public void delete() {
+        this.prev.next(this.next);
+        this.next.prev(this.prev);
+        this.prev = null;
+        this.next = null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderLocator.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderLocator.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderLocator.java
deleted file mode 100644
index dc8fffc..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderLocator.java
+++ /dev/null
@@ -1,583 +0,0 @@
-/**
- * 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.yoko.util.osgi;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-public class ProviderLocator {
-    // a service tracker for the registry service
-    // NB:  This is declared as just Object to avoid classloading issues if we're running
-    // outside of an OSGi environment.
-    static private ProviderRegistry registry;
-
-    private ProviderLocator() {
-        // private constructor to prevent an instance from getting created.
-    }
-
-
-    public static void setRegistry(ProviderRegistry registry) {
-        ProviderLocator.registry = registry;
-    }
-
-    /**
-     * Locate a class by its provider id indicator. .
-     *
-     * @param providerId The provider id (generally, a fully qualified class name).
-     *
-     * @return The Class corresponding to this provider id.  Returns null
-     *         if this is not registered or the indicated class can't be
-     *         loaded.
-     */
-    static public Class<?> locate(String providerId) {
-        ProviderRegistry registry = getRegistry();
-        // if no registry service available, this is a failure
-        if (registry == null) {
-            return null;
-        }
-        // get the service, if it exists.  NB, if there is a service object,
-        // then the extender and the interface class are available, so this cast should be
-        // safe now.
-
-        // the rest of the work is done by the registry
-        return registry.locate(providerId);
-    }
-
-    /**
-     * Locate all class files that match a given factory id.
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the class objects corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located.
-     */
-    static public List<Class<?>> locateAll(String providerId) {
-        Object registry = getRegistry();
-
-        // if no registry service available, this is a failure
-        if (registry == null) {
-            return new ArrayList<Class<?>>();
-        }
-        // get the service, if it exists.  NB, if there is a service object,
-        // then the extender and the interface class are available, so this cast should be
-        // safe now.
-
-        // the rest of the work is done by the registry
-        return ((ProviderRegistry)registry).locateAll(providerId);
-    }
-
-    /**
-     * Utility class for locating a class with OSGi registry
-     * support.  Uses the thread context classloader as part of
-     * the search order.
-     *
-     * @param className The name of the target class.
-     *
-     * @return The loaded class.
-     * @exception ClassNotFoundException
-     *                   Thrown if the class cannot be located.
-     */
-    static public Class<?> loadClass(String className) throws ClassNotFoundException {
-        return loadClass(className, null, Thread.currentThread().getContextClassLoader());
-    }
-
-    /**
-     * Utility class for locating a class with OSGi registry
-     * support.  Uses the thread context classloader as part of
-     * the search order.
-     *
-     * @param className The name of the target class.
-     *
-     * @return The loaded class.
-     * @exception ClassNotFoundException
-     *                   Thrown if the class cannot be located.
-     */
-    static public Class<?> loadClass(String className, Class<?> contextClass) throws ClassNotFoundException {
-        return loadClass(className, contextClass, Thread.currentThread().getContextClassLoader());
-    }
-
-    /**
-     * Standardized utility method for performing class lookups
-     * with support for OSGi registry lookups.
-     *
-     * @param className The name of the target class.
-     * @param loader    An optional class loader.
-     *
-     * @return The loaded class
-     * @exception ClassNotFoundException
-     *                   Thrown if the class cannot be loaded.
-     */
-    static public Class<?> loadClass(String className, Class<?>contextClass, ClassLoader loader) throws ClassNotFoundException {
-        // ideally, this should be last.  However, some of the bundles duplicate classes
-        // found on the boot delegation, so we need to check this first to keep
-        // from picking up one of the default implementations.
-        Class cls = locate(className);
-        if (cls != null) {
-            return cls;
-        }
-
-        if (loader != null) {
-            try {
-                return loader.loadClass(className);
-            } catch (ClassNotFoundException x) {
-            }
-        }
-        if (contextClass != null) {
-            loader = contextClass.getClassLoader();
-        }
-        // try again using the class context loader
-        return Class.forName(className, true, loader);
-    }
-
-
-    /**
-     * Get a single service instance that matches an interface
-     * definition.
-     *
-     * @param iface  The name of the required interface.
-     * @param contextClass
-     *               The class requesting the lookup (used for class resolution).
-     * @param loader A class loader to use for searching for service definitions
-     *               and loading classes.
-     *
-     * @return The service instance, or null if no matching services
-     *         can be found.
-     * @exception Exception Thrown for any classloading or exceptions thrown
-     *                      trying to instantiate a service instance.
-     */
-    static public Object getService(String iface, Class<?> contextClass, ClassLoader loader) throws Exception {
-        // if we are working in an OSGi environment, then process the service
-        // registry first.  Ideally, we would do this last, but because of boot delegation
-        // issues with some API implementations, we must try the OSGi version first
-        Object registry = getRegistry();
-        if (registry != null) {
-            // get the service, if it exists.  NB, if there is a service object,
-            // then the extender and the interface class are available, so this cast should be
-            // safe now.
-            // the rest of the work is done by the registry
-            Object service = ((ProviderRegistry)registry).getService(iface);
-            if (service != null) {
-                return service;
-            }
-        }
-
-        // try for a classpath locatable instance next.  If we find an appropriate class mapping,
-        // create an instance and return it.
-        Class<?> cls = locateServiceClass(iface, contextClass, loader);
-        if (cls != null) {
-            return cls.newInstance();
-        }
-        // a provider was not found
-        return null;
-    }
-
-
-    /**
-     * Locate a service class that matches an interface
-     * definition.
-     *
-     * @param iface  The name of the required interface.
-     * @param contextClass
-     *               The class requesting the lookup (used for class resolution).
-     * @param loader A class loader to use for searching for service definitions
-     *               and loading classes.
-     *
-     * @return The located class, or null if no matching services
-     *         can be found.
-     * @exception Exception Thrown for any classloading exceptions thrown
-     *                      trying to load the class.
-     */
-    static public Class<?> getServiceClass(String iface, Class<?> contextClass, ClassLoader loader) throws ClassNotFoundException {
-        // if we are working in an OSGi environment, then process the service
-        // registry first.  Ideally, we would do this last, but because of boot delegation
-        // issues with some API implementations, we must try the OSGi version first
-        Object registry = getRegistry();
-        if (registry != null) {
-            // get the service, if it exists.  NB, if there is a service object,
-            // then the extender and the interface class are available, so this cast should be
-            // safe now.
-
-            // If we've located stuff in the registry, then return it
-            Class<?> cls = ((ProviderRegistry)registry).getServiceClass(iface);
-            if (cls != null) {
-                return cls;
-            }
-        }
-
-        // try for a classpath locatable instance first.  If we find an appropriate class mapping,
-        // create an instance and return it.
-        return locateServiceClass(iface, contextClass, loader);
-    }
-
-
-    /**
-     * Get a list of services that match a given interface
-     * name.  This searches both the current class path and
-     * the global repository for matches.
-     *
-     * @param iface  The name of the required interface.
-     * @param contextClass
-     *               The class requesting the lookup (used for class resolution).
-     * @param loader A class loader to use for searching for service definitions
-     *               and loading classes.
-     *
-     * @return A list of matching services.  Returns an empty list if there
-     *         are no matches.
-     * @exception Exception Thrown for any classloading or exceptions thrown
-     *                      trying to instantiate a service instance.
-     */
-    static public List<Object> getServices(String iface, Class<?> contextClass, ClassLoader loader) throws Exception {
-        List<Object> services = new ArrayList<Object>();
-
-        // because of boot delegation issues with some of the API implementations, it is necessary
-        // to process the OSGi registered versions first to allow override of JRE provided APIs.
-        Object registry = getRegistry();
-        if (registry != null) {
-            // get the service, if it exists.  NB, if there is a service object,
-            // then the extender and the interface class are available, so this cast should be
-            // safe now.
-            // get any registered service instances now
-            List<Object> globalServices = ((ProviderRegistry)registry).getServices(iface);
-            // add to our list also
-            if (globalServices != null) {
-                services.addAll(globalServices);
-            }
-        }
-
-        // try for a classpath locatable instance second.  If we find an appropriate class mapping,
-        // create an instance and return it.
-        Collection<Class<?>> classes = locateServiceClasses(iface, contextClass, loader);
-        if (classes != null) {
-            // create an instance of each of these classes
-            for (Class<?> cls : classes) {
-                services.add(cls.newInstance());
-            }
-        }
-
-        // now return the merged set
-        return services;
-    }
-
-
-    /**
-     * Get a list of service class implementations that match
-     * an interface name.  This searches both the current class path and
-     * the global repository for matches.
-     *
-     * @param iface  The name of the required interface.
-     * @param contextClass
-     *               The class requesting the lookup (used for class resolution).
-     * @param loader A class loader to use for searching for service definitions
-     *               and loading classes.
-     *
-     * @return A list of matching provider classes.  Returns an empty list if there
-     *         are no matches.
-     * @exception Exception Thrown for any classloading exceptions thrown
-     *                      trying to load a provider class.
-     */
-    static public List<Class<?>> getServiceClasses(String iface, Class<?> contextClass, ClassLoader loader) throws Exception {
-        Set<Class<?>> serviceClasses = new LinkedHashSet<Class<?>>();
-
-        // because of boot delegation issues with some of the API implementations, it is necessary
-        // to process the OSGi registered versions first to allow override of JRE provided APIs.
-        Object registry = getRegistry();
-        if (registry != null) {
-            // get the service, if it exists.  NB, if there is a service object,
-            // then the extender and the interface class are available, so this cast should be
-            // safe now.
-            // get any registered service provider classes now
-            List<Class<?>> globalServices = ((ProviderRegistry)registry).getServiceClasses(iface);
-            // add to our list also
-            if (globalServices != null) {
-                serviceClasses.addAll(globalServices);
-            }
-        }
-
-        // try for a classpath locatable classes second.  If we find an appropriate class mapping,
-        // add this to our return collection.
-        Collection<Class<?>> classes = locateServiceClasses(iface, contextClass, loader);
-        if (classes != null) {
-            serviceClasses.addAll(classes);
-        }
-        // now return the merged set
-        return new ArrayList(serviceClasses);
-    }
-
-
-    /**
-     * Locate the first class name for a META-INF/services definition
-     * of a given class.  The first matching provider is
-     * returned.
-     *
-     * @param iface  The interface class name used for the match.
-     * @param loader The classloader for locating resources.
-     *
-     * @return The mapped provider name, if found.  Returns null if
-     *         no mapping is located.
-     */
-    static private String locateServiceClassName(String iface, Class<?> contextClass, ClassLoader loader) {
-        // search first with the loader class path
-        String name = locateServiceClassName(iface, loader);
-        if (name != null) {
-            return name;
-        }
-        // then with the context class, if there is one
-        if (contextClass != null) {
-            name = locateServiceClassName(iface, contextClass.getClassLoader());
-            if (name != null) {
-                return name;
-            }
-        }
-        // not found
-        return null;
-    }
-
-
-    /**
-     * Locate a classpath-define service mapping.
-     *
-     * @param iface  The required interface name.
-     * @param loader The ClassLoader instance to use to locate the service.
-     *
-     * @return The mapped class name, if one is found.  Returns null if the
-     *         mapping is not located.
-     */
-    static private String locateServiceClassName(String iface, ClassLoader loader) {
-        if (loader != null) {
-            try {
-                // we only look at resources that match the file name, using the specified loader
-                String service = "META-INF/services/" + iface;
-                Enumeration<URL> providers = loader.getResources(service);
-
-                while (providers.hasMoreElements()) {
-                    List<String>providerNames = parseServiceDefinition(providers.nextElement());
-                    // if there is something defined here, return the first entry
-                    if (!providerNames.isEmpty()) {
-                        return providerNames.get(0);
-                    }
-                }
-            } catch (IOException e) {
-            }
-        }
-        // not found
-        return null;
-    }
-
-
-    /**
-     * Locate the first class for a META-INF/services definition
-     * of a given interface class.  The first matching provider is
-     * returned.
-     *
-     * @param iface  The interface class name used for the match.
-     * @param loader The classloader for locating resources.
-     *
-     * @return The mapped provider class, if found.  Returns null if
-     *         no mapping is located.
-     */
-    static private Class<?> locateServiceClass(String iface, Class<?> contextClass, ClassLoader loader) throws ClassNotFoundException {
-        String className = locateServiceClassName(iface, contextClass, loader);
-        if (className == null) {
-            return null;
-        }
-
-        // we found a name, try loading the class.  This will throw an exception if there is an error
-        return loadClass(className, contextClass, loader);
-    }
-
-
-    /**
-     * Locate all class names name for a META-INF/services definition
-     * of a given class.
-     *
-     * @param iface  The interface class name used for the match.
-     * @param loader The classloader for locating resources.
-     *
-     * @return The mapped provider name, if found.  Returns null if
-     *         no mapping is located.
-     */
-    static private Collection<String> locateServiceClassNames(String iface, Class<?> contextClass, ClassLoader loader) {
-        Set<String> names = new LinkedHashSet<String>();
-
-        locateServiceClassNames(iface, loader, names);
-        if (contextClass != null) {
-            locateServiceClassNames(iface, contextClass.getClassLoader(), names);
-        }
-
-        return names;
-    }
-
-
-    /**
-     * Locate all class names name for a META-INF/services definition
-     * of a given class.
-     *
-     * @param iface  The interface class name used for the match.
-     * @param loader The classloader for locating resources.
-     *
-     * @return The mapped provider name, if found.  Returns null if
-     *         no mapping is located.
-     */
-    static void locateServiceClassNames(String iface, ClassLoader loader, Set names) {
-        if (loader != null) {
-
-            try {
-                // we only look at resources that match the file name, using the specified loader
-                String service = "META-INF/services/" + iface;
-                Enumeration<URL> providers = loader.getResources(service);
-
-                while (providers.hasMoreElements()) {
-                    List<String>providerNames = parseServiceDefinition(providers.nextElement());
-                    // just add all of these to the list
-                    names.addAll(providerNames);
-                }
-            } catch (IOException e) {
-            }
-        }
-    }
-
-
-    /**
-     * Locate all classes that map to a given provider class definition.  This will
-     * search both the services directories, as well as the provider classes from the
-     * OSGi provider registry.
-     *
-     * @param iface  The interface class name used for the match.
-     * @param loader The classloader for locating resources.
-     *
-     * @return A list of all mapped classes, if found.  Returns an empty list if
-     *         no mappings are found.
-     */
-    static private Collection<Class<?>> locateServiceClasses(String iface, Class<?> contextClass, ClassLoader loader) throws ClassNotFoundException {
-        // get the set of names from services definitions on the classpath
-        Collection<String> classNames = locateServiceClassNames(iface, contextClass, loader);
-        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
-
-        // load each class and add to our return set
-        for (String name : classNames) {
-            classes.add(loadClass(name, contextClass, loader));
-        }
-        return classes;
-    }
-
-
-    /**
-     * Parse a definition file and return the names of all included implementation classes
-     * contained within the file.
-     *
-     * @param u      The URL of the file
-     *
-     * @return A list of all matching classes.  Returns an empty list
-     *         if no matches are found.
-     */
-    static private List<String> parseServiceDefinition(URL u) {
-        final String url = u.toString();
-        List<String> classes = new ArrayList<String>();
-        // ignore directories
-        if (url.endsWith("/")) {
-            return classes;
-        }
-        // the identifier used for the provider is the last item in the URL.
-        final String providerId = url.substring(url.lastIndexOf("/") + 1);
-        try {
-            BufferedReader br = new BufferedReader(new InputStreamReader(u.openStream(), "UTF-8"));
-            // the file can be multiple lines long, with comments.  A single file can define multiple providers
-            // for a single key, so we might need to create multiple entries.  If the file does not contain any
-            // definition lines, then as a default, we use the providerId as an implementation class also.
-            String line = br.readLine();
-            while (line != null) {
-                // we allow comments on these lines, and a line can be all comment
-                int comment = line.indexOf('#');
-                if (comment != -1) {
-                    line = line.substring(0, comment);
-                }
-                line = line.trim();
-                // if there is nothing left on the line after stripping white space and comments, skip this
-                if (line.length() > 0) {
-                    // add this to our list
-                    classes.add(line);
-                }
-                // keep reading until the end.
-                line = br.readLine();
-            }
-            br.close();
-        } catch (IOException e) {
-            // ignore errors and handle as default
-        }
-        return classes;
-    }
-
-    /**
-     * Perform a service class discovery by looking for a
-     * property in a target properties file located in the
-     * java.home directory.
-     *
-     * @param path     The relative path to the desired properties file.
-     * @param property The name of the required property.
-     *
-     * @return The value of the named property within the properties file.  Returns
-     *         null if the property doesn't exist or the properties file doesn't exist.
-     */
-    public static String lookupByJREPropertyFile(String path, String property) throws IOException {
-        String jreDirectory = System.getProperty("java.home");
-        File configurationFile = new File(jreDirectory + File.separator + path);
-        if (configurationFile.exists() && configurationFile.canRead()) {
-            Properties properties = new Properties();
-            InputStream in = null;
-            try {
-                in = new FileInputStream(configurationFile);
-                properties.load(in);
-                return properties.getProperty(property);
-            } finally {
-                if (in != null) {
-                    try {
-                        in.close();
-                    } catch (Exception e) {
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-
-    /**
-     * Retrieve the registry from the tracker if it is available,
-     * all without causing the interface class to load.
-     *
-     * @return The registry service instance, or null if it is not
-     *         available for any reason.
-     */
-    private static ProviderRegistry getRegistry() {
-        return registry;
-    }
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderRegistry.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderRegistry.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderRegistry.java
deleted file mode 100644
index 8978c2f..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/ProviderRegistry.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * 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.yoko.util.osgi;
-
-import java.util.List;
-
-/**
- * The implementation of the factory registry used to store
- * the bundle registrations.
- */
-public interface ProviderRegistry {
-    /**
-     * Locate a class by its factory id indicator. .
-     *
-     * @param factoryId The factory id (generally, a fully qualified class name).
-     *
-     * @return The Class corresponding to this factory id.  Returns null
-     *         if this is not registered or the indicated class can't be
-     *         loaded.
-     */
-    public Class<?> locate(String factoryId);
-
-    /**
-     * Locate all class files that match a given factory id.
-     *
-     * @param factoryId The target factory identifier.
-     *
-     * @return A List containing the class objects corresponding to the
-     *         factory identifier.  Returns an empty list if no
-     *         matching classes can be located.
-     */
-    public List<Class<?>> locateAll(String factoryId);
-
-
-    /**
-     * Locate and instantiate an instance of a service provider
-     * defined in the META-INF/services directory of tracked bundles.
-     *
-     * @param providerId The name of the target interface class.
-     *
-     * @return The service instance.  Returns null if no service defintions
-     *         can be located.
-     * @exception Exception Any classloading or other exceptions thrown during
-     *                      the process of creating this service instance.
-     */
-    public Object getService(String providerId) throws Exception;
-
-    /**
-     * Locate all services that match a given provider id and create instances.
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the instances corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located or created
-     */
-    public List<Object> getServices(String providerId);
-
-
-    /**
-     * Locate and return the class for a service provider
-     * defined in the META-INF/services directory of tracked bundles.
-     *
-     * @param providerId The name of the target interface class.
-     *
-     * @return The provider class.   Returns null if no service defintions
-     *         can be located.
-     * @exception Exception Any classloading or other exceptions thrown during
-     *                      the process of loading this service provider class.
-     */
-    public Class<?> getServiceClass(String providerId) throws ClassNotFoundException;
-
-
-    /**
-     * Locate all services that match a given provider id and return the implementation
-     * classes
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the classes corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located.
-     */
-    public List<Class<?>> getServiceClasses(String providerId);
-
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/BundleProviderLoader.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/BundleProviderLoader.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/BundleProviderLoader.java
deleted file mode 100644
index ec50364..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/BundleProviderLoader.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.yoko.util.osgi.locator;
-
-import org.osgi.framework.Bundle;
-
-/**
- * Holder class for located services information.
- */
-public class BundleProviderLoader implements Comparable<BundleProviderLoader> {
-    // the class name for this provider
-    private final String providerId;
-    // the mapped class name of the provider.
-    private final String providerClass;
-    // the hosting bundle.
-    private final Bundle bundle;
-
-    private final int priority;
-
-    /**
-     * Create a loader for this registered provider.
-     *
-     * @param providerId The provider ID
-     * @param providerClass The mapped class name of the provider.
-     * @param bundle    The hosting bundle.
-     * @param priority
-     */
-    public BundleProviderLoader(String providerId, String providerClass, Bundle bundle, int priority) {
-        this.providerId = providerId;
-        this.providerClass = providerClass;
-        this.bundle = bundle;
-        this.priority = priority;
-    }
-
-    /**
-     * Load a provider class.
-     *
-     * @return The provider class from the target bundle.
-     * @exception Exception
-     */
-    public Class<?> loadClass() throws ClassNotFoundException {
-        try {
-//                log(LogService.LOG_DEBUG, "loading class for: " + this);
-            return bundle.loadClass(providerClass);
-        } catch (ClassNotFoundException e) {
-//                log(LogService.LOG_DEBUG, "exception caught while loading " + this, e);
-            throw e;
-        }
-    }
-
-    /**
-     * Create an instance of the registred service.
-     *
-     * @return The created instance.  A new instance is created on each call.
-     * @exception Exception
-     */
-    public Object createInstance() throws Exception {
-        // get the class object
-        Class <?> cls = loadClass();
-        try {
-            // just create an instance using the default constructor
-            return cls.newInstance();
-        } catch (Exception e) {
-//                log(LogService.LOG_DEBUG, "exception caught while creating " + this, e);
-            throw e;
-        } catch (Error e) {
-//                log(LogService.LOG_DEBUG, "error caught while creating " + this, e);
-            throw e;
-        }
-    }
-
-
-    public String id() {
-        return providerId;
-    }
-
-    @Override
-    public String toString() {
-        return "Provider interface=" + providerId + " , provider class=" + providerClass + ", bundle=" + bundle;
-    }
-
-    @Override
-    public int hashCode() {
-        return providerId.hashCode() + providerClass.hashCode() + (int)bundle.getBundleId();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof BundleProviderLoader) {
-            return providerId.equals(((BundleProviderLoader)obj).providerId) &&
-                   providerClass.equals(((BundleProviderLoader)obj).providerClass) &&
-                   bundle.getBundleId() == ((BundleProviderLoader)obj).bundle.getBundleId();
-        } else {
-            return false;
-        }
-    }
-
-    public int compareTo(BundleProviderLoader other) {
-        return other.priority - priority;
-    }
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderBean.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderBean.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderBean.java
deleted file mode 100644
index f2271f9..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderBean.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.yoko.util.osgi.locator;
-
-import java.util.logging.Logger;
-
-import org.osgi.framework.Bundle;
-
-/**
- * @version $Rev$ $Date$
- */
-public class ProviderBean {
-    private static final Logger log = Logger.getLogger(ProviderBean.class.getName());
-
-    private Register providerRegistry;
-
-    private BundleProviderLoader bundleProviderLoader;
-
-    public ProviderBean(String key,
-                       String className,
-                       Bundle bundle,
-                       Register providerRegistry) {
-        this(key, className, bundle, providerRegistry, -1);
-    }
-
-    public ProviderBean(String key,
-                        String className,
-                        Bundle bundle,
-                        Register providerRegistry,
-                        Integer priority) {
-        bundleProviderLoader = new BundleProviderLoader(key, className, bundle, priority == null? -1: priority);
-        log.finer("ProviderBean: " + bundleProviderLoader);
-        this.providerRegistry = providerRegistry;
-    }
-
-
-
-    public void start() {
-        providerRegistry.registerProvider(bundleProviderLoader);
-    }
-
-    public void stop() {
-        providerRegistry.unregisterProvider(bundleProviderLoader);
-    }
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderRegistryImpl.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderRegistryImpl.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderRegistryImpl.java
deleted file mode 100644
index 7a1feec..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ProviderRegistryImpl.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/**
- * 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.yoko.util.osgi.locator;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.yoko.util.osgi.ProviderLocator;
-
-/**
- * The implementation of the provider registry used to store
- * the bundle registrations.
- */
-public class ProviderRegistryImpl implements org.apache.yoko.util.osgi.ProviderRegistry, Register {
-
-    private static final Logger log = Logger.getLogger(ProviderRegistryImpl.class.getName());
-    // our mapping between a provider id and the implementation information.  There
-    // might be a one-to-many relationship between the ids and implementing classes.
-    private SPIRegistry providers = new SPIRegistry();
-    // our mapping between an interface name and a META-INF/services SPI implementation.  There
-    // might be a one-to-many relationship between the ids and implementing classes.
-    private SPIRegistry serviceProviders = new SPIRegistry();
-
-    public void start() {
-        ProviderLocator.setRegistry(this);
-    }
-
-    public void stop() {
-        ProviderLocator.setRegistry(null);
-    }
-
-    /**
-     * Register an individual provivider item by its provider identifier.
-     *
-     * @param provider The loader used to resolve the provider class.
-     */
-    public void registerProvider(BundleProviderLoader provider) {
-        log(Level.FINE, "registering provider " + provider);
-        providers.register(provider);
-    }
-
-    /**
-     * Removed a provider registration for a named provider id.
-     *
-     * @param provider The provider registration instance
-     */
-    public void unregisterProvider(BundleProviderLoader provider) {
-        log(Level.FINE, "unregistering provider " + provider);
-        providers.unregister(provider);
-    }
-
-
-    /**
-     * Register an individual provivider item by its provider identifier.
-     *
-     * @param provider The loader used to resolve the provider class.
-     */
-    public void registerService(BundleProviderLoader provider) {
-        log(Level.FINE, "registering service " + provider);
-        serviceProviders.register(provider);
-    }
-
-    /**
-     * Removed a provider registration for a named provider id.
-     *
-     * @param provider The provider registration instance
-     */
-    public void unregisterService(BundleProviderLoader provider) {
-        log(Level.FINE, "unregistering service " + provider);
-        serviceProviders.unregister(provider);
-    }
-
-    /**
-     * Locate a class by its provider id indicator. .
-     *
-     * @param providerId The provider id (generally, a fully qualified class name).
-     *
-     * @return The Class corresponding to this provider id.  Returns null
-     *         if this is not registered or the indicated class can't be
-     *         loaded.
-     */
-    public Class<?> locate(String providerId) {
-        // see if we have a registered match for this...getting just the first instance
-        BundleProviderLoader loader = providers.getLoader(providerId);
-        if (loader != null) {
-            try {
-                // try to load this.  We always return null
-                return loader.loadClass();
-            } catch (Exception e) {
-                e.printStackTrace();
-                // just swallow this and return null.  The exception has already
-                // been logged.
-            }
-        }
-        // no match to return
-        return null;
-    }
-
-    /**
-     * Locate all class files that match a given provider id.
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the class objects corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located.
-     */
-    public List<Class<?>> locateAll(String providerId) {
-        List<Class<?>> classes = new ArrayList<Class<?>>();
-        List<BundleProviderLoader> l = providers.getLoaders(providerId);
-        // this returns null if nothing is found.
-        if (l != null) {
-            for (BundleProviderLoader c : l) {
-                try {
-                    classes.add(c.loadClass());
-                } catch (Exception e) {
-                    // just swallow this and proceed to the next.  The exception has
-                    // already been logged.
-                }
-            }
-        }
-        return classes;
-    }
-
-    /**
-     * Locate and instantiate an instance of a service provider
-     * defined in the META-INF/services directory of tracked bundles.
-     *
-     * @param providerId The name of the target interface class.
-     *
-     * @return The service instance.  Returns null if no service defintions
-     *         can be located.
-     * @exception Exception Any classloading or other exceptions thrown during
-     *                      the process of creating this service instance.
-     */
-    public Object getService(String providerId) throws Exception {
-        // see if we have a registered match for this...getting just the first instance
-        BundleProviderLoader loader = serviceProviders.getLoader(providerId);
-        if (loader != null) {
-            // try to load this and create an instance.  Any/all exceptions get
-            // thrown here
-            return loader.createInstance();
-        }
-        // no match to return
-        return null;
-    }
-
-    /**
-     * Locate all services that match a given provider id and create instances.
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the instances corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located or created
-     */
-    public List<Object> getServices(String providerId) {
-        List<Object> instances = new ArrayList<Object>();
-        List<BundleProviderLoader> l = serviceProviders.getLoaders(providerId);
-        // this returns null for nothing found
-        if (l != null) {
-            for (BundleProviderLoader c : l) {
-                try {
-                    instances.add(c.createInstance());
-                } catch (Exception e) {
-                    // just swallow this and proceed to the next.  The exception has
-                    // already been logged.
-                }
-            }
-        }
-        return instances;
-    }
-
-    /**
-     * Locate all services that match a given provider id and return the implementation
-     * classes
-     *
-     * @param providerId The target provider identifier.
-     *
-     * @return A List containing the classes corresponding to the
-     *         provider identifier.  Returns an empty list if no
-     *         matching classes can be located.
-     */
-    public List<Class<?>> getServiceClasses(String providerId) {
-        List<Class<?>> classes = new ArrayList<Class<?>>();
-        List<BundleProviderLoader> l = serviceProviders.getLoaders(providerId);
-        // this returns null for nothing found
-        if (l != null) {
-            for (BundleProviderLoader c : l) {
-                try {
-                    classes.add(c.loadClass());
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    // just swallow this and proceed to the next.  The exception has
-                    // already been logged.
-                }
-            }
-        }
-        return classes;
-    }
-
-    /**
-     * Locate and return the class for a service provider
-     * defined in the META-INF/services directory of tracked bundles.
-     *
-     * @param providerId The name of the target interface class.
-     *
-     * @return The provider class.   Returns null if no service defintions
-     *         can be located.
-     * @exception ClassNotFoundException Any classloading or other exceptions thrown during
-     *                      the process of loading this service provider class.
-     */
-    public Class<?> getServiceClass(String providerId) throws ClassNotFoundException {
-        // see if we have a registered match for this...getting just the first instance
-        BundleProviderLoader loader = serviceProviders.getLoader(providerId);
-        if (loader != null) {
-            // try to load this and create an instance.  Any/all exceptions get
-            // thrown here
-            return loader.loadClass();
-        }
-        // no match to return
-        return null;
-    }
-
-    private void log(Level level, String message) {
-        log.log(level, message);
-    }
-
-    /**
-     * Holder class for information about a given collection of
-     * id to provider mappings.  Used for both the providers and
-     * the services.
-     */
-    private class SPIRegistry {
-        private Map<String, List<BundleProviderLoader>> registry;
-
-
-        /**
-         * Register an individual provivider item by its provider identifier.
-         *
-         * @param provider The loader used to resolve the provider class.
-         */
-        public synchronized void register(BundleProviderLoader provider) {
-            // if this is the first registration, create the mapping table
-            if (registry == null) {
-                registry = new HashMap<String, List<BundleProviderLoader>>();
-            }
-
-            String providerId = provider.id();
-
-            // the providers are stored as a list...we use the first one registered
-            // when asked to locate.
-            List<BundleProviderLoader> l = registry.get(providerId);
-            if (l ==  null) {
-                l = new ArrayList<BundleProviderLoader>(2);
-                registry.put(providerId, l);
-            }
-            l.add(provider);
-            Collections.sort(l);
-        }
-
-        /**
-         * Remove a provider registration for a named provider id.
-         *
-         * @param provider The provider registration instance
-         */
-        public synchronized void unregister(BundleProviderLoader provider) {
-            if (registry != null) {
-                // this is stored as a list.  Just remove using the registration information
-                // This may move a different provider to the front of the list.
-                List<BundleProviderLoader> l = registry.get(provider.id());
-                if (l != null) {
-                    l.remove(provider);
-                }
-            }
-        }
-
-        private synchronized BundleProviderLoader getLoader(String id) {
-            // synchronize on the registry instance
-            if (registry != null) {
-                log.fine("registry: " + registry);
-                // return the first match, if any
-                List<BundleProviderLoader> list = registry.get(id);
-                if (list != null && !list.isEmpty()) {
-                    return list.get(0);
-                }
-            }
-            // no match here
-            return null;
-        }
-
-        private synchronized List<BundleProviderLoader> getLoaders(String id) {
-            if (registry != null) {
-                // if we have matches, return a copy of what we currently have
-                // to create a safe local copy.
-                List<BundleProviderLoader> list = registry.get(id);
-                if (list != null && !list.isEmpty()) {
-                    return new ArrayList<BundleProviderLoader>(list);
-                }
-            }
-            // no match here
-            return null;
-        }
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/Register.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/Register.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/Register.java
deleted file mode 100644
index 2868a93..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/Register.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.yoko.util.osgi.locator;
-
-/**
- * @version $Rev$ $Date$
- */
-public interface Register {
-
-    void registerProvider(BundleProviderLoader provider);
-
-    void unregisterProvider(BundleProviderLoader provider);
-
-    void registerService(BundleProviderLoader provider);
-
-    void unregisterService(BundleProviderLoader provider);
-
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ServiceBean.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ServiceBean.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ServiceBean.java
deleted file mode 100644
index 8f3fcb6..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/ServiceBean.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.yoko.util.osgi.locator;
-
-import java.util.logging.Logger;
-
-import org.osgi.framework.Bundle;
-
-/**
- * @version $Rev$ $Date$
- */
-public class ServiceBean {
-    private static final Logger log = Logger.getLogger(ServiceBean.class.getName());
-
-    private Register providerRegistry;
-
-    private BundleProviderLoader bundleProviderLoader;
-
-    public ServiceBean(String key,
-                       String className,
-                       Bundle bundle,
-                       Register providerRegistry) {
-        this(key, className, bundle, providerRegistry, -1);
-    }
-    
-    public ServiceBean(String key,
-                       String className,
-                       Bundle bundle,
-                       Register providerRegistry,
-                       Integer priority) {
-        bundleProviderLoader = new BundleProviderLoader(key, className, bundle, priority == null? -1: priority);
-        log.finer("ServiceBean: " + bundleProviderLoader);
-        this.providerRegistry = providerRegistry;
-    }
-
-
-
-    public void start() {
-        providerRegistry.registerService(bundleProviderLoader);
-    }
-
-    public void stop() {
-        providerRegistry.unregisterService(bundleProviderLoader);
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/activator/AbstractBundleActivator.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/activator/AbstractBundleActivator.java b/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/activator/AbstractBundleActivator.java
deleted file mode 100644
index 2e82ffc..0000000
--- a/yoko-util/src/main/java/org/apache/yoko/util/osgi/locator/activator/AbstractBundleActivator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.apache.yoko.util.osgi.locator.activator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.yoko.util.osgi.locator.BundleProviderLoader;
-import org.apache.yoko.util.osgi.locator.Register;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-
-public abstract class AbstractBundleActivator implements BundleActivator {
-
-	public static class Info {
-	    final String id;
-	    final String className;
-        final int priority;
-        
-		public Info(String id, String className, int priority) {
-			super();
-			this.id = id;
-			this.className = className;
-			this.priority = priority;
-		}
-		
-	}
-	private final Info[] providerInfo;
-    private final Info[] serviceInfo;
-	private ServiceTracker<Register, Register> tracker;
-	private BundleContext context;
-	private boolean registered;
-	private final List<BundleProviderLoader> providerLoaders = new ArrayList<BundleProviderLoader>();
-	private final List<BundleProviderLoader> serviceLoaders = new ArrayList<BundleProviderLoader>();
-	
-	public AbstractBundleActivator(Info[] providerInfo, Info[] serviceInfo) {
-		this.providerInfo = providerInfo;
-		this.serviceInfo = serviceInfo;
-	}
-
-	public void start(final BundleContext context) throws Exception {
-		this.context = context;
-		tracker = new ServiceTracker<Register, Register>(context, Register.class, new ServiceTrackerCustomizer<Register, Register>() {
-
-			public Register addingService(ServiceReference<Register> reference) {
-				Register register = context.getService(reference);
-				register(register);
-				return register;
-			}
-
-			public void modifiedService(ServiceReference<Register> reference,
-					Register service) {
-				// TODO Auto-generated method stub
-				
-			}
-
-			public void removedService(ServiceReference<Register> reference,
-					Register service) {
-				// TODO Auto-generated method stub
-				
-			}
-			
-		});
-		tracker.open();
-		Register register = tracker.getService();
-		if (register != null) {
-			register(register);
-		}
-
-	}
-
-	private synchronized void register(Register register) {
-		if (!registered) {
-			registered = true;
-			Bundle bundle = context.getBundle();
-			for (Info classInfo: providerInfo) {
-				BundleProviderLoader loader = new BundleProviderLoader(classInfo.id, classInfo.className, bundle, classInfo.priority);
-				providerLoaders.add(loader);
-				register.registerProvider(loader);
-			}
-			for (Info classInfo: serviceInfo) {
-				BundleProviderLoader loader = new BundleProviderLoader(classInfo.id, classInfo.className, bundle, classInfo.priority);
-				serviceLoaders.add(loader);
-				register.registerService(loader);
-			}
-		}
-	}
-
-	public void stop(BundleContext context) throws Exception {
-		Register register = tracker.getService();
-		tracker.close();
-		synchronized (this) {
-			if (register != null && registered) {
-				for (BundleProviderLoader loader: providerLoaders) {
-					register.unregisterProvider(loader);
-				}
-				for (BundleProviderLoader loader: serviceLoaders) {
-					register.unregisterService(loader);
-				}
-			}
-		}
-
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/geronimo-yoko/blob/f580371d/yoko-util/src/test/java/org/apache/yoko/util/concurrent/ConcurrentFifoTest.java
----------------------------------------------------------------------
diff --git a/yoko-util/src/test/java/org/apache/yoko/util/concurrent/ConcurrentFifoTest.java b/yoko-util/src/test/java/org/apache/yoko/util/concurrent/ConcurrentFifoTest.java
new file mode 100644
index 0000000..4818250
--- /dev/null
+++ b/yoko-util/src/test/java/org/apache/yoko/util/concurrent/ConcurrentFifoTest.java
@@ -0,0 +1,274 @@
+package org.apache.yoko.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.yoko.util.Sequential;
+import org.junit.Before;
+import org.junit.Test;
+
+@SuppressWarnings("unused")
+public class ConcurrentFifoTest {
+    private static final List<String> ELEMS = new ArrayList<>();
+
+    static {
+        for (char c1 = 'A'; c1 <= 'Z'; c1++)
+            for (char c2 = 'a'; c2 <= 'z'; c2++)
+                ELEMS.add("" + c1 + c2);
+    }
+
+    ConcurrentFifo<String> fifo;
+    Set<Sequential.Place<String>> places;
+    volatile CyclicBarrier startBarrier;
+
+    @Before
+    public void setupFifo() {
+        fifo = new ConcurrentFifo<>();
+    }
+
+    @Before
+    public void setupPlaces() {
+        places = Collections.newSetFromMap(new ConcurrentHashMap<Sequential.Place<String>, Boolean>());
+    }
+
+    @Before
+    public void nullifyStartBarrier() {
+        startBarrier = null;
+    }
+
+    @Test
+    public void testPuttingStuff() throws Exception {
+        // create tasks
+        List<Adder> tasks = new ArrayList<>();
+        for (String dummy : ELEMS)
+            tasks.add(new Adder());
+
+        // run the tasks concurrently
+        List<List<String>> expectedOrders = runConcurrently(tasks);
+
+        // convert the fifo to a list
+        List<String> actualOrder = drainFifo();
+
+        assertEquals(ELEMS.size() * ELEMS.size(), actualOrder.size());
+
+        // check correct ordering per Adder:
+        // as we tally the elements in order,
+        // the number of ELEM[n] encountered 
+        // should always be greater than or 
+        // equal to the number of ELEM[n+1] 
+        // encountered
+        TreeMap<String, Integer> tallySheet = new TreeMap<>();
+        // start with zero for every element
+        for (String elem : ELEMS) tallySheet.put(elem,  0);
+        // place known elephant in Cairo
+        tallySheet.put("", Integer.MAX_VALUE);
+        int index = -1;
+        for (String elem : actualOrder) {
+            index ++;
+            int newTally = tallySheet.get(elem) + 1;
+            tallySheet.put(elem, newTally);
+            Entry<String, Integer> lowerEntry = tallySheet.lowerEntry(elem);
+            String msg = String.format("Element out of order at index %d: %d \"%s\" found but only %d \"%s\"", index, newTally, elem, lowerEntry.getValue(), lowerEntry.getKey());
+            assertTrue(msg, lowerEntry.getValue() >= newTally);
+        }
+    }
+
+    @Test
+    public void testPickingStuff() throws Exception {
+        // pre-populate elements
+        for (String elem : ELEMS)
+            places.add(fifo.put(elem));
+
+        // create tasks
+        List<Constrictor> tasks = new ArrayList<>();
+        for (String elem : ELEMS)
+            tasks.add(new Constrictor());
+
+        // run the tasks concurrently
+        List<List<String>> removalLists = runConcurrently(tasks);
+        for (List<String> list : removalLists) if (!!!list.isEmpty()) System.out.println(list);
+
+        // convert the queue to a list
+        List<String> remainingElements = drainFifo();
+
+        // check for the right number of entries
+        assertEquals(Collections.emptyList(), remainingElements);
+
+        // check everything was removed exactly once
+        List<String> checkedRemovals = concatenate(removalLists);
+        Collections.sort(checkedRemovals);
+        assertEquals(ELEMS, checkedRemovals);
+    }
+
+    @Test
+    public void testGettingStuff() throws Exception {
+        // pre-populate elements
+        for (String elem : ELEMS)
+            places.add(fifo.put(elem));
+
+        // create tasks
+        List<Wiper> tasks = new ArrayList<>();
+        for (String elem : ELEMS)
+            tasks.add(new Wiper());
+
+        // run the tasks concurrently
+        List<List<String>> removalLists = runConcurrently(tasks);
+        for (List<String> list : removalLists) if (!!!list.isEmpty()) System.out.println(list);
+
+        // convert the queue to a list
+        List<String> remainingElements = drainFifo();
+
+        // check for the right number of entries
+        assertEquals(Collections.emptyList(), remainingElements);
+
+        // check everything was removed exactly once
+        List<String> checkedRemovals = concatenate(removalLists);
+        Collections.sort(checkedRemovals);
+        assertEquals(ELEMS, checkedRemovals);
+
+        // check no-one removed anything out of order
+        // i.e. each list of removed elements should remain unchanged by sorting
+        for (List<String> removed : removalLists)
+            assertEquals(new ArrayList<>(new TreeSet<>(removed)), removed);
+    }
+
+    @Test
+    public void testAllOpsConcurrently() throws Exception {
+        // pre-populate all the possible elements
+        for (String elem : ELEMS)
+            places.add(fifo.put(elem));
+
+        // create tasks
+        List<Callable<List<String>>> tasks = new ArrayList<>();
+        for (int i = 0; i < 1000; i++) {
+            switch (i % 4) {
+            case 0:
+            case 2:
+                tasks.add(new Adder());
+                break;
+            case 1:
+                tasks.add(new Constrictor());
+                break;
+            case 3:
+                tasks.add(new Wiper());
+                break;
+            }
+        }
+
+        List<String> added = new ArrayList<>(), removed = new ArrayList<>();
+
+        // collate additions and subtractions
+        Iterator<Callable<List<String>>> iterator = tasks.iterator();
+        for (List<String> results : runConcurrently(tasks))
+            (iterator.next() instanceof Adder ? added : removed).addAll(results);
+        added.addAll(ELEMS); // these were added up front
+        Collections.sort(added);
+        List<String> remainder = drainFifo();
+        removed.addAll(remainder);
+        Collections.sort(removed);
+
+        assertEquals(added, removed);
+
+    }
+
+    private <T> List<T> concatenate(List<List<T>> lists) {
+        List<T> result = new ArrayList<>();
+        for (List<T> list : lists)
+            result.addAll(list);
+        return result;
+    }
+
+    private List<String> drainFifo() {
+        List<String> queuedOrder = new ArrayList<>();
+        do {
+            String o = fifo.remove();
+            if (o == null) break;
+            queuedOrder.add(o);
+        } while (true);
+        return queuedOrder;
+    }
+
+    private <T> List<T> runConcurrently(List<? extends Callable<T>> tasks)
+            throws InterruptedException, ExecutionException {
+        // start all the threads
+        startBarrier = new CyclicBarrier(tasks.size());
+        ExecutorService xs = Executors.newFixedThreadPool(tasks.size());
+        try {
+            List<Future<T>> futures = new ArrayList<>();
+            for (Callable<T> task : tasks)
+                futures.add(xs.submit(task));
+
+            // collect the results
+            List<T> results = new ArrayList<>();
+            for (Future<T> future : futures)
+                results.add(future.get());
+            return results;
+        } finally {
+            xs.shutdown();
+        }
+    }
+
+    /** Adds stuff to the FIFO */
+    class Adder implements Callable<List<String>> {
+        @Override
+        public List<String> call() throws Exception {
+            List<String> added = new ArrayList<>();
+            startBarrier.await();
+            for (String elem : new ArrayList<>(ELEMS)) {
+                places.add(fifo.put(elem));
+                added.add(elem);
+            }
+            return added;
+        }
+    }
+
+    /** Constrains the FIFO by removing specific elements */
+    class Constrictor implements Callable<List<String>> {
+        @Override
+        public List<String> call() throws Exception {
+            List<String> constricted = new ArrayList<>();
+            startBarrier.await();
+            while (!!! places.isEmpty()) {
+                // get a copy of the known places in the fifo and shuffle it
+                List<Sequential.Place<String>> myPlaces = new ArrayList<>(places);
+                Collections.shuffle(myPlaces);
+                // remove everything we can
+                for (Sequential.Place<String> place : myPlaces) {
+                    String elem = place.relinquish();
+                    if (elem != null)
+                        constricted.add(elem);
+                    places.remove(place);
+                }
+            }
+            return constricted;
+        }
+    }
+
+    /** Wipes out the FIFO by getting all the elements */
+    class Wiper implements Callable<List<String>> {
+        @Override
+        public List<String> call() throws Exception {
+            List<String> wiped = new ArrayList<>();
+            startBarrier.await();
+            for (String elem = fifo.remove(); elem != null; elem = fifo.remove())
+                wiped.add(elem);
+            return wiped;
+        }
+    }
+}


Mime
View raw message