[jboss-svn-commits] JBoss Common SVN: r4335 - in arquillian/trunk: spi/src/main/java/org/jboss/arquillian/spi/util and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Apr 26 11:56:49 EDT 2010
Author: pete.muir at jboss.org
Date: 2010-04-26 11:56:48 -0400 (Mon, 26 Apr 2010)
New Revision: 4335
Added:
arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/ServiceLoader.java
Removed:
arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/DefaultServiceLoader.java
Modified:
arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DynamicServiceLoader.java
arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestEnrichers.java
arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestRunners.java
Log:
tidy up ServiceLoader
Modified: arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DynamicServiceLoader.java
===================================================================
--- arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DynamicServiceLoader.java 2010-04-26 13:17:41 UTC (rev 4334)
+++ arquillian/trunk/impl-base/src/main/java/org/jboss/arquillian/impl/DynamicServiceLoader.java 2010-04-26 15:56:48 UTC (rev 4335)
@@ -19,8 +19,7 @@
import java.util.Collection;
import java.util.logging.Logger;
-import org.jboss.arquillian.spi.ServiceLoader;
-import org.jboss.arquillian.spi.util.DefaultServiceLoader;
+import org.jboss.arquillian.spi.util.ServiceLoader;
/**
* DynamicServiceLoader
@@ -28,7 +27,7 @@
* @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
* @version $Revision: $
*/
-public class DynamicServiceLoader implements ServiceLoader
+public class DynamicServiceLoader implements org.jboss.arquillian.spi.ServiceLoader
{
private static Logger logger = Logger.getLogger(DynamicServiceLoader.class.getName());
@@ -37,7 +36,7 @@
*/
public <T> Collection<T> all(Class<T> serviceClass)
{
- return DefaultServiceLoader.load(serviceClass).getProviders();
+ return ServiceLoader.load(serviceClass).getProviders();
}
/* (non-Javadoc)
@@ -45,7 +44,7 @@
*/
public <T> T onlyOne(Class<T> serviceClass)
{
- Collection<T> providers = DefaultServiceLoader.load(serviceClass).getProviders();
+ Collection<T> providers = ServiceLoader.load(serviceClass).getProviders();
verifyOnlyOneOrSameImplementation(serviceClass, providers);
return providers.iterator().next();
Deleted: arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/DefaultServiceLoader.java
===================================================================
--- arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/DefaultServiceLoader.java 2010-04-26 13:17:41 UTC (rev 4334)
+++ arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/DefaultServiceLoader.java 2010-04-26 15:56:48 UTC (rev 4335)
@@ -1,308 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * 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.jboss.arquillian.spi.util;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.Constructor;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * This class handles looking up service providers on the class path. It
- * implements the <a href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider"
- * >Service Provider section of the JAR File Specification</a>.
- *
- * The Service Provider programmatic lookup was not specified prior to Java 6 so
- * this interface allows use of the specification prior to Java 6.
- *
- * The API is copied from <a
- * href="http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html"
- * >java.util.ServiceLoader</a>
- *
- * @author Pete Muir
- * @author <a href="mailto:dev at avalon.apache.org">Avalon Development Team</a>
- */
-public class DefaultServiceLoader<S> implements Iterable<S>
-{
-
- private static final String SERVICES = "META-INF/services";
-
- /**
- * Creates a new service loader for the given service type, using the current
- * thread's context class loader.
- *
- * An invocation of this convenience method of the form
- *
- * {@code ServiceLoader.load(service)</code>}
- *
- * is equivalent to
- *
- * <code>ServiceLoader.load(service,
- * Thread.currentThread().getContextClassLoader())</code>
- *
- * @param service The interface or abstract class representing the service
- * @return A new service loader
- */
- public static <S> DefaultServiceLoader<S> load(Class<S> service)
- {
- return load(SERVICES, service, Thread.currentThread().getContextClassLoader());
- }
-
- public static <S> DefaultServiceLoader<S> load(String directoryName, Class<S> service)
- {
- return load(directoryName, service, Thread.currentThread().getContextClassLoader());
- }
-
- public static <S> DefaultServiceLoader<S> load(String directoryName, Class<S> service, ClassLoader loader)
- {
- if (loader == null)
- {
- loader = service.getClassLoader();
- }
- return new DefaultServiceLoader<S>(directoryName, service, loader);
- }
-
- /**
- * Creates a new service loader for the given service type and class loader.
- *
- * @param service The interface or abstract class representing the service
- * @param loader The class loader to be used to load provider-configuration
- * files and provider classes, or null if the system class loader
- * (or, failing that, the bootstrap class loader) is to be used
- * @return A new service loader
- */
- public static <S> DefaultServiceLoader<S> load(Class<S> service, ClassLoader loader)
- {
- return load(SERVICES, service, loader);
- }
-
- /**
- * Creates a new service loader for the given service type, using the
- * extension class loader.
- *
- * This convenience method simply locates the extension class loader, call it
- * extClassLoader, and then returns
- *
- * <code>ServiceLoader.load(service, extClassLoader)</code>
- *
- * If the extension class loader cannot be found then the system class loader
- * is used; if there is no system class loader then the bootstrap class
- * loader is used.
- *
- * This method is intended for use when only installed providers are desired.
- * The resulting service will only find and load providers that have been
- * installed into the current Java virtual machine; providers on the
- * application's class path will be ignored.
- *
- * @param service The interface or abstract class representing the service
- * @return A new service loader
- */
- public static <S> DefaultServiceLoader<S> loadInstalled(Class<S> service)
- {
- throw new UnsupportedOperationException();
- }
-
- private final String serviceFile;
- private Class<S> expectedType;
- private final ClassLoader loader;
-
- private Set<S> providers;
-
- private DefaultServiceLoader(String prefix, Class<S> service, ClassLoader loader)
- {
- this.loader = loader;
- this.serviceFile = prefix + "/" + service.getName();
- this.expectedType = service;
- }
-
- /**
- * Clear this loader's provider cache so that all providers will be reloaded.
- *
- * After invoking this method, subsequent invocations of the iterator method
- * will lazily look up and instantiate providers from scratch, just as is
- * done by a newly-created loader.
- *
- * This method is intended for use in situations in which new providers can
- * be installed into a running Java virtual machine.
- */
- public void reload()
- {
- providers = new HashSet<S>();
- Enumeration<URL> enumeration = null;
- boolean errorOccurred = false;
-
- try
- {
- enumeration = loader.getResources(serviceFile);
- }
- catch (IOException ioe)
- {
- errorOccurred = true;
- }
-
- if (!errorOccurred)
- {
- while (enumeration.hasMoreElements())
- {
- try
- {
- final URL url = enumeration.nextElement();
- final InputStream is = url.openStream();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
-
- String line = reader.readLine();
- while (null != line)
- {
- try
- {
- final int comment = line.indexOf('#');
-
- if (comment > -1)
- {
- line = line.substring(0, comment);
- }
-
- line.trim();
-
- if (line.length() > 0)
- {
- try
- {
- Class<?> clazz = loader.loadClass(line);
- Class<? extends S> serviceClass;
- try
- {
- serviceClass = clazz.asSubclass(expectedType);
- }
- catch (ClassCastException e)
- {
- throw new IllegalStateException(line + " does not implement " + expectedType);
- }
- Constructor<? extends S> constructor = serviceClass.getConstructor();
- if(!constructor.isAccessible()) {
- constructor.setAccessible(true);
- }
- S instance = constructor.newInstance();
- providers.add(instance);
- }
- catch (NoClassDefFoundError e)
- {
- throw e;
- }
- catch (InstantiationException e)
- {
- throw e;
- }
- catch (IllegalAccessException e)
- {
- throw e;
- }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- // TODO Don't use exceptions for flow control!
- // try the next line
- }
-
- line = reader.readLine();
- }
- reader.close();
- }
- catch (Exception e)
- {
- // try the next file
- }
- }
- }
- }
-
-
-
- /**
- * Lazily loads the available providers of this loader's service.
- *
- * The iterator returned by this method first yields all of the elements of
- * the provider cache, in instantiation order. It then lazily loads and
- * instantiates any remaining providers, adding each one to the cache in
- * turn.
- *
- * To achieve laziness the actual work of parsing the available
- * provider-configuration files and instantiating providers must be done by
- * the iterator itself. Its hasNext and next methods can therefore throw a
- * ServiceConfigurationError if a provider-configuration file violates the
- * specified format, or if it names a provider class that cannot be found and
- * instantiated, or if the result of instantiating the class is not
- * assignable to the service type, or if any other kind of exception or error
- * is thrown as the next provider is located and instantiated. To write
- * robust code it is only necessary to catch ServiceConfigurationError when
- * using a service iterator.
- *
- * If such an error is thrown then subsequent invocations of the iterator
- * will make a best effort to locate and instantiate the next available
- * provider, but in general such recovery cannot be guaranteed.
- *
- * Design Note Throwing an error in these cases may seem extreme. The
- * rationale for this behavior is that a malformed provider-configuration
- * file, like a malformed class file, indicates a serious problem with the
- * way the Java virtual machine is configured or is being used. As such it is
- * preferable to throw an error rather than try to recover or, even worse,
- * fail silently.
- *
- * The iterator returned by this method does not support removal. Invoking
- * its remove method will cause an UnsupportedOperationException to be
- * thrown.
- *
- * @return An iterator that lazily loads providers for this loader's service
- */
- public Iterator<S> iterator()
- {
- if (providers == null)
- {
- reload();
- }
- return providers.iterator();
- }
-
- public Set<S> getProviders() {
- if (providers == null)
- {
- reload();
- }
- return Collections.unmodifiableSet(providers);
- }
-
- /**
- * Returns a string describing this service.
- *
- * @return A descriptive string
- */
- @Override
- public String toString()
- {
- return "Services for " + serviceFile;
- }
-
-}
Copied: arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/ServiceLoader.java (from rev 4277, arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/DefaultServiceLoader.java)
===================================================================
--- arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/ServiceLoader.java (rev 0)
+++ arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/ServiceLoader.java 2010-04-26 15:56:48 UTC (rev 4335)
@@ -0,0 +1,298 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * 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.jboss.arquillian.spi.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * This class handles looking up service providers on the class path. It
+ * implements the <a href="http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider"
+ * >Service Provider section of the JAR File Specification</a>.
+ *
+ * The Service Provider programmatic lookup was not specified prior to Java 6 so
+ * this interface allows use of the specification prior to Java 6.
+ *
+ * The API is copied from <a
+ * href="http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html"
+ * >java.util.ServiceLoader</a>
+ *
+ * @author Pete Muir
+ * @author <a href="mailto:dev at avalon.apache.org">Avalon Development Team</a>
+ */
+public class ServiceLoader<S> implements Iterable<S>
+{
+
+ private static final String SERVICES = "META-INF/services";
+
+ /**
+ * Creates a new service loader for the given service type, using the current
+ * thread's context class loader.
+ *
+ * An invocation of this convenience method of the form
+ *
+ * {@code ServiceLoader.load(service)</code>}
+ *
+ * is equivalent to
+ *
+ * <code>ServiceLoader.load(service,
+ * Thread.currentThread().getContextClassLoader())</code>
+ *
+ * @param service The interface or abstract class representing the service
+ * @return A new service loader
+ */
+ public static <S> ServiceLoader<S> load(Class<S> service)
+ {
+ return load(service, Thread.currentThread().getContextClassLoader());
+ }
+
+ /**
+ * Creates a new service loader for the given service type and class loader.
+ *
+ * @param service The interface or abstract class representing the service
+ * @param loader The class loader to be used to load provider-configuration
+ * files and provider classes, or null if the system class loader
+ * (or, failing that, the bootstrap class loader) is to be used
+ * @return A new service loader
+ */
+ public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader)
+ {
+ if (loader == null)
+ {
+ loader = service.getClassLoader();
+ }
+ return new ServiceLoader<S>(service, loader);
+ }
+
+ /**
+ * Creates a new service loader for the given service type, using the
+ * extension class loader.
+ *
+ * This convenience method simply locates the extension class loader, call it
+ * extClassLoader, and then returns
+ *
+ * <code>ServiceLoader.load(service, extClassLoader)</code>
+ *
+ * If the extension class loader cannot be found then the system class loader
+ * is used; if there is no system class loader then the bootstrap class
+ * loader is used.
+ *
+ * This method is intended for use when only installed providers are desired.
+ * The resulting service will only find and load providers that have been
+ * installed into the current Java virtual machine; providers on the
+ * application's class path will be ignored.
+ *
+ * @param service The interface or abstract class representing the service
+ * @return A new service loader
+ */
+ public static <S> ServiceLoader<S> loadInstalled(Class<S> service)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ private final String serviceFile;
+ private Class<S> expectedType;
+ private final ClassLoader loader;
+
+ private Set<S> providers;
+
+ private ServiceLoader(Class<S> service, ClassLoader loader)
+ {
+ this.loader = loader;
+ this.serviceFile = SERVICES + "/" + service.getName();
+ this.expectedType = service;
+ }
+
+ /**
+ * Clear this loader's provider cache so that all providers will be reloaded.
+ *
+ * After invoking this method, subsequent invocations of the iterator method
+ * will lazily look up and instantiate providers from scratch, just as is
+ * done by a newly-created loader.
+ *
+ * This method is intended for use in situations in which new providers can
+ * be installed into a running Java virtual machine.
+ */
+ public void reload()
+ {
+ providers = new HashSet<S>();
+ Enumeration<URL> enumeration = null;
+ boolean errorOccurred = false;
+
+ try
+ {
+ enumeration = loader.getResources(serviceFile);
+ }
+ catch (IOException ioe)
+ {
+ errorOccurred = true;
+ }
+
+ if (!errorOccurred)
+ {
+ while (enumeration.hasMoreElements())
+ {
+ try
+ {
+ final URL url = enumeration.nextElement();
+ final InputStream is = url.openStream();
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+
+ String line = reader.readLine();
+ while (null != line)
+ {
+ try
+ {
+ final int comment = line.indexOf('#');
+
+ if (comment > -1)
+ {
+ line = line.substring(0, comment);
+ }
+
+ line.trim();
+
+ if (line.length() > 0)
+ {
+ try
+ {
+ Class<?> clazz = loader.loadClass(line);
+ Class<? extends S> serviceClass;
+ try
+ {
+ serviceClass = clazz.asSubclass(expectedType);
+ }
+ catch (ClassCastException e)
+ {
+ throw new IllegalStateException("Extension " + line + " does not implement Extension");
+ }
+ Constructor<? extends S> constructor = serviceClass.getConstructor();
+ if(!constructor.isAccessible()) {
+ constructor.setAccessible(true);
+ }
+ S instance = constructor.newInstance();
+ providers.add(instance);
+ }
+ catch (NoClassDefFoundError e)
+ {
+ throw e;
+ }
+ catch (InstantiationException e)
+ {
+ throw e;
+ }
+ catch (IllegalAccessException e)
+ {
+ throw e;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ // TODO Don't use exceptions for flow control!
+ // try the next line
+ }
+
+ line = reader.readLine();
+ }
+ reader.close();
+ }
+ catch (Exception e)
+ {
+ // try the next file
+ }
+ }
+ }
+ }
+
+
+
+ /**
+ * Lazily loads the available providers of this loader's service.
+ *
+ * The iterator returned by this method first yields all of the elements of
+ * the provider cache, in instantiation order. It then lazily loads and
+ * instantiates any remaining providers, adding each one to the cache in
+ * turn.
+ *
+ * To achieve laziness the actual work of parsing the available
+ * provider-configuration files and instantiating providers must be done by
+ * the iterator itself. Its hasNext and next methods can therefore throw a
+ * ServiceConfigurationError if a provider-configuration file violates the
+ * specified format, or if it names a provider class that cannot be found and
+ * instantiated, or if the result of instantiating the class is not
+ * assignable to the service type, or if any other kind of exception or error
+ * is thrown as the next provider is located and instantiated. To write
+ * robust code it is only necessary to catch ServiceConfigurationError when
+ * using a service iterator.
+ *
+ * If such an error is thrown then subsequent invocations of the iterator
+ * will make a best effort to locate and instantiate the next available
+ * provider, but in general such recovery cannot be guaranteed.
+ *
+ * Design Note Throwing an error in these cases may seem extreme. The
+ * rationale for this behavior is that a malformed provider-configuration
+ * file, like a malformed class file, indicates a serious problem with the
+ * way the Java virtual machine is configured or is being used. As such it is
+ * preferable to throw an error rather than try to recover or, even worse,
+ * fail silently.
+ *
+ * The iterator returned by this method does not support removal. Invoking
+ * its remove method will cause an UnsupportedOperationException to be
+ * thrown.
+ *
+ * @return An iterator that lazily loads providers for this loader's service
+ */
+ public Iterator<S> iterator()
+ {
+ if (providers == null)
+ {
+ reload();
+ }
+ return providers.iterator();
+ }
+
+ public Set<S> getProviders() {
+ if (providers == null)
+ {
+ reload();
+ }
+ return Collections.unmodifiableSet(providers);
+ }
+
+ /**
+ * Returns a string describing this service.
+ *
+ * @return A descriptive string
+ */
+ @Override
+ public String toString()
+ {
+ return "Services for " + serviceFile;
+ }
+
+}
Modified: arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestEnrichers.java
===================================================================
--- arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestEnrichers.java 2010-04-26 13:17:41 UTC (rev 4334)
+++ arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestEnrichers.java 2010-04-26 15:56:48 UTC (rev 4335)
@@ -45,7 +45,7 @@
public static Object[] enrich(Context context, Method method)
{
Object[] values = new Object[method.getParameterTypes().length];
- DefaultServiceLoader<TestEnricher> serviceLoader = DefaultServiceLoader
+ ServiceLoader<TestEnricher> serviceLoader = ServiceLoader
.load(TestEnricher.class);
for (TestEnricher enricher : serviceLoader)
{
Modified: arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestRunners.java
===================================================================
--- arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestRunners.java 2010-04-26 13:17:41 UTC (rev 4334)
+++ arquillian/trunk/spi/src/main/java/org/jboss/arquillian/spi/util/TestRunners.java 2010-04-26 15:56:48 UTC (rev 4335)
@@ -38,7 +38,7 @@
*/
public static TestRunner getTestRunner()
{
- DefaultServiceLoader<TestRunner> serviceLoader = DefaultServiceLoader.load(
+ ServiceLoader<TestRunner> serviceLoader = ServiceLoader.load(
TestRunner.class,
SecurityActions.getThreadContextClassLoader());
More information about the jboss-svn-commits
mailing list