/**
 * Copyright (c) 2001, Thai Open Source Software Center Ltd
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 *     Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 
 *     Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 * 
 *     Neither the name of the Thai Open Source Software Center Ltd nor
 *     the names of its contributors may be used to endorse or promote
 *     products derived from this software without specific prior written
 *     permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.relaxng.datatype.helpers;

import org.relaxng.datatype.DatatypeLibraryFactory;
import org.relaxng.datatype.DatatypeLibrary;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.io.Reader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;

/**
 * Discovers the datatype library implementation from the classpath.
 * 
 * <p>
 * The call of the createDatatypeLibrary method finds an implementation
 * from a given datatype library URI at run-time.
 */
public class DatatypeLibraryLoader implements DatatypeLibraryFactory {
  private final Service service = new Service(DatatypeLibraryFactory.class);

  public DatatypeLibrary createDatatypeLibrary(String uri) {
    for (Enumeration e = service.getProviders();
	 e.hasMoreElements();) {
      DatatypeLibraryFactory factory
	= (DatatypeLibraryFactory)e.nextElement();
      DatatypeLibrary library = factory.createDatatypeLibrary(uri);
      if (library != null)
	return library;
    }
    return null;
  }

	private static class Service {
	  private final Class serviceClass;
	  private final Enumeration configFiles;
	  private Enumeration classNames = null;
	  private final Vector providers = new Vector();
	  private Loader loader;

	  private class ProviderEnumeration implements Enumeration {
	    private int nextIndex = 0;

	    public boolean hasMoreElements() {
	      return nextIndex < providers.size() || moreProviders();
	    }

	    public Object nextElement() {
	      try {
		return providers.elementAt(nextIndex++);
	      }
	      catch (ArrayIndexOutOfBoundsException e) {
		throw new NoSuchElementException();
	      }
	    }
	  }

	  private static class Singleton implements Enumeration {
	    private Object obj;
	    private Singleton(Object obj) {
	      this.obj = obj;
	    }

	    public boolean hasMoreElements() {
	      return obj != null;
	    }

	    public Object nextElement() {
	      if (obj == null)
		throw new NoSuchElementException();
	      Object tem = obj;
	      obj = null;
	      return tem;
	    }
	  }

	  // JDK 1.1
	  private static class Loader {
	    Enumeration getResources(String resName) {
	      ClassLoader cl = Loader.class.getClassLoader();
	      URL url;
	      if (cl == null)
		url = ClassLoader.getSystemResource(resName);
	      else
		url = cl.getResource(resName);
	      return new Singleton(url);
	    }

	    Class loadClass(String name) throws ClassNotFoundException {
	      return Class.forName(name);
	    }
	  }

	  // JDK 1.2+
	  private static class Loader2 extends Loader {
	    private ClassLoader cl;

	    Loader2() {
	      cl = Loader2.class.getClassLoader();
	      // If the thread context class loader has the class loader
	      // of this class as an ancestor, use the thread context class
	      // loader.  Otherwise, the thread context class loader
	      // probably hasn't been set up properly, so don't use it.
	      ClassLoader clt = Thread.currentThread().getContextClassLoader();
	      for (ClassLoader tem = clt; tem != null; tem = tem.getParent())
		if (tem == cl) {
		  cl = clt;
		  break;
		}
	    }

	    Enumeration getResources(String resName) {
	      try {
		return cl.getResources(resName);
	      }
	      catch (IOException e) {
		return new Singleton(null);
	      }
	    }

	    Class loadClass(String name) throws ClassNotFoundException {
	      return Class.forName(name, true, cl);
	    }
	  }

	  public Service(Class cls) {
	    try {
	      loader = new Loader2();
	    }
	    catch (NoSuchMethodError e) {
	      loader = new Loader();
	    }
	    serviceClass = cls;
	    String resName = "META-INF/services/" + serviceClass.getName();
	    configFiles = loader.getResources(resName);
	  }

	  public Enumeration getProviders() {
	    return new ProviderEnumeration();
	  }

	  synchronized private boolean moreProviders() {
	    for (;;) {
	      while (classNames == null) {
		if (!configFiles.hasMoreElements())
		  return false;
		classNames = parseConfigFile((URL)configFiles.nextElement());
	      }
	      while (classNames.hasMoreElements()) {
		String className = (String)classNames.nextElement();
		try {
		  Class cls = loader.loadClass(className);
		  Object obj = cls.newInstance();
		  if (serviceClass.isInstance(obj)) {
		    providers.addElement(obj);
		    return true;
		  }
		}
		catch (ClassNotFoundException e) { }
		catch (InstantiationException e) { }
		catch (IllegalAccessException e) { }
		catch (LinkageError e) { }
	      }
	      classNames = null;
	    }
	  }

	  private static final int START = 0;
	  private static final int IN_NAME = 1;
	  private static final int IN_COMMENT = 2;

	  private static Enumeration parseConfigFile(URL url) {
	    try {
	      InputStream in = url.openStream();
	      Reader r;
	      try {
		r = new InputStreamReader(in, "UTF-8");
	      }
	      catch (UnsupportedEncodingException e) {
		r = new InputStreamReader(in, "UTF8");
	      }
	      r = new BufferedReader(r);
	      Vector tokens = new Vector();
	      StringBuffer tokenBuf = new StringBuffer();
	      int state = START;
	      for (;;) {
		int n = r.read();
		if (n < 0)
		  break;
		char c = (char)n;
		switch (c) {
		case '\r':
		case '\n':
		  state = START;
		  break;
		case ' ':
		case '\t':
		  break;
		case '#':
		  state = IN_COMMENT;
		  break;
		default:
		  if (state != IN_COMMENT) {
		    state = IN_NAME;
		    tokenBuf.append(c);
		  }
		  break;
		}
		if (tokenBuf.length() != 0 && state != IN_NAME) {
		  tokens.addElement(tokenBuf.toString());
		  tokenBuf.setLength(0);
		}
	      }
	      if (tokenBuf.length() != 0)
		tokens.addElement(tokenBuf.toString());
	      return tokens.elements();
	    }
	    catch (IOException e) {
	      return null;
	    }
	  }
	}
  
}

