Java tutorial
/* * Licensed 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. */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; /** * Maintains a mapping of service names to an ordered set of service providers * when running in an OSGi container. <p/> It is expected that a bundle using * Drools will populate this map with properties from its own ClassLoader. <p/> * This is an adaptation of the technique described by Guillaume Nodet in his * article<i> <a * href='http://gnodet.blogspot.com/2008/05/jee-specs-in-osgi.html'> Java EE * specs in OSGi</a></i>. The main changes were to add comments. * * @author Guillaume Nodet * @author Faron Dutton * @see {@linkplain http://gnodet.blogspot.com/2008/05/jee-specs-in-osgi.html} */ public final class OSGiLocator { /** * Maps a service name (the fully qualified name of the interface) to an * ordered set of factories. Each factory instantiating a specific service * provider (implementation). */ private static Map<String, List<Callable<Class<?>>>> factories; /** * Private constructor used to prevent instantiation of this utility class * (i.e., Utility Pattern). */ private OSGiLocator() { super(); } /** * Removes the given service provider factory from the set of providers for * the service. * * @param serviceName * The fully qualified name of the service interface. * @param factory * A factory for creating a specific type of service provider. May be * <tt>null</tt> in which case this method does nothing. * @throws IllegalArgumentException * if serviceName is <tt>null</tt> */ public static synchronized void unregister(final String serviceName, final Callable<Class<?>> factory) { if (serviceName == null) { throw new IllegalArgumentException("serviceName cannot be null"); } if (factories != null) { List<Callable<Class<?>>> l = factories.get(serviceName); if (l != null) { l.remove(factory); } } } /** * Adds the given service provider factory to the set of providers for the * service. * * @param serviceName * The fully qualified name of the service interface. * @param factory * A factory for creating a specific type of service provider. May be * <tt>null</tt> in which case this method does nothing. * @throws IllegalArgumentException * if serviceName is <tt>null</tt> */ public static synchronized void register(final String serviceName, final Callable<Class<?>> factory) { if (serviceName == null) { throw new IllegalArgumentException("serviceName cannot be null"); } if (factory != null) { if (factories == null) { factories = new HashMap<String, List<Callable<Class<?>>>>(); } List<Callable<Class<?>>> l = factories.get(serviceName); if (l == null) { l = new ArrayList<Callable<Class<?>>>(); factories.put(serviceName, l); } l.add(factory); } } /** * Finds the preferred provider for the given service. The preferred provider * is the last one added to the set of providers. * * @param serviceName * The fully qualified name of the service interface. * @return The last provider added for the service if any exists. Otherwise, * it returns <tt>null</tt>. * @throws IllegalArgumentException * if serviceName is <tt>null</tt> */ public static synchronized Class<?> locate(final String serviceName) { if (serviceName == null) { throw new IllegalArgumentException("serviceName cannot be null"); } if (factories != null) { List<Callable<Class<?>>> l = factories.get(serviceName); if (l != null && !l.isEmpty()) { Callable<Class<?>> c = l.get(l.size() - 1); try { return c.call(); } catch (Exception e) { } } } return null; } /** * Finds all providers for the given service. * * @param serviceName * The fully qualified name of the service interface. * @return The ordered set of providers for the service if any exists. * Otherwise, it returns an empty list. * @throws IllegalArgumentException * if serviceName is <tt>null</tt> */ public static synchronized List<Class<?>> locateAll(final String serviceName) { if (serviceName == null) { throw new IllegalArgumentException("serviceName cannot be null"); } List<Class<?>> classes = new ArrayList<Class<?>>(); if (factories != null) { List<Callable<Class<?>>> l = factories.get(serviceName); if (l != null) { for (Callable<Class<?>> c : l) { try { classes.add(c.call()); } catch (Exception e) { } } } } return classes; } }