/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.jelly.parser;

import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.collections.ArrayStack;

import org.apache.commons.jelly.JellyContext;
import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.Tag;
import org.apache.commons.jelly.TagLibrary;
import org.apache.commons.jelly.impl.CompositeTextScriptBlock;
import org.apache.commons.jelly.impl.ExpressionScript;
import org.apache.commons.jelly.impl.StaticTag;
import org.apache.commons.jelly.impl.ScriptBlock;
import org.apache.commons.jelly.impl.StaticTagScript;
import org.apache.commons.jelly.impl.TagFactory;
import org.apache.commons.jelly.impl.TagScript;
import org.apache.commons.jelly.impl.TextScript;
import org.apache.commons.jelly.util.ClassLoaderUtils;
import org.apache.commons.jelly.expression.CompositeExpression;
import org.apache.commons.jelly.expression.ConstantExpression;
import org.apache.commons.jelly.expression.Expression;
import org.apache.commons.jelly.expression.ExpressionFactory;
import org.apache.commons.jelly.expression.jexl.JexlExpressionFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;

/** <p><code>XMLParser</code> parses the XML Jelly format.
 * The SAXParser and XMLReader portions of this code come from Digester.</p>
 *
 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 * @version $Revision$
 */
public class XMLParser extends DefaultHandler {

    /**
     * Share the Jelly properties across parsers
     */
    private static Properties jellyProperties;


    /** JellyContext which is used to locate tag libraries*/
    private JellyContext context = new JellyContext();

    /** the expression factory used to evaluate tag attributes */
    private ExpressionFactory expressionFactory;

    /** The current script block */
    private ScriptBlock script;

    /** The current, parent tagScript */
    private TagScript tagScript;

    /** The stack of body scripts. */
    private ArrayStack scriptStack = new ArrayStack();

    /** The stack of tagScripts - use ArrayList as it allows null. */
    private ArrayList tagScriptStack = new ArrayList();

    /** The current text buffer where non-custom tags get written */
    private StringBuffer textBuffer;

    /**
     * The class loader to use for instantiating application objects.
     * If not specified, the context class loader, or the class loader
     * used to load XMLParser itself, is used, based on the value of the
     * <code>useContextClassLoader</code> variable.
     */
    protected ClassLoader classLoader = null;

    /**
     * Do we want to use the Context ClassLoader when loading classes
     * for instantiating new objects?  Default is <code>false</code>.
     */
    protected boolean useContextClassLoader = false;

    /**
     * The application-supplied error handler that is notified when parsing
     * warnings, errors, or fatal errors occur.
     */
    protected ErrorHandler errorHandler = null;

    /**
     * The SAXParserFactory that is created the first time we need it.
     */
    protected static SAXParserFactory factory = null;

    /**
     * The SAXParser we will use to parse the input stream.
     */
    protected SAXParser parser = null;

    /**
     * The XMLReader used to parse digester rules.
     */
    protected XMLReader reader = null;

    /**
     * The Locator associated with our parser.
     */
    protected Locator locator = null;

    /**
     * Registered namespaces we are currently processing.  The key is the
     * namespace prefix that was declared in the document.  The value is an
     * ArrayStack of the namespace URIs this prefix has been mapped to --
     * the top Stack element is the most current one.  (This architecture
     * is required because documents can declare nested uses of the same
     * prefix for different Namespace URIs).
     */
    protected Map namespaces = new HashMap();

    /** The Map of the namespace prefix -&gt; URIs defined for the current element */
    private Map elementNamespaces;

    /**
     * The name of the file being parsed that is passed to the TagScript objects
     * for error reporting
     */
    private String fileName;

    /**
     * Do we want to use a validating parser?
     */
    protected boolean validating = false;

    /** Flag to indicate if this object has been configured */
    private boolean configured;

    /**
     * when not null, set the default namespace for
     * unprefixed elements via the DefaultNamespaceFilter
     * class
     */
    private String defaultNamespaceURI = null;

    /**
     * The Log to which logging calls will be made.
     */
    private Log log = LogFactory.getLog(XMLParser.class);

    /**
     * Construct a new XMLParser with default properties.
     */
    public XMLParser() {
    }

    /**
     * Construct a new XMLParser, allowing a SAXParser to be passed in.  This
     * allows XMLParser to be used in environments which are unfriendly to
     * JAXP1.1 (such as WebLogic 6.0).  Thanks for the request to change go to
     * James House (james@interobjective.com).  This may help in places where
     * you are able to load JAXP 1.1 classes yourself.
     */
    public XMLParser(SAXParser parser) {
        this.parser = parser;
    }

    /**
     * Construct a new XMLParser, allowing an XMLReader to be passed in.  This
     * allows XMLParser to be used in environments which are unfriendly to
     * JAXP1.1 (such as WebLogic 6.0).  Note that if you use this option you
     * have to configure namespace and validation support yourself, as these
     * properties only affect the SAXParser and empty constructor.
     */
    public XMLParser(XMLReader reader) {
        this.reader = reader;
    }

    /**
     * Parse the content of the specified file using this XMLParser.  Returns
     * the root element from the object stack (if any).
     *
     * @param file File containing the XML data to be parsed
     *
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public Script parse(File file) throws IOException, SAXException {
        return parse(file.toURL());
    }

    /**
     * Parse the content of the specified file using this XMLParser.  Returns
     * the root element from the object stack (if any).
     *
     * @param url URL containing the XML data to be parsed
     *
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public Script parse(URL url) throws IOException, SAXException {
        ensureConfigured();
        this.fileName = url.toString();

        InputSource source = new InputSource(url.toString());

        getXMLReader().parse(source);
        return script;
    }

    /**
     * Parse the content of the specified input source using this XMLParser.
     * Returns the root element from the object stack (if any).
     *
     * @param input Input source containing the XML data to be parsed
     *
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public Script parse(InputSource input) throws IOException, SAXException {
        ensureConfigured();
        this.fileName = input.getSystemId();
        getXMLReader().parse(input);
        return script;
    }

    /**
     * Parse the content of the specified input stream using this XMLParser.
     * Returns the root element from the object stack (if any).
     * (Note: if reading a File or URL, use one of the URL-based
     * parse methods instead.  This method will not be able
     * to resolve any relative paths inside a DTD.)
     *
     * @param input  Input stream containing the XML data to be parsed
     * @return
     * @throws IOException
     *                   if an input/output error occurs
     * @throws SAXException
     *                   if a parsing exception occurs
     */
    public Script parse(InputStream input) throws IOException, SAXException {
        ensureConfigured();
        this.fileName = getCurrentURI();
        getXMLReader().parse(new InputSource(input));
        return script;
    }

    /**
     * Parse the content of the specified reader using this XMLParser.
     * Returns the root element from the object stack (if any).
     * (Note: if reading a File or URL, use one of the URL-based
     * parse methods instead.  This method will not be able
     * to resolve any relative paths inside a DTD.)
     *
     * @param reader Reader containing the XML data to be parsed
     * @return
     * @throws IOException
     *                   if an input/output error occurs
     * @throws SAXException
     *                   if a parsing exception occurs
     */
    public Script parse(Reader reader) throws IOException, SAXException {
        ensureConfigured();
        this.fileName = getCurrentURI();
        getXMLReader().parse(new InputSource(reader));
        return script;
    }

    /**
     * Parse the content of the specified URI using this XMLParser.
     * Returns the root element from the object stack (if any).
     *
     * @param uri URI containing the XML data to be parsed
     *
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public Script parse(String uri) throws IOException, SAXException {
        ensureConfigured();
        this.fileName = uri;
        getXMLReader().parse(uri);
        return script;
    }

    /**
     * Return the currently mapped namespace URI for the specified prefix,
     * if any; otherwise return <code>null</code>.  These mappings come and
     * go dynamically as the document is parsed.
     *
     * @param prefix Prefix to look up
     */
    public String findNamespaceURI(String prefix) {
        ArrayStack stack = (ArrayStack) namespaces.get(prefix);
        if (stack == null) {
            return (null);
        }
        try {
            return ((String) stack.peek());
        }
        catch (EmptyStackException e) {
            return (null);
        }
    }

    // Properties
    //-------------------------------------------------------------------------
    public JellyContext getContext() {
        return context;
    }

    public void setContext(JellyContext context) {
        this.context = context;
    }

    /**
     * Set the jelly namespace to use for unprefixed elements.
     * Will be overridden by an explicit namespace in the
     * XML document.
     *
     * @param namespace jelly namespace to use (e.g. 'jelly:core')
     */
    public void setDefaultNamespaceURI(String namespace) {
        this.defaultNamespaceURI = namespace;
    }

    /**
     * Return the class loader to be used for instantiating application objects
     * when required.  This is determined based upon the following rules:
     * <ul>
     * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
     * <li>The thread context class loader, if it exists and the
     *     <code>useContextClassLoader</code> property is set to true</li>
     * <li>The class loader used to load the XMLParser class itself.
     * </ul>
     */
    public ClassLoader getClassLoader() {
        return ClassLoaderUtils.getClassLoader(classLoader, useContextClassLoader, getClass());
    }

    /**
     * Set the class loader to be used for instantiating application objects
     * when required.
     *
     * @param classLoader The new class loader to use, or <code>null</code>
     *  to revert to the standard rules
     */
    public void setClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    /**
     * Return the boolean as to whether the context classloader should be used.
     */
    public boolean getUseContextClassLoader() {
        return useContextClassLoader;
    }

    /**
     * Determine whether to use the Context ClassLoader (the one found by
     * calling <code>Thread.currentThread().getContextClassLoader()</code>)
     * to resolve/load classes.  If not
     * using Context ClassLoader, then the class-loading defaults to
     * using the calling-class' ClassLoader.
     *
     * @param use determines whether to use JellyContext ClassLoader.
     */
    public void setUseContextClassLoader(boolean use) {
        useContextClassLoader = use;
    }

    /**
     * Return the error handler for this XMLParser.
     */
    public ErrorHandler getErrorHandler() {
        return (this.errorHandler);
    }

    /**
     * Set the error handler for this XMLParser.
     *
     * @param errorHandler The new error handler
     */
    public void setErrorHandler(ErrorHandler errorHandler) {
        this.errorHandler = errorHandler;
    }

    /**
     * Return the current Logger associated with this instance of the XMLParser
     */
    public Log getLogger() {
        return log;
    }

    /**
     * Set the current logger for this XMLParser.
     */
    public void setLogger(Log log) {
        this.log = log;
    }

    /**
     * Locates an expression factory by looking at the TagLibrary for the specified
     * tag and falling back by creating one.  If the current tag is a StaticTag (IE
     * has no TagLibrary) then continues up the stack looking for a valid one.
     * @param tagScript
     * @return the expression factory used to evaluate tag attributes
     */
    public ExpressionFactory getExpressionFactory(TagScript tagScript) {
    	// Check the tag library
    	TagLibrary tagLibrary = null;
    	if (tagScript != null)
    		tagLibrary = tagScript.getTagLibrary();

    	// If the tagScript is a StaticTag, then go up the stack looking for a
    	//	tagScript that belongs to a real TagLibrary
    	if (tagLibrary == null && tagScript instanceof StaticTagScript)
    		for (int i = tagScriptStack.size() - 1; i > -1; i--) {
    			TagScript script = (TagScript)tagScriptStack.get(i);
    			tagLibrary = script.getTagLibrary();
    			if (tagLibrary != null)
    				break;
    			if (!(script instanceof StaticTagScript))
    				break;
    		}
    	if (tagLibrary != null) {
    		ExpressionFactory factory = tagLibrary.getExpressionFactory();
    		if (factory != null)
    			return factory;
    	}
        if (expressionFactory == null) {
            expressionFactory = createExpressionFactory();
        }
        return expressionFactory;
    }

    /** Sets the expression factory used to evaluate tag attributes */
    public void setExpressionFactory(ExpressionFactory expressionFactory) {
        this.expressionFactory = expressionFactory;
    }

    /**
     * Called to create an instance of the ExpressionFactory (@see getExpressionFactory)
     * @return
     */
    protected ExpressionFactory createExpressionFactory() {
        return new JexlExpressionFactory();
    }

    /**
     * Creates an expression, using the ExpressionFactory returned by getExpressionFactory();
     * the default implementation defers to the TagLibrary to create the Expression
     * @param attributeName
     * @param value
     * @return
     * @throws JellyException
     */
    public Expression createExpression(TagScript script, String attributeName, String value) throws JellyException {
    	ExpressionFactory factory = getExpressionFactory(script);
    	TagLibrary tagLibrary = script.getTagLibrary();
    	if (tagLibrary != null)
    		return tagLibrary.createExpression(factory, script, attributeName, value);
       	return CompositeExpression.parse(value, factory);
    }

    /**
     * Return the SAXParser we will use to parse the input stream.  If there
     * is a problem creating the parser, return <code>null</code>.
     */
    public SAXParser getParser() {
        // Return the parser we already created (if any)
        if (parser != null) {
            return (parser);
        }
        // Create and return a new parser
        synchronized (this) {
            try {
                if (factory == null) {
                    factory = SAXParserFactory.newInstance();
                }
                factory.setNamespaceAware(true);
                factory.setValidating(validating);
                parser = factory.newSAXParser();
                return (parser);
            }
            catch (Exception e) {
                log.error("XMLParser.getParser: ", e);
                return (null);
            }
        }
    }

    /**
     * By setting the reader in the constructor, you can bypass JAXP and
     * be able to use digester in Weblogic 6.0.
     *
     * @deprecated Use getXMLReader() instead, which can throw a
     *  SAXException if the reader cannot be instantiated
     */
    public XMLReader getReader() {
        try {
            return (getXMLReader());
        }
        catch (SAXException e) {
            log.error("Cannot get XMLReader", e);
            return (null);
        }
    }

    /**
     * Return the XMLReader to be used for parsing the input document.
     *
     * @throws SAXException if no XMLReader can be instantiated
     */
    public synchronized XMLReader getXMLReader() throws SAXException {
        if (reader == null) {
            reader = getParser().getXMLReader();
            if (this.defaultNamespaceURI != null) {
                reader = new DefaultNamespaceFilter(this.defaultNamespaceURI,reader);
            }
        }
        //set up the parse
        reader.setContentHandler(this);
        reader.setDTDHandler(this);
        //reader.setEntityResolver(this);
        reader.setErrorHandler(this);

        return reader;
    }

    /**
     * Return the validating parser flag.
     */
    public boolean getValidating() {
        return (this.validating);
    }

    /**
     * Set the validating parser flag.  This must be called before
     * <code>parse()</code> is called the first time.
     *
     * @param validating The new validating parser flag.
     */
    public void setValidating(boolean validating) {
        this.validating = validating;
    }


    /**
     * Returns the script that has just been created if this class is used
     * as a SAX ContentHandler and passed into some XML processor or parser.
     *
     * @return the ScriptBlock created if SAX events are piped into this class,
     * which must include a startDocument() and endDocument()
     */
    public ScriptBlock getScript() {
        return script;
    }


    // ContentHandler interface
    //-------------------------------------------------------------------------
    /**
     * Process notification of the beginning of the document being reached.
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void startDocument() throws SAXException {
        script = new ScriptBlock();
        textBuffer = new StringBuffer();
        tagScript = null;
        scriptStack.clear();
        tagScriptStack.clear();
    }

    /**
     * Process notification of the end of the document being reached.
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void endDocument() throws SAXException {
        textBuffer = null;
    }

    /**
     * Process notification of the start of an XML element being reached.
     *
     * @param namespaceURI The Namespace URI, or the empty string if the
     *   element has no Namespace URI or if Namespace processing is not
     *   being performed.
     * @param localName The local name (without prefix), or the empty
     *   string if Namespace processing is not being performed.
     * @param qName The qualified name (with prefix), or the empty
     *   string if qualified names are not available.\
     * @param list The attributes attached to the element. If there are
     *   no attributes, it shall be an empty Attributes object.
     * @throws SAXException if a parsing error is to be reported
     */
    public void startElement(
        String namespaceURI,
        String localName,
        String qName,
        Attributes list)
        throws SAXException {

        try {
            // add check to ensure namespace URI is "" for no namespace
            if ( namespaceURI == null ) {
                namespaceURI = "";
            }

            // if this is a tag then create a script to run it
            // otherwise pass the text to the current body
            TagScript newTagScript = createTag(namespaceURI, localName, list);
            if (newTagScript == null) {
                newTagScript = createStaticTag(namespaceURI, localName, qName, list);
            }
            tagScript = newTagScript;
            tagScriptStack.add(tagScript);
            if (tagScript != null) {
                // set the line number details
                if ( locator != null ) {
                    tagScript.setLocator(locator);
                }
                // sets the file name element names
                if (fileName != null)
                	tagScript.setFileName(fileName);
                tagScript.setElementName(qName);
                tagScript.setLocalName(localName);

                if (textBuffer.length() > 0) {
                    addTextScript(textBuffer.toString());
                    textBuffer.setLength(0);
                }
                script.addScript(tagScript);
                // start a new body
                scriptStack.push(script);
                script = new ScriptBlock();
                tagScript.setTagBody(script);
            }
            else {
                // XXXX: might wanna handle empty elements later...
                textBuffer.append("<");
                textBuffer.append(qName);
                int size = list.getLength();
                for (int i = 0; i < size; i++) {
                    textBuffer.append(" ");
                    textBuffer.append(list.getQName(i));
                    textBuffer.append("=");
                    textBuffer.append("\"");
                    textBuffer.append(list.getValue(i));
                    textBuffer.append("\"");
                }
                textBuffer.append(">");
            }
        }
        catch (SAXException e) {
            throw e;
        }
        catch (Exception e) {
            log.error( "Caught exception: " + e, e );
            throw new SAXException( "Runtime Exception: " + e, e );
        }
    }

    /**
     * Process notification of character data received from the body of
     * an XML element.
     *
     * @param buffer The characters from the XML document
     * @param start Starting offset into the buffer
     * @param length Number of characters from the buffer
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void characters(char buffer[], int start, int length)
        throws SAXException {
        textBuffer.append(buffer, start, length);
    }

    /**
     * Process notification of the end of an XML element being reached.
     *
     * @param namespaceURI The Namespace URI, or the empty string if the
     *   element has no Namespace URI or if Namespace processing is not
     *   being performed.
     * @param localName The local name (without prefix), or the empty
     *   string if Namespace processing is not being performed.
     * @param qName The qualified XML 1.0 name (with prefix), or the
     *   empty string if qualified names are not available.
     * @throws SAXException if a parsing error is to be reported
     */
    public void endElement(String namespaceURI, String localName, String qName)
        throws SAXException {
        try {
            tagScript = (TagScript) tagScriptStack.remove(tagScriptStack.size() - 1);
            if (tagScript != null) {
                if (textBuffer.length() > 0) {
                    addTextScript(textBuffer.toString());
                    textBuffer.setLength(0);
                }
                script = (ScriptBlock) scriptStack.pop();
            }
            else {
                textBuffer.append("</");
                textBuffer.append(qName);
                textBuffer.append(">");
            }

            // now lets set the parent tag variable
            if ( tagScriptStack.isEmpty() ) {
                tagScript = null;
            }
            else {
                tagScript = (TagScript) tagScriptStack.get(tagScriptStack.size() - 1);
            }
        } catch (Exception e) {
            log.error( "Caught exception: " + e, e );
            throw new SAXException( "Runtime Exception: " + e, e );
        }
    }

    /**
     * Process notification that a namespace prefix is coming in to scope.
     *
     * @param prefix Prefix that is being declared
     * @param namespaceURI Corresponding namespace URI being mapped to
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void startPrefixMapping(String prefix, String namespaceURI)
        throws SAXException {
        // Register this prefix mapping
        ArrayStack stack = (ArrayStack) namespaces.get(prefix);
        if (stack == null) {
            stack = new ArrayStack();
            namespaces.put(prefix, stack);
        }
        stack.push(namespaceURI);

        if ( elementNamespaces == null ) {
            elementNamespaces = new HashMap();
        }
        elementNamespaces.put(prefix, namespaceURI);
    }

    /**
     * Process notification that a namespace prefix is going out of scope.
     *
     * @param prefix Prefix that is going out of scope
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void endPrefixMapping(String prefix) throws SAXException {
        // Deregister this prefix mapping
        ArrayStack stack = (ArrayStack) namespaces.get(prefix);
        if (stack == null) {
            return;
        }
        try {
            stack.pop();
            if (stack.empty()) {
                namespaces.remove(prefix);
            }
        }
        catch (EmptyStackException e) {
            throw createSAXException("endPrefixMapping popped too many times");
        }
    }

    /**
     * Process notification of ignorable whitespace received from the body of
     * an XML element.
     *
     * @param buffer The characters from the XML document
     * @param start Starting offset into the buffer
     * @param len Number of characters from the buffer
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void ignorableWhitespace(char buffer[], int start, int len)
        throws SAXException {
        ; // No processing required
    }

    /**
     * Process notification of a processing instruction that was encountered.
     *
     * @param target The processing instruction target
     * @param data The processing instruction data (if any)
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void processingInstruction(String target, String data)
        throws SAXException {
        ; // No processing is required
    }

    /**
     * Set the document locator associated with our parser.
     *
     * @param locator The new locator
     */
    public void setDocumentLocator(Locator locator) {
        this.locator = locator;
    }

    /**
     * Process notification of a skipped entity.
     *
     * @param name Name of the skipped entity
     *
     * @throws SAXException if a parsing error is to be reported
     */
    public void skippedEntity(String name) throws SAXException {
        ; // No processing required
    }


    // DTDHandler interface
    //-------------------------------------------------------------------------

    /**
     * Receive notification of a notation declaration event.
     *
     * @param name The notation name
     * @param publicId The public identifier (if any)
     * @param systemId The system identifier (if any)
     */
    public void notationDecl(String name, String publicId, String systemId) {
    }

    /**
     * Receive notification of an unparsed entity declaration event.
     *
     * @param name The unparsed entity name
     * @param publicId The public identifier (if any)
     * @param systemId The system identifier (if any)
     * @param notation The name of the associated notation
     */
    public void unparsedEntityDecl(
        String name,
        String publicId,
        String systemId,
        String notation) {
    }


    // ErrorHandler interface
    //-------------------------------------------------------------------------

    /**
     * Forward notification of a parsing error to the application supplied
     * error handler, if any, otherwise throw a SAXException with the error.
     *
     * @param exception The error information
     *
     * @throws SAXException if a parsing exception occurs
     */
    public void error(SAXParseException exception) throws SAXException {
        log.error(
            "Parse Error at line "
                + exception.getLineNumber()
                + " column "
                + exception.getColumnNumber()
                + ": "
                + exception.getMessage(),
            exception);
        if (errorHandler != null) {
            errorHandler.error(exception);
        } else {
            throw exception;
        }
    }

    /**
     * Forward notification of a fatal parsing error to the application
     * supplied error handler, if any, otherwise throw a SAXException with the error.
     *
     * @param exception The fatal error information
     *
     * @throws SAXException if a parsing exception occurs
     */
    public void fatalError(SAXParseException exception) throws SAXException {
        log.error(
            "Parse Fatal Error at line "
                + exception.getLineNumber()
                + " column "
                + exception.getColumnNumber()
                + ": "
                + exception.getMessage(),
            exception);
        if (errorHandler != null) {
            errorHandler.fatalError(exception);
        } else {
            throw exception;
        }
    }

    /**
     * Forward notification of a parse warning to the application supplied
     * error handler (if any).  Unlike XMLParser.error(SAXParseException) and
     * XMLParser.fatalError(SAXParseException), this implementation will
     * NOT throw a SAXException by default if no error handler is supplied.
     *
     * @param exception The warning information
     *
     * @throws SAXException if a parsing exception occurs
     */
    public void warning(SAXParseException exception) throws SAXException {
        log.error(
            "Parse Warning at line "
                + exception.getLineNumber()
                + " column "
                + exception.getColumnNumber()
                + ": "
                + exception.getMessage(),
            exception);
        if (errorHandler != null) {
            errorHandler.warning(exception);
        }
    }

    // Implementation methods
    //-------------------------------------------------------------------------
    /**
     * If this object has not been configured then register the default
     * namespaces
     */
    private void ensureConfigured() {
        if (!configured) {
            configure();
            configured = true;
        }
    }

    /**
     * This method is called only once before parsing occurs
     * which allows tag libraries to be registered and so forth
     */
    protected void configure() {
        // load the properties file of libraries available
        Properties properties = getJellyProperties();
        for (Iterator iter = properties.entrySet().iterator(); iter.hasNext();) {
            Map.Entry entry = (Map.Entry) iter.next();
            String uri = (String) entry.getKey();
            String className = (String) entry.getValue();
            String libraryURI = "jelly:" + uri;

            // don't overload any Mock Tags already
            if ( ! context.isTagLibraryRegistered(libraryURI) ) {
                context.registerTagLibrary(libraryURI, className);
            }
        }
    }


    /**
     * A helper method which loads the static Jelly properties once on startup
     */
    protected synchronized Properties getJellyProperties() {
        if (jellyProperties == null) {
            jellyProperties = new Properties();

            InputStream in = null;
            URL url =
                getClassLoader().getResource("src/main/resources/org/apache/commons/jelly/jelly.properties");
            if (url != null) {
                log.debug("Loading Jelly default tag libraries from: " + url);
                try {
                    in = url.openStream();
                    jellyProperties .load(in);
                }
                catch (IOException e) {
                    log.error("Could not load jelly properties from: " + url + ". Reason: " + e, e);
                }
                finally {
                    try {
                        in.close();
                    }
                    catch (Exception e) {
                        if (log.isDebugEnabled()) log.debug("error closing jelly.properties", e);
                    }
                }
            }
        }
        return jellyProperties;
    }

    /**
     * Factory method to create new Tag script for the given namespaceURI and name or
     * return null if this is not a custom Tag.
     */
    protected TagScript createTag(
        String namespaceURI,
        String localName,
        Attributes list)
        throws SAXException {
        try {
            // use the URI to load a taglib
            TagLibrary taglib = context.getTagLibrary(namespaceURI);
            if (taglib == null) {
                if (namespaceURI != null && namespaceURI.startsWith("jelly:")) {
                    String uri = namespaceURI.substring(6);
                    // try to find the class on the classpath
                    try {
                        Class taglibClass = getClassLoader().loadClass(uri);
                        taglib = (TagLibrary) taglibClass.newInstance();
                        context.registerTagLibrary(namespaceURI, taglib);
                    }
                    catch (ClassNotFoundException e) {
                        throw createSAXException("Could not load class: " + uri + " so taglib instantiation failed", e);
                    }
                    catch (IllegalAccessException e) {
                        throw createSAXException("Constructor for class is not accessible: " + uri + " so taglib instantiation failed",e);
                    }
                    catch (InstantiationException e) {
                        throw createSAXException("Class could not be instantiated: " + uri + " so taglib instantiation failed",e);
                    }
                    catch (ClassCastException e) {
                        throw createSAXException("Class is not a TagLibrary: " + uri + " so taglib instantiation failed",e);
                    }
                }
            }
            if (taglib != null) {
                TagScript script = taglib.createTagScript(localName, list);
                if ( script != null ) {
                    configureTagScript(taglib, script);

                    // clone the attributes to keep them around after this parse
                    script.setSaxAttributes(new AttributesImpl(list));

                    // now iterate through through the expressions
                    int size = list.getLength();
                    for (int i = 0; i < size; i++) {
                        String attributeName = list.getLocalName(i);
                        // Fix for JELLY-184 where the xmlns attributes have a blank name and cause
                        //	an exception later on
                        if (attributeName.length() == 0)
                        	continue;
                        String attributeValue = list.getValue(i);
                        Expression expression =
                            createExpression(script,
                                attributeName,
                                attributeValue);
//                        Expression expression =
//                            taglib.createExpression(
//                                getExpressionFactory(),
//                                script,
//                                attributeName,
//                                attributeValue);
                        if (expression == null) {
                            expression = createConstantExpression(localName, attributeName, attributeValue);
                        }
                        script.addAttribute(attributeName, expression);
                    }
                } else if (!taglib.isAllowUnknownTags())
                    throw new JellyException("Unrecognized tag called " + localName + " in TagLibrary " + namespaceURI);
                return script;
            }
            return null;
        }
        catch (Exception e) {
            log.warn(
                "Could not create taglib or URI: " + namespaceURI + " tag name: " + localName,
                e);
            throw createSAXException(e);
        }
    }


    /**
     * Factory method to create a static Tag that represents some static content.
     */
    protected TagScript createStaticTag(
        final String namespaceURI,
        final String localName,
        final String qName,
        Attributes list)
        throws SAXException {
        try {
            //StaticTag tag = new StaticTag( namespaceURI, localName, qName );
            StaticTagScript script = new StaticTagScript(
                new TagFactory() {
                    public Tag createTag(String name, Attributes attributes) {
                        return new StaticTag( namespaceURI, localName, qName );
                    }
                }
            );
            configureTagScript(script);

            // now iterate through through the expressions
            int size = list.getLength();
            for (int i = 0; i < size; i++) {
                String attributeValue = list.getValue(i);
                Expression expression = createExpression(script, null, attributeValue);
//                Expression expression = CompositeExpression.parse(
//                        attributeValue, getExpressionFactory()
//                    );
                String attrQName = list.getQName(i);
                int p = attrQName.indexOf(':');
                String prefix = p>=0 ?
                        attrQName.substring(0,p):
                        "";
                script.addAttribute(list.getLocalName(i),
                        prefix, list.getURI(i), expression);
            }
            return script;
        }
        catch (Exception e) {
            log.warn(
                "Could not create static tag for URI: "
                    + namespaceURI
                    + " tag name: "
                    + localName,
                e);
            throw createSAXException(e);
        }
    }

    /**
     * Configure a newly created TagScript instance before any Expressions are created;
     * see configureTagScript(TagScript) for StaticTags
     * @param tagLibrary the TagLibrary that created the TagScript
     * @param aTagScript the TagScript that's just been created
     */
    protected void configureTagScript(TagLibrary tagLibrary,  TagScript aTagScript) {
        // Set the TagLibrary that created the script
        aTagScript.setTagLibrary(tagLibrary);

        configureTagScript(aTagScript);
    }

    /**
     * Configure a newly created TagScript instance before any Expressions are created
     * @param aTagScript
     */
    protected void configureTagScript(TagScript aTagScript) {
        // set parent relationship...
        aTagScript.setParent(this.tagScript);

        // set the namespace Map
        if ( elementNamespaces != null ) {
            aTagScript.setTagNamespacesMap( elementNamespaces );
            elementNamespaces = null;
        }
    }

    /**
     * Adds the text to the current script block parsing any embedded
     * expressions into ExpressionScript objects.
     */
    protected void addTextScript(String text) throws JellyException {
    	Expression expression = createExpression(tagScript, "", text);
        addExpressionScript(script, expression);
    }


    /**
     * Adds the given Expression object to the current Script.
     */
    protected void addExpressionScript(ScriptBlock script, Expression expression) {
        if ( expression instanceof ConstantExpression ) {
            ConstantExpression constantExpression
                = (ConstantExpression) expression;
            Object value = constantExpression.getValue();
            if ( value != null ) {
                script.addScript(new TextScript( value.toString() ));
            }
        }
        else
        if ( expression instanceof CompositeExpression ) {
            CompositeTextScriptBlock newBlock = new CompositeTextScriptBlock();
            script.addScript(newBlock);

            CompositeExpression compositeExpression
                = (CompositeExpression) expression;
            Iterator iter = compositeExpression.getExpressions().iterator();
            while (iter.hasNext()) {
                addExpressionScript( newBlock, (Expression) iter.next() );
            }
        }
        else {
            script.addScript(new ExpressionScript(expression));
        }
    }

    protected Expression createConstantExpression(
        String tagName,
        String attributeName,
        String attributeValue)  {
        return new ConstantExpression(attributeValue);
    }

    /**
     * @return the current context URI as a String or null if there is no
     * current context defined on the JellyContext
     */
    protected String getCurrentURI() {
        URL url = this.getContext().getCurrentURL();
        return (url != null) ? url.toString() : null;
    }

    /**
     * Create a SAX exception which also understands about the location in
     * the file where the exception occurs
     *
     * @return the new exception
     */
    protected SAXException createSAXException(String message, Exception e) {
        log.warn("Underlying exception: " + e);
        if (e != null) {
            e.printStackTrace();
        }
        if (locator != null) {
            String error =
                "Error at ("
                    + locator.getLineNumber()
                    + ", "
                    + locator.getColumnNumber()
                    + "): "
                    + message;
            if (e != null) {
                return new SAXParseException(error, locator, e);
            }
            else {
                return new SAXParseException(error, locator);
            }
        }
        log.error("No Locator!");
        if (e != null) {
            return new SAXException(message, e);
        }
        else {
            return new SAXException(message);
        }
    }

    /**
     * Create a SAX exception which also understands about the location in
     * the digester file where the exception occurs
     *
     * @return the new exception
     */
    protected SAXException createSAXException(Exception e) {
        return createSAXException(e.getMessage(), e);
    }
    /**
     * Create a SAX exception which also understands about the location in
     * the digester file where the exception occurs
     *
     * @return the new exception
     */
    protected SAXException createSAXException(String message) {
        return createSAXException(message, null);
    }
}
