src/share/classes/java/util/ServiceLoader.java

Print this page
rev 3186 : 6880112: Project Coin: Port JDK core library code to use diamond operator


 174  * @param  <S>
 175  *         The type of the service to be loaded by this loader
 176  *
 177  * @author Mark Reinhold
 178  * @since 1.6
 179  */
 180 
 181 public final class ServiceLoader<S>
 182     implements Iterable<S>
 183 {
 184 
 185     private static final String PREFIX = "META-INF/services/";
 186 
 187     // The class or interface representing the service being loaded
 188     private Class<S> service;
 189 
 190     // The class loader used to locate, load, and instantiate providers
 191     private ClassLoader loader;
 192 
 193     // Cached providers, in instantiation order
 194     private LinkedHashMap<String,S> providers = new LinkedHashMap<String,S>();
 195 
 196     // The current lazy-lookup iterator
 197     private LazyIterator lookupIterator;
 198 
 199     /**
 200      * Clear this loader's provider cache so that all providers will be
 201      * reloaded.
 202      *
 203      * <p> After invoking this method, subsequent invocations of the {@link
 204      * #iterator() iterator} method will lazily look up and instantiate
 205      * providers from scratch, just as is done by a newly-created loader.
 206      *
 207      * <p> This method is intended for use in situations in which new providers
 208      * can be installed into a running Java virtual machine.
 209      */
 210     public void reload() {
 211         providers.clear();
 212         lookupIterator = new LazyIterator(service, loader);
 213     }
 214 


 274     // @param  service
 275     //         The service type for which providers are being sought;
 276     //         used to construct error detail strings
 277     //
 278     // @param  u
 279     //         The URL naming the configuration file to be parsed
 280     //
 281     // @return A (possibly empty) iterator that will yield the provider-class
 282     //         names in the given configuration file that are not yet members
 283     //         of the returned set
 284     //
 285     // @throws ServiceConfigurationError
 286     //         If an I/O error occurs while reading from the given URL, or
 287     //         if a configuration-file format error is detected
 288     //
 289     private Iterator<String> parse(Class service, URL u)
 290         throws ServiceConfigurationError
 291     {
 292         InputStream in = null;
 293         BufferedReader r = null;
 294         ArrayList<String> names = new ArrayList<String>();
 295         try {
 296             in = u.openStream();
 297             r = new BufferedReader(new InputStreamReader(in, "utf-8"));
 298             int lc = 1;
 299             while ((lc = parseLine(service, u, r, lc, names)) >= 0);
 300         } catch (IOException x) {
 301             fail(service, "Error reading configuration file", x);
 302         } finally {
 303             try {
 304                 if (r != null) r.close();
 305                 if (in != null) in.close();
 306             } catch (IOException y) {
 307                 fail(service, "Error closing configuration file", y);
 308             }
 309         }
 310         return names.iterator();
 311     }
 312 
 313     // Private inner class implementing fully-lazy provider lookup
 314     //


 446     }
 447 
 448     /**
 449      * Creates a new service loader for the given service type and class
 450      * loader.
 451      *
 452      * @param  service
 453      *         The interface or abstract class representing the service
 454      *
 455      * @param  loader
 456      *         The class loader to be used to load provider-configuration files
 457      *         and provider classes, or <tt>null</tt> if the system class
 458      *         loader (or, failing that, the bootstrap class loader) is to be
 459      *         used
 460      *
 461      * @return A new service loader
 462      */
 463     public static <S> ServiceLoader<S> load(Class<S> service,
 464                                             ClassLoader loader)
 465     {
 466         return new ServiceLoader<S>(service, loader);
 467     }
 468 
 469     /**
 470      * Creates a new service loader for the given service type, using the
 471      * current thread's {@linkplain java.lang.Thread#getContextClassLoader
 472      * context class loader}.
 473      *
 474      * <p> An invocation of this convenience method of the form
 475      *
 476      * <blockquote><pre>
 477      * ServiceLoader.load(<i>service</i>)</pre></blockquote>
 478      *
 479      * is equivalent to
 480      *
 481      * <blockquote><pre>
 482      * ServiceLoader.load(<i>service</i>,
 483      *                    Thread.currentThread().getContextClassLoader())</pre></blockquote>
 484      *
 485      * @param  service
 486      *         The interface or abstract class representing the service




 174  * @param  <S>
 175  *         The type of the service to be loaded by this loader
 176  *
 177  * @author Mark Reinhold
 178  * @since 1.6
 179  */
 180 
 181 public final class ServiceLoader<S>
 182     implements Iterable<S>
 183 {
 184 
 185     private static final String PREFIX = "META-INF/services/";
 186 
 187     // The class or interface representing the service being loaded
 188     private Class<S> service;
 189 
 190     // The class loader used to locate, load, and instantiate providers
 191     private ClassLoader loader;
 192 
 193     // Cached providers, in instantiation order
 194     private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
 195 
 196     // The current lazy-lookup iterator
 197     private LazyIterator lookupIterator;
 198 
 199     /**
 200      * Clear this loader's provider cache so that all providers will be
 201      * reloaded.
 202      *
 203      * <p> After invoking this method, subsequent invocations of the {@link
 204      * #iterator() iterator} method will lazily look up and instantiate
 205      * providers from scratch, just as is done by a newly-created loader.
 206      *
 207      * <p> This method is intended for use in situations in which new providers
 208      * can be installed into a running Java virtual machine.
 209      */
 210     public void reload() {
 211         providers.clear();
 212         lookupIterator = new LazyIterator(service, loader);
 213     }
 214 


 274     // @param  service
 275     //         The service type for which providers are being sought;
 276     //         used to construct error detail strings
 277     //
 278     // @param  u
 279     //         The URL naming the configuration file to be parsed
 280     //
 281     // @return A (possibly empty) iterator that will yield the provider-class
 282     //         names in the given configuration file that are not yet members
 283     //         of the returned set
 284     //
 285     // @throws ServiceConfigurationError
 286     //         If an I/O error occurs while reading from the given URL, or
 287     //         if a configuration-file format error is detected
 288     //
 289     private Iterator<String> parse(Class service, URL u)
 290         throws ServiceConfigurationError
 291     {
 292         InputStream in = null;
 293         BufferedReader r = null;
 294         ArrayList<String> names = new ArrayList<>();
 295         try {
 296             in = u.openStream();
 297             r = new BufferedReader(new InputStreamReader(in, "utf-8"));
 298             int lc = 1;
 299             while ((lc = parseLine(service, u, r, lc, names)) >= 0);
 300         } catch (IOException x) {
 301             fail(service, "Error reading configuration file", x);
 302         } finally {
 303             try {
 304                 if (r != null) r.close();
 305                 if (in != null) in.close();
 306             } catch (IOException y) {
 307                 fail(service, "Error closing configuration file", y);
 308             }
 309         }
 310         return names.iterator();
 311     }
 312 
 313     // Private inner class implementing fully-lazy provider lookup
 314     //


 446     }
 447 
 448     /**
 449      * Creates a new service loader for the given service type and class
 450      * loader.
 451      *
 452      * @param  service
 453      *         The interface or abstract class representing the service
 454      *
 455      * @param  loader
 456      *         The class loader to be used to load provider-configuration files
 457      *         and provider classes, or <tt>null</tt> if the system class
 458      *         loader (or, failing that, the bootstrap class loader) is to be
 459      *         used
 460      *
 461      * @return A new service loader
 462      */
 463     public static <S> ServiceLoader<S> load(Class<S> service,
 464                                             ClassLoader loader)
 465     {
 466         return new ServiceLoader<>(service, loader);
 467     }
 468 
 469     /**
 470      * Creates a new service loader for the given service type, using the
 471      * current thread's {@linkplain java.lang.Thread#getContextClassLoader
 472      * context class loader}.
 473      *
 474      * <p> An invocation of this convenience method of the form
 475      *
 476      * <blockquote><pre>
 477      * ServiceLoader.load(<i>service</i>)</pre></blockquote>
 478      *
 479      * is equivalent to
 480      *
 481      * <blockquote><pre>
 482      * ServiceLoader.load(<i>service</i>,
 483      *                    Thread.currentThread().getContextClassLoader())</pre></blockquote>
 484      *
 485      * @param  service
 486      *         The interface or abstract class representing the service