[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