/*
* Eoulsan development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public License version 2.1 or
* later and CeCILL-C. This should be distributed with the code.
* If you do not have a copy, see:
*
* http://www.gnu.org/licenses/lgpl-2.1.txt
* http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt
*
* Copyright for this code is held jointly by the Genomic platform
* of the Institut de Biologie de l'École normale supérieure and
* the individual authors. These should be listed in @author doc
* comments.
*
* For more information on the Eoulsan project and its aims,
* or to join the Eoulsan Google group, visit the home page
* at:
*
* http://outils.genomique.biologie.ens.fr/eoulsan
*
*/
package fr.ens.biologie.genomique.eoulsan.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* This class allow to load the list of available resources for a service
* @since 1.2
* @author Laurent Jourdren
*/
public class ServiceListLoader {
private static final String PREFIX = "META-INF/services/";
private final String serviceName;
private final ClassLoader loader;
public static final class Entry {
private final URL url;
private final int lineNumber;
private final String value;
/**
* Get the URL of the file of the entry.
* @return the URL of the file of the etry
*/
public URL getUrl() {
return this.url;
}
/**
* Get line number of the entry.
* @return the line number of the entry
*/
public int getLineNumber() {
return this.lineNumber;
}
/**
* Get he value of the entry.
* @return the value of the entry
*/
public String getValue() {
return this.value;
}
@Override
public String toString() {
return this.getClass().getSimpleName()
+ "{url=" + this.url + ", lineNumber=" + this.lineNumber + ", value="
+ this.value;
}
/**
* Private constructor.
* @param url URL
* @param lineNumber line number
* @param value value
*/
private Entry(final URL url, final int lineNumber, final String value) {
this.url = url;
this.lineNumber = lineNumber;
this.value = value;
}
}
/**
* Get the list of available services.
* @return a list with the entries of the available services
* @throws IOException if an error occurs while reading the list of services
*/
private List<Entry> getServiceEntries() throws IOException {
final String fullName = PREFIX + this.serviceName;
final Enumeration<URL> urls;
// Get the list of urls to the resources files
if (this.loader == null) {
urls = ClassLoader.getSystemResources(fullName);
} else {
urls = this.loader.getResources(fullName);
}
// Parse the URLs files
final List<Entry> result = new ArrayList<>();
for (URL url : Utils.newIterable(urls)) {
parse(url, result);
}
return result;
}
/**
* Parse a resource list.
* @param url URL of the resource list
* @param result the result object
* @throws IOException if an error occurs while reading the list
*/
private void parse(final URL url, final List<Entry> result)
throws IOException {
final InputStream is = url.openStream();
BufferedReader reader = FileUtils.createBufferedReader(is);
int lineNumber = 0;
String line;
while ((line = reader.readLine()) != null) {
lineNumber++;
final String trimLine = line.trim();
if ("".equals(trimLine) || trimLine.startsWith("#")) {
continue;
}
result.add(new Entry(url, lineNumber, trimLine));
}
is.close();
}
//
// Static methods
//
/**
* Get the list of available services.
* @param serviceName name of the service
* @throws IOException if an error occurs while reading the resources
*/
public static final List<String> load(final String serviceName)
throws IOException {
return load(serviceName, null);
}
/**
* Get the list of available services.
* @param serviceName name of the service
* @param loader ClassLoader to use to read resources
* @throws IOException if an error occurs while reading the resources
*/
public static final List<String> load(final String serviceName,
final ClassLoader loader) throws IOException {
final List<Entry> entries = loadEntries(serviceName, loader);
final List<String> result = new ArrayList<>(entries.size());
for (Entry e : entries) {
result.add(e.getValue());
}
return result;
}
/**
* Get the list of available services.
* @param serviceName name of the service
* @throws IOException if an error occurs while reading the resources
*/
public static final List<Entry> loadEntries(final String serviceName)
throws IOException {
return loadEntries(serviceName, null);
}
/**
* Get the list of available services.
* @param serviceName name of the service
* @param loader ClassLoader to use to read resources
* @throws IOException if an error occurs while reading the resources
*/
public static final List<Entry> loadEntries(final String serviceName,
final ClassLoader loader) throws IOException {
return new ServiceListLoader(serviceName, loader).getServiceEntries();
}
//
// Constructor
//
/**
* Public constructor.
* @param serviceName name of the service
* @param loader class loader to use to load resource files
*/
private ServiceListLoader(final String serviceName,
final ClassLoader loader) {
if (serviceName == null) {
throw new NullPointerException("The service name is null");
}
this.loader = loader == null ? this.getClass().getClassLoader() : loader;
this.serviceName = serviceName;
}
}