![JAR search and dependency download from the Maven repository](/logo.png)
org.granite.util.ServiceLoader Maven / Gradle / Ivy
The newest version!
/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2014 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see .
*/
package org.granite.util;
import java.io.BufferedReader;
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.logging.Level;
import java.util.logging.Logger;
/**
* @author Franck WOLFF
*/
public class ServiceLoader implements Iterable {
// Can't use granite logger here, because service loader can be used to load a specific
// logger implementation (stack overflow...)
private static final Logger jdkLog = Logger.getLogger(ServiceLoader.class.getName());
private final Class service;
private final ClassLoader loader;
private List serviceClassNames;
private Class>[] constructorParameterTypes = new Class>[0];
private Object[] constructorParameters = new Object[0];
private ServiceLoader(Class service, ClassLoader loader, List servicesNames) {
this.service = service;
this.loader = loader;
this.serviceClassNames = servicesNames;
}
public void setConstructorParameters(Class>[] constructorParameterTypes, Object[] constructorParameters) {
if (constructorParameterTypes == null)
constructorParameterTypes = new Class>[0];
if (constructorParameters == null)
constructorParameters = new Object[0];
if (constructorParameterTypes.length != constructorParameters.length)
throw new IllegalArgumentException("constructor types and argurments must have the same size");
this.constructorParameterTypes = constructorParameterTypes;
this.constructorParameters = constructorParameters;
}
public ServicesIterator iterator() {
return new ServicesIterator(loader, serviceClassNames.iterator(), constructorParameterTypes, constructorParameters);
}
public void reload() {
ServiceLoader serviceLoaderTmp = load(service, loader);
this.serviceClassNames = serviceLoaderTmp.serviceClassNames;
}
public static ServiceLoader load(Class service) {
return load(service, Thread.currentThread().getContextClassLoader());
}
public static ServiceLoader load(final Class service, final ClassLoader loader) {
List serviceClassNames = new ArrayList();
try {
// Standard Java platforms.
Enumeration en = loader.getResources("META-INF/services/" + service.getName());
while (en.hasMoreElements())
parse(en.nextElement(), serviceClassNames);
// Android support (META-INF/** files are not included in APK files).
en = loader.getResources("meta_inf/services/" + service.getName());
while (en.hasMoreElements())
parse(en.nextElement(), serviceClassNames);
return new ServiceLoader(service, loader, serviceClassNames);
}
catch (Exception e) {
jdkLog.log(Level.SEVERE, "Could not load services of type " + service, e);
throw new RuntimeException(e);
}
}
private static void parse(URL serviceFile, List serviceClassNames) {
try {
InputStream is = serviceFile.openStream();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String serviceClassName = null;
while ((serviceClassName = reader.readLine()) != null) {
int comment = serviceClassName.indexOf('#');
if (comment >= 0)
serviceClassName = serviceClassName.substring(0, comment);
serviceClassName = serviceClassName.trim();
if (serviceClassName.length() > 0) {
jdkLog.log(Level.FINE, "Adding service " + serviceClassName + " from " + serviceFile);
serviceClassNames.add(serviceClassName);
}
}
}
finally {
is.close();
}
}
catch (Exception e) {
jdkLog.log(Level.SEVERE, "Could not parse service file " + serviceFile, e);
}
}
public static class ServicesIterator implements Iterator {
private final ClassLoader loader;
private final Iterator serviceClassNames;
private final Class>[] constructorParameterTypes;
private final Object[] constructorParameters;
private ServicesIterator(ClassLoader loader, Iterator servicesNames, Class>[] constructorParameterTypes, Object[] constructorParameters) {
this.loader = loader;
this.serviceClassNames = servicesNames;
this.constructorParameterTypes = constructorParameterTypes;
this.constructorParameters = constructorParameters;
}
public boolean hasNext() {
return serviceClassNames.hasNext();
}
public S next() {
String serviceClassName = serviceClassNames.next();
jdkLog.log(Level.FINE, "Loading service " + serviceClassName);
try {
@SuppressWarnings("unchecked")
Class extends S> serviceClass = (Class extends S>)loader.loadClass(serviceClassName);
return serviceClass.getConstructor(constructorParameterTypes).newInstance(constructorParameters);
}
catch (Throwable t) {
jdkLog.log(Level.SEVERE, "Could not load service " + serviceClassName, t);
throw new RuntimeException(t);
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy