package org.herac.tuxguitar.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.apache.log4j.Logger; public class TGServiceReader { /** The Logger for this class. */ public static final transient Logger LOG = Logger .getLogger(TGServiceReader.class); private static final class IteratorImpl implements Iterator<Class<?>> { private Iterator<String> iterator; private ClassLoader loader; private Class<?> spi; private Enumeration<URL> urls; public IteratorImpl(Class<?> spi, ClassLoader loader, Enumeration<URL> urls) { this.spi = spi; this.loader = loader; this.urls = urls; this.initialize(); } public boolean hasNext() { return (this.iterator != null && this.iterator.hasNext()); } private void initialize() { List<String> providers = new ArrayList<String>(); while (this.urls.hasMoreElements()) { URL url = (URL) this.urls.nextElement(); try { BufferedReader reader = new BufferedReader(new InputStreamReader(url .openStream(), "UTF-8")); String line = null; while ((line = reader.readLine()) != null) { String provider = uncommentLine(line).trim(); if (provider != null && provider.length() > 0) { providers.add(provider); } } } catch (UnsupportedEncodingException e) { LOG.error(e); } catch (IOException e) { LOG.error(e); } } this.iterator = providers.iterator(); } public Class<?> next() { if (!hasNext()) { throw new NoSuchElementException(); } try { Class<?> provider = (Class<?>) this.loader.loadClass( this.iterator.next()).newInstance(); if (this.spi.isInstance(provider)) { return provider; } } catch (Throwable throwable) { LOG.error(throwable); } throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } private String uncommentLine(String line) { int index = line.indexOf('#'); if (index >= 0) { return (line.substring(0, index)); } return line; } } private static final String SERVICE_PATH = new String("META-INF/services/"); public static Iterator<Class<?>> lookupProviders(Class<?> spi) { return TGServiceReader.lookupProviders(spi, TGClassLoader.instance() .getClassLoader()); } public static Iterator<Class<?>> lookupProviders(Class<?> spi, ClassLoader loader) { try { if (spi == null || loader == null) { throw new IllegalArgumentException(); } return new IteratorImpl(spi, loader, loader.getResources(SERVICE_PATH + spi.getName())); } catch (IOException ioex) { return Collections.EMPTY_LIST.iterator(); } } }