diff -r 4252bfc396fc -r d382dacfd73f emul/compact/src/main/java/java/util/ServiceLoader.java --- a/emul/compact/src/main/java/java/util/ServiceLoader.java Tue Feb 26 14:55:55 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,538 +0,0 @@ -/* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - - -/** - * A simple service-provider loading facility. - * - *
A service is a well-known set of interfaces and (usually - * abstract) classes. A service provider is a specific implementation - * of a service. The classes in a provider typically implement the interfaces - * and subclass the classes defined in the service itself. Service providers - * can be installed in an implementation of the Java platform in the form of - * extensions, that is, jar files placed into any of the usual extension - * directories. Providers can also be made available by adding them to the - * application's class path or by some other platform-specific means. - * - *
For the purpose of loading, a service is represented by a single type, - * that is, a single interface or abstract class. (A concrete class can be - * used, but this is not recommended.) A provider of a given service contains - * one or more concrete classes that extend this service type with data - * and code specific to the provider. The provider class is typically - * not the entire provider itself but rather a proxy which contains enough - * information to decide whether the provider is able to satisfy a particular - * request together with code that can create the actual provider on demand. - * The details of provider classes tend to be highly service-specific; no - * single class or interface could possibly unify them, so no such type is - * defined here. The only requirement enforced by this facility is that - * provider classes must have a zero-argument constructor so that they can be - * instantiated during loading. - * - *
A service provider is identified by placing a - * provider-configuration file in the resource directory - * META-INF/services. The file's name is the fully-qualified binary name of the service's type. - * The file contains a list of fully-qualified binary names of concrete - * provider classes, one per line. Space and tab characters surrounding each - * name, as well as blank lines, are ignored. The comment character is - * '#' ('\u0023', NUMBER SIGN); on - * each line all characters following the first comment character are ignored. - * The file must be encoded in UTF-8. - * - *
If a particular concrete provider class is named in more than one - * configuration file, or is named in the same configuration file more than - * once, then the duplicates are ignored. The configuration file naming a - * particular provider need not be in the same jar file or other distribution - * unit as the provider itself. The provider must be accessible from the same - * class loader that was initially queried to locate the configuration file; - * note that this is not necessarily the class loader from which the file was - * actually loaded. - * - *
Providers are located and instantiated lazily, that is, on demand. A - * service loader maintains a cache of the providers that have been loaded so - * far. Each invocation of the {@link #iterator iterator} method returns an - * iterator that first yields all of the elements of the cache, in - * instantiation order, and then lazily locates and instantiates any remaining - * providers, adding each one to the cache in turn. The cache can be cleared - * via the {@link #reload reload} method. - * - *
Service loaders always execute in the security context of the caller. - * Trusted system code should typically invoke the methods in this class, and - * the methods of the iterators which they return, from within a privileged - * security context. - * - *
Instances of this class are not safe for use by multiple concurrent - * threads. - * - *
Unless otherwise specified, passing a null argument to any - * method in this class will cause a {@link NullPointerException} to be thrown. - * - * - *
Example - * Suppose we have a service type com.example.CodecSet which is - * intended to represent sets of encoder/decoder pairs for some protocol. In - * this case it is an abstract class with two abstract methods: - * - *
- * - * Each method returns an appropriate object or null if the provider - * does not support the given encoding. Typical providers support more than - * one encoding. - * - *- * public abstract Encoder getEncoder(String encodingName); - * public abstract Decoder getDecoder(String encodingName);
If com.example.impl.StandardCodecs is an implementation of the - * CodecSet service then its jar file also contains a file named - * - *
- * - *- * META-INF/services/com.example.CodecSet
This file contains the single line: - * - *
- * - *- * com.example.impl.StandardCodecs # Standard codecs
The CodecSet class creates and saves a single service instance - * at initialization: - * - *
- * - *- * private static ServiceLoader<CodecSet> codecSetLoader - * = ServiceLoader.load(CodecSet.class);
To locate an encoder for a given encoding name it defines a static - * factory method which iterates through the known and available providers, - * returning only when it has located a suitable encoder or has run out of - * providers. - * - *
- * - *- * public static Encoder getEncoder(String encodingName) { - * for (CodecSet cp : codecSetLoader) { - * Encoder enc = cp.getEncoder(encodingName); - * if (enc != null) - * return enc; - * } - * return null; - * }
A getDecoder method is defined similarly. - * - * - *
Usage Note If - * the class path of a class loader that is used for provider loading includes - * remote network URLs then those URLs will be dereferenced in the process of - * searching for provider-configuration files. - * - *
This activity is normal, although it may cause puzzling entries to be - * created in web-server logs. If a web server is not configured correctly, - * however, then this activity may cause the provider-loading algorithm to fail - * spuriously. - * - *
A web server should return an HTTP 404 (Not Found) response when a
- * requested resource does not exist. Sometimes, however, web servers are
- * erroneously configured to return an HTTP 200 (OK) response along with a
- * helpful HTML error page in such cases. This will cause a {@link
- * ServiceConfigurationError} to be thrown when this class attempts to parse
- * the HTML page as a provider-configuration file. The best solution to this
- * problem is to fix the misconfigured web server to return the correct
- * response code (HTTP 404) along with the HTML error page.
- *
- * @param After invoking this method, subsequent invocations of the {@link
- * #iterator() 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.clear();
- lookupIterator = new LazyIterator(service, loader);
- }
-
- private ServiceLoader(Class 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 {@link java.util.Iterator#hasNext hasNext} and
- * {@link java.util.Iterator#next next} methods can therefore throw a
- * {@link 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 {@link
- * 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.
- *
- * The iterator returned by this method does not support removal.
- * Invoking its {@link java.util.Iterator#remove() remove} method will
- * cause an {@link UnsupportedOperationException} to be thrown.
- *
- * @return An iterator that lazily loads providers for this loader's
- * service
- */
- public Iterator An invocation of this convenience method of the form
- *
- * This convenience method simply locates the extension class loader,
- * call it extClassLoader, and then returns
- *
- * 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
- * The type of the service to be loaded by this loader
- *
- * @author Mark Reinhold
- * @since 1.6
- */
-
-public final class ServiceLoader
- implements Iterable
-{
-
- private static final String PREFIX = "META-INF/services/";
-
- // The class or interface representing the service being loaded
- private Class service;
-
- // The class loader used to locate, load, and instantiate providers
- private ClassLoader loader;
-
- // Cached providers, in instantiation order
- private LinkedHashMap svc, ClassLoader cl) {
- service = svc;
- loader = cl;
- reload();
- }
-
- private static void fail(Class service, String msg, Throwable cause)
- throws ServiceConfigurationError
- {
- throw new ServiceConfigurationError(service.getName() + ": " + msg,
- cause);
- }
-
- private static void fail(Class service, String msg)
- throws ServiceConfigurationError
- {
- throw new ServiceConfigurationError(service.getName() + ": " + msg);
- }
-
- private static void fail(Class service, URL u, int line, String msg)
- throws ServiceConfigurationError
- {
- fail(service, u + ":" + line + ": " + msg);
- }
-
- // Parse a single line from the given configuration file, adding the name
- // on the line to the names list.
- //
- private int parseLine(Class service, URL u, BufferedReader r, int lc,
- List
- {
-
- Class service;
- ClassLoader loader;
- Enumeration service, ClassLoader loader) {
- this.service = service;
- this.loader = loader;
- }
-
- public boolean hasNext() {
- if (nextName != null) {
- return true;
- }
- if (configs == null) {
- try {
- String fullName = PREFIX + service.getName();
- if (loader == null)
- configs = ClassLoader.getSystemResources(fullName);
- else
- configs = loader.getResources(fullName);
- } catch (IOException x) {
- fail(service, "Error locating configuration files", x);
- }
- }
- while ((pending == null) || !pending.hasNext()) {
- if (!configs.hasMoreElements()) {
- return false;
- }
- pending = parse(service, configs.nextElement());
- }
- nextName = pending.next();
- return true;
- }
-
- public S next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
- String cn = nextName;
- nextName = null;
- try {
- S p = service.cast(Class.forName(cn, true, loader)
- .newInstance());
- providers.put(cn, p);
- return p;
- } catch (ClassNotFoundException x) {
- fail(service,
- "Provider " + cn + " not found");
- } catch (Throwable x) {
- fail(service,
- "Provider " + cn + " could not be instantiated: " + x,
- x);
- }
- throw new Error(); // This cannot happen
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- }
-
- /**
- * Lazily loads the available providers of this loader's service.
- *
- * 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.
- *
- * iterator() {
- return new Iterator() {
-
- Iterator ServiceLoader load(Class service,
- ClassLoader loader)
- {
- return new ServiceLoader<>(service, loader);
- }
-
- /**
- * Creates a new service loader for the given service type, using the
- * current thread's {@linkplain java.lang.Thread#getContextClassLoader
- * context class loader}.
- *
- *
- *
- * is equivalent to
- *
- *
- * ServiceLoader.load(service)
- *
- * @param service
- * The interface or abstract class representing the service
- *
- * @return A new service loader
- */
- public static
- * ServiceLoader.load(service,
- * Thread.currentThread().getContextClassLoader())
ServiceLoader load(Class service) {
- ClassLoader cl = null; // XXX: Thread.currentThread().getContextClassLoader();
- return ServiceLoader.load(service, cl);
- }
-
- /**
- * Creates a new service loader for the given service type, using the
- * extension class loader.
- *
- *
- *
- *
- * ServiceLoader.load(service, extClassLoader)
ServiceLoader loadInstalled(Class service) {
- ClassLoader cl = ClassLoader.getSystemClassLoader();
- ClassLoader prev = null;
- while (cl != null) {
- prev = cl;
- cl = cl.getParent();
- }
- return ServiceLoader.load(service, prev);
- }
-
- /**
- * Returns a string describing this service.
- *
- * @return A descriptive string
- */
- public String toString() {
- return "java.util.ServiceLoader[" + service.getName() + "]";
- }
-
-}