/*
 * Copyright (c) 2004 World Wide Web Consortium,
 *
 * (Massachusetts Institute of Technology, European Research Consortium for
 * Informatics and Mathematics, Keio University). All Rights Reserved. This
 * work is distributed under the W3C(r) Software License [1] 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.
 *
 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
 */


package org.w3c.dom.bootstrap;

import java.util.StringTokenizer;
import java.util.Vector;
import org.w3c.dom.DOMImplementationSource;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementation;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * A factory that enables applications to obtain instances of
 * <code>DOMImplementation</code>.
 *
 * <p>
 * Example:
 * </p>
 *
 * <pre class='example'>
 *  // get an instance of the DOMImplementation registry
 *  DOMImplementationRegistry registry =
 *       DOMImplementationRegistry.newInstance();
 *  // get a DOM implementation the Level 3 XML module
 *  DOMImplementation domImpl =
 *       registry.getDOMImplementation("XML 3.0");
 * </pre>
 *
 * <p>
 * This provides an application with an implementation-independent starting
 * point. DOM implementations may modify this class to meet new security
 * standards or to provide *additional* fallbacks for the list of
 * DOMImplementationSources.
 * </p>
 *
 * @see DOMImplementation
 * @see DOMImplementationSource
 * @since DOM Level 3
 */
public final class DOMImplementationRegistry {
    /**
     * The system property to specify the
     * DOMImplementationSource class names.
     */
    public static final String PROPERTY =
	"org.w3c.dom.DOMImplementationSourceList";
    
    /**
     * Default columns per line.
     */
    private static final int DEFAULT_LINE_LENGTH = 80;
    
    /**
     * The list of DOMImplementationSources.
     */
    private Vector sources;
    
    /**
     * Private constructor.
     * @param srcs Vector List of DOMImplementationSources
     */
    private DOMImplementationRegistry(final Vector srcs) {
	sources = srcs;
    }
    
    /**
     * Obtain a new instance of a <code>DOMImplementationRegistry</code>.
     *

     * The <code>DOMImplementationRegistry</code> is initialized by the
     * application or the implementation, depending on the context, by
     * first checking the value of the Java system property
     * <code>org.w3c.dom.DOMImplementationSourceList</code> and
     * the the service provider whose contents are at
     * "<code>META_INF/services/org.w3c.dom.DOMImplementationSourceList</code>"
     * The value of this property is a white-space separated list of
     * names of availables classes implementing the
     * <code>DOMImplementationSource</code> interface. Each class listed
     * in the class name list is instantiated and any exceptions
     * encountered are thrown to the application.
     *
     * @return an initialized instance of DOMImplementationRegistry
     * @throws ClassNotFoundException
     *     If any specified class can not be found
     * @throws InstantiationException
     *     If any specified class is an interface or abstract class
     * @throws IllegalAccessException
     *     If the default constructor of a specified class is not accessible
     * @throws ClassCastException
     *     If any specified class does not implement
     * <code>DOMImplementationSource</code>
     */
    public static DOMImplementationRegistry newInstance()
	throws
	ClassNotFoundException,
	InstantiationException,
	IllegalAccessException,
	ClassCastException {
	Vector sources = new Vector();
	
	ClassLoader classLoader = getClassLoader();
	// fetch system property:
	String p = getSystemProperty(PROPERTY);
	
	//
	// if property is not specified then use contents of
        // META_INF/org.w3c.dom.DOMImplementationSourceList from classpath
	if (p == null) {
	    p = getServiceValue(classLoader);
	} 
        if (p == null) {
	    //
	    // DOM Implementations can modify here to add *additional* fallback
	    // mechanisms to access a list of default DOMImplementationSources.
	    p = "gnu.xml.dom.ImplementationSource";
	}
	if (p != null) {
	    StringTokenizer st = new StringTokenizer(p);
	    while (st.hasMoreTokens()) {
		String sourceName = st.nextToken();
		// Use context class loader, falling back to Class.forName
		// if and only if this fails...
		Class sourceClass = null;
		if (classLoader != null) {
		    sourceClass = classLoader.loadClass(sourceName);
		} else {
		    sourceClass = Class.forName(sourceName);
		}
		DOMImplementationSource source =
		    (DOMImplementationSource) sourceClass.newInstance();
		sources.addElement(source);
	    }
	}
	return new DOMImplementationRegistry(sources);
    }
    
    /**
     * Return the first implementation that has the desired
     * features, or <code>null</code> if none is found.
     *
     * @param features
     *            A string that specifies which features are required. This is
     *            a space separated list in which each feature is specified by
     *            its name optionally followed by a space and a version number.
     *            This is something like: "XML 1.0 Traversal +Events 2.0"
     * @return An implementation that has the desired features,
     *         or <code>null</code> if none found.
     */
    public DOMImplementation getDOMImplementation(final String features) {
	int size = sources.size();
	String name = null;
	for (int i = 0; i < size; i++) {
	    DOMImplementationSource source =
		(DOMImplementationSource) sources.elementAt(i);
	    DOMImplementation impl = source.getDOMImplementation(features);
	    if (impl != null) {
		return impl;
	    }
	}
	return null;
    }
    
    /**
     * Return a list of implementations that support the
     * desired features.
     *
     * @param features
     *            A string that specifies which features are required. This is
     *            a space separated list in which each feature is specified by
     *            its name optionally followed by a space and a version number.
     *            This is something like: "XML 1.0 Traversal +Events 2.0"
     * @return A list of DOMImplementations that support the desired features.
     */
    public DOMImplementationList getDOMImplementationList(final String features) {
	final Vector implementations = new Vector();
	int size = sources.size();
	for (int i = 0; i < size; i++) {
	    DOMImplementationSource source =
		(DOMImplementationSource) sources.elementAt(i);
	    DOMImplementationList impls =
		source.getDOMImplementationList(features);
	    for (int j = 0; j < impls.getLength(); j++) {
		DOMImplementation impl = impls.item(j);
		implementations.addElement(impl);
	    }
	}
	return new DOMImplementationList() {
		public DOMImplementation item(final int index) {
		    if (index >= 0 && index < implementations.size()) {
			try {
			    return (DOMImplementation)
				implementations.elementAt(index);
			} catch (ArrayIndexOutOfBoundsException e) {
			    return null;
			}
		    }
		    return null;
		}
		
		public int getLength() {
		    return implementations.size();
		}
	    };
    }
    
    /**
     * Register an implementation.
     *
     * @param s The source to be registered, may not be <code>null</code>
     */
    public void addSource(final DOMImplementationSource s) {
	if (s == null) {
	    throw new NullPointerException();
	}
	if (!sources.contains(s)) {
	    sources.addElement(s);
	}
    }
    
    /**
     *
     * Gets a class loader.
     *
     * @return A class loader, possibly <code>null</code>
     */
    private static ClassLoader getClassLoader() {
	try {
	    ClassLoader contextClassLoader = getContextClassLoader();
	    
	    if (contextClassLoader != null) {
		return contextClassLoader;
	    }
	} catch (Exception e) {
	    // Assume that the DOM application is in a JRE 1.1, use the
	    // current ClassLoader
	    return DOMImplementationRegistry.class.getClassLoader();
	}
	return DOMImplementationRegistry.class.getClassLoader();
    }
    
    /**
     * This method attempts to return the first line of the resource
     * META_INF/services/org.w3c.dom.DOMImplementationSourceList
     * from the provided ClassLoader.
     *
     * @param classLoader classLoader, may not be <code>null</code>.
     * @return first line of resource, or <code>null</code>
     */
    private static String getServiceValue(final ClassLoader classLoader) {
	String serviceId = "META-INF/services/" + PROPERTY;
	// try to find services in CLASSPATH
	try {
	    InputStream is = getResourceAsStream(classLoader, serviceId);
	    
	    if (is != null) {
		BufferedReader rd;
		try {
		    rd =
			new BufferedReader(new InputStreamReader(is, "UTF-8"),
					   DEFAULT_LINE_LENGTH);
		} catch (java.io.UnsupportedEncodingException e) {
		    rd =
			new BufferedReader(new InputStreamReader(is),
					   DEFAULT_LINE_LENGTH);
		}		
		String serviceValue = rd.readLine();
		rd.close();
		if (serviceValue != null && serviceValue.length() > 0) {
		    return serviceValue;
		}
	    }
	} catch (Exception ex) {
	    return null;
	}
	return null;
    }
    
    /**
     * A simple JRE (Java Runtime Environment) 1.1 test
     *
     * @return <code>true</code> if JRE 1.1 
     */
    private static boolean isJRE11() {
	try {
	    Class c = Class.forName("java.security.AccessController");
	    // java.security.AccessController existed since 1.2 so, if no
	    // exception was thrown, the DOM application is running in a JRE
	    // 1.2 or higher
	    return false;
	} catch (Exception ex) {
	    // ignore 
	}
	return true;
    }
    
    /**
     * This method returns the ContextClassLoader or <code>null</code> if
     * running in a JRE 1.1
     *
     * @return The Context Classloader
     */
    private static ClassLoader getContextClassLoader() {
	return isJRE11()
	    ? null
	    : (ClassLoader)
 	      AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			ClassLoader classLoader = null;
			try {
			    classLoader =
				Thread.currentThread().getContextClassLoader();
			} catch (SecurityException ex) {
			}
			return classLoader;
		    }
		});
    }
    
    /**
     * This method returns the system property indicated by the specified name
     * after checking access control privileges. For a JRE 1.1, this check is
     * not done.
     * 	 
     * @param name the name of the system property	 
     * @return the system property
     */
    private static String getSystemProperty(final String name) {
	return isJRE11()
	    ? (String) System.getProperty(name)
	    : (String) AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			return System.getProperty(name);
		    }
		});
    }
    
    /**
     * This method returns an Inputstream for the reading resource
     * META_INF/services/org.w3c.dom.DOMImplementationSourceList after checking
     * access control privileges. For a JRE 1.1, this check is not done.
     *
     * @param classLoader classLoader	 
     * @param name the resource 	 
     * @return an Inputstream for the resource specified
     */
    private static InputStream getResourceAsStream(final ClassLoader classLoader,
						   final String name) {
	if (isJRE11()) {
	    InputStream ris;
	    if (classLoader == null) {
		ris = ClassLoader.getSystemResourceAsStream(name);
	    } else {
		ris = classLoader.getResourceAsStream(name);
	    }    
	    return ris;
	} else {
	    return (InputStream)
		AccessController.doPrivileged(new PrivilegedAction() {
			public Object run() {
			    InputStream ris;
			    if (classLoader == null) {
				ris =
				    ClassLoader.getSystemResourceAsStream(name);
			    } else {
				ris = classLoader.getResourceAsStream(name);
			    }
			    return ris;
			}
		    });
	}
    }
}
