summaryrefslogtreecommitdiffstats
path: root/luni
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2010-04-06 16:36:51 -0700
committerElliott Hughes <enh@google.com>2010-04-06 16:36:51 -0700
commit64e526d079a7218f984eeaba6ff2feeaadeeaffb (patch)
treef52c323d8aec61cebddaf7485900dff5edede194 /luni
parent75107682f111073add772464a4ed9e9c1bc9bd77 (diff)
downloadlibcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.zip
libcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.tar.gz
libcore-64e526d079a7218f984eeaba6ff2feeaadeeaffb.tar.bz2
Actually use ServiceLoader in places where we had a hard-coded equivalent.
I've also removed a file that was causing us to use this code unnecessarily at run-time to explicitly specify the built-in default PreferencesFactory. I haven't touched Charset, but should come back and fix that too at some point. Change-Id: I3a2145041d048078bdb55ae7b8fa4ec9d8726922
Diffstat (limited to 'luni')
-rw-r--r--luni/src/main/java/java/util/ServiceLoader.java45
1 files changed, 33 insertions, 12 deletions
diff --git a/luni/src/main/java/java/util/ServiceLoader.java b/luni/src/main/java/java/util/ServiceLoader.java
index 2f28dff..335a1db 100644
--- a/luni/src/main/java/java/util/ServiceLoader.java
+++ b/luni/src/main/java/java/util/ServiceLoader.java
@@ -62,6 +62,8 @@ import java.net.URL;
*
* <p>Note that each iteration creates new instances of the various service implementations, so
* any heavily-used code will likely want to cache the known implementations itself and reuse them.
+ * Note also that the candidate classes are instantiated lazily as you call {@code next} on the
+ * iterator: construction of the iterator itself does not instantiate any of the providers.
*
* @param <S> the service class or interface
* @since 1.6
@@ -106,13 +108,17 @@ public final class ServiceLoader<S> implements Iterable<S> {
}
/**
- * Constructs a service loader.
+ * Constructs a service loader. If {@code classLoader} is null, the system class loader
+ * is used.
*
* @param service the service class or interface
- * @param loader the class loader
+ * @param classLoader the class loader
* @return a new ServiceLoader
*/
public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader classLoader) {
+ if (classLoader == null) {
+ classLoader = ClassLoader.getSystemClassLoader();
+ }
return new ServiceLoader<S>(service, classLoader);
}
@@ -120,16 +126,12 @@ public final class ServiceLoader<S> implements Iterable<S> {
services.clear();
try {
String name = "META-INF/services/" + service.getName();
- services.addAll(Collections.list(classLoader().getResources(name)));
+ services.addAll(Collections.list(classLoader.getResources(name)));
} catch (IOException e) {
return;
}
}
- private ClassLoader classLoader() {
- return (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader();
- }
-
/**
* Constructs a service loader, using the current thread's context class loader.
*
@@ -156,6 +158,29 @@ public final class ServiceLoader<S> implements Iterable<S> {
return ServiceLoader.load(service, cl);
}
+ /**
+ * Internal API to support built-in SPIs that check a system property first.
+ * Returns an instance specified by a property with the class' binary name, or null if
+ * no such property is set.
+ * @hide
+ */
+ public static <S> S loadFromSystemProperty(final Class<S> service) {
+ return AccessController.doPrivileged(new PrivilegedAction<S>() {
+ public S run() {
+ try {
+ final String className = System.getProperty(service.getName());
+ if (className != null) {
+ Class<?> c = ClassLoader.getSystemClassLoader().loadClass(className);
+ return (S) c.newInstance();
+ }
+ return null;
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+ });
+ }
+
@Override
public String toString() {
return "ServiceLoader for " + service.getName();
@@ -190,11 +215,7 @@ public final class ServiceLoader<S> implements Iterable<S> {
}
String className = queue.remove();
try {
- if (classLoader == null) {
- return service.cast(Class.forName(className).newInstance());
- } else {
- return service.cast(classLoader.loadClass(className).newInstance());
- }
+ return service.cast(classLoader.loadClass(className).newInstance());
} catch (Exception e) {
throw new ServiceConfigurationError("Couldn't instantiate class " + className, e);
}