summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java')
-rw-r--r--sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java177
1 files changed, 177 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java b/sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java
new file mode 100644
index 0000000000..65ede08a32
--- /dev/null
+++ b/sca-java-1.x/tags/java-stable-20060304/sca/common/src/main/java/org/apache/tuscany/common/discovery/util/ServiceProviderRegistry.java
@@ -0,0 +1,177 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * 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.
+ */
+package org.apache.tuscany.common.discovery.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.tuscany.common.io.util.FixedURLInputStream;
+
+//FIXME Port to 1.5 collections
+
+/**
+ * A Registry for service providers defined using the
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">JAR service provider mechanism</a>.
+ *
+ */
+public class ServiceProviderRegistry {
+
+ private Map registry = Collections.synchronizedMap(new WeakHashMap());
+
+ private final static ServiceProviderRegistry instance = new ServiceProviderRegistry();
+
+ /**
+ * Constructor.
+ */
+ public ServiceProviderRegistry() {
+ super();
+ }
+
+ /**
+ * @return Returns the instance.
+ */
+ public static ServiceProviderRegistry getInstance() {
+ return instance;
+ }
+
+ /**
+ * Get the available providers of a given type.
+ *
+ * @param clazz
+ * @return
+ */
+ public List getServiceProviders(final Class clazz) {
+ List providers = (List) registry.get(clazz);
+ if (providers != null)
+ return providers;
+
+ providers = (List) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return loadServiceProviders(clazz);
+ }
+ });
+
+ registry.put(clazz, providers);
+ return providers;
+ }
+
+ /**
+ * Get an provider of a given type.
+ *
+ * @param clazz
+ * @return
+ */
+ public Object getServiceProvider(Class clazz) {
+ List providers = getServiceProviders(clazz);
+ if (providers.isEmpty())
+ return null;
+ else {
+ return providers.get(0);
+ }
+ }
+
+ /**
+ * Registers an provider programatically
+ *
+ * @param clazz
+ * @param provider
+ */
+ public void registerServiceProvider(Class clazz, Object provider) {
+ getServiceProviders(clazz).add(provider);
+ }
+
+ /**
+ * Load providers of the given type
+ *
+ * @param clazz
+ * @return
+ */
+ private List loadServiceProviders(Class clazz) {
+ List classNames = new ArrayList();
+
+ // First look for a system property named <SPI className>
+ String className = System.getProperty(clazz.getName());
+ if (className != null)
+ classNames.add(className);
+
+ // Find all the class names mentioned in all the META-INF/services/<SPI className>
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ try {
+ Enumeration files = loader.getResources("META-INF/services/" + clazz.getName());
+ while (files.hasMoreElements()) {
+ URL url = (URL) files.nextElement();
+ readClassNames(url, classNames);
+ }
+ } catch (IOException e) {
+ }
+
+ // Instantiate an provider for each of the named classes
+ List providers = new ArrayList();
+ Iterator i = classNames.iterator();
+ while (i.hasNext()) {
+ String name = (String) i.next();
+ try {
+ Class providerClass = Class.forName(name, true, loader);
+ providers.add(providerClass.newInstance());
+ } catch (Exception e) {
+ // Ignore ClassNotFoundException
+ }
+ }
+ return providers;
+ }
+
+ /**
+ * Read class names from the given URL.
+ * @param url
+ * @param classNames
+ * @throws IOException
+ */
+ private void readClassNames(URL url, List classNames) throws IOException {
+ InputStream is = new FixedURLInputStream(url);
+ try {
+ BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ String inputLine = null;
+ while ((inputLine = in.readLine()) != null) {
+ int i = inputLine.indexOf('#');
+ if (i >= 0) {
+ inputLine = inputLine.substring(0, i);
+ }
+ inputLine = inputLine.trim();
+ if (inputLine.length() > 0) {
+ if (!classNames.contains(inputLine)) {
+ classNames.add(inputLine);
+ }
+ }
+ }
+ } finally {
+ is.close();
+ }
+ }
+
+}