package com.jxml.quick.recycle;

import java.io.*;
import org.xml.sax.Parser;
import org.xml.sax.helpers.ParserFactory;

/**
 * Manages a pool or reusable Parser objects.
 */
public final class QParserPool
{
    public static String parserClassName=null;
    public static boolean sax2=false;

    static
    {
	String parserName=System.getProperty("org.xml.sax.parser");
	InputStream is=null;
	try
	{
		is=ClassLoader.getSystemResourceAsStream("SAXParserClassName.txt");
	}
	catch(Exception e1)
	{
		is=null;
	}
	if (is!=null)
	{
		try
		{
			is.close();
		}
		catch (Exception e2)
		{
		}
	        setParserClass();
	}
	else if (parserName!=null)
	{
	        setParserClass();
	}
	else
	{
		try
		{
			Class.forName("javax.xml.parsers.SAXParserFactory");
			sax2=JAXP.selectingParser();
			if (!sax2)
			        setParserClass();
		}
		catch (Exception e3)
		{
		        setParserClass();
		}
	}
    }

    // Establish the default parser.
    static void setParserClass()
    {
	    try
	    {
		    // Check for the java option "-Dorg.xml.sax.parser="
		    parserClassName = System.getProperty("org.xml.sax.parser");
		    if (parserClassName==null)
		    {
			try
			{
			    // Look for a file in the classpath called SAXParserClassName.txt
			    InputStream is=ClassLoader.getSystemResourceAsStream("SAXParserClassName.txt");
			    if (is!=null)
			    {
			    	InputStreamReader isr=new InputStreamReader(is);
			    	BufferedReader br=new BufferedReader(isr);
			    	parserClassName=br.readLine().trim();
				is.close();
			    }
			    else
				parserClassName="com.microstar.xml.SAXDriver";
		    	    Class parser=Class.forName(parserClassName);
			}
			catch (Exception x)
			{
			    System.err.println(x.toString());
			    if (parserClassName!=null)
			    {
				System.err.println("Unalbe to use class "+parserClassName);
			    }
			    System.err.println("Defaulting to AElfred");
			    parserClassName="com.microstar.xml.SAXDriver";
			}
		    }
	    }
	    catch(Exception e)
	    {
	    }
    }

	private String parserClass=null;
	private QPool pool=new QPool();

	/**
	 * Create parser objects using the 'org.xml.sax.parser' system property.
	 */
	public QParserPool()
	{
		parserClass=parserClassName;
	}

	/**
	 * Create parser objects of the specified class.
	 */
	public QParserPool(String className)
	{
		parserClass=className;
//System.out.println("PARSER---"+className);
	}

	/**
	 * Allocate a previously used parser. If none exists, create a new one.
	 */
	public synchronized Parser allocate()
		throws ClassNotFoundException, IllegalAccessException, InstantiationException
	{
		Parser parser=(Parser)pool.allocate();
		if (parser!=null)
			return parser;
		if (sax2)
			return JAXP.newParser();
		else if (parserClass==null)
			return ParserFactory.makeParser();
		else
			return ParserFactory.makeParser(parserClass);
	}

	/**
	 * The parser is now available for reuse.
	 */
	public synchronized void release(Parser parser)
	{
		pool.recycle(parser);
	}
}
