/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed 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.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.beans.decoder;

import com.sun.beans.finder.ClassFinder;

import java.beans.ExceptionListener;

import java.io.IOException;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * The main class to parse JavaBeans XML archive.
 *
 * @since 1.7
 *
 * @author Sergey A. Malenkov
 *
 * @see ElementHandler
 */
public final class DocumentHandler extends DefaultHandler {
    private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<String, Class<? extends ElementHandler>>();

    private final Map<String, Object> environment = new HashMap<String, Object>();

    private final List<Object> objects = new ArrayList<Object>();

    private Reference<ClassLoader> loader;
    private ExceptionListener listener;
    private Object owner;

    private ElementHandler handler;

    /**
     * Creates new instance of document handler.
     */
    public DocumentHandler() {
        setElementHandler("java", JavaElementHandler.class); // NON-NLS: the element name
        setElementHandler("null", NullElementHandler.class); // NON-NLS: the element name
        setElementHandler("array", ArrayElementHandler.class); // NON-NLS: the element name
        setElementHandler("class", ClassElementHandler.class); // NON-NLS: the element name
        setElementHandler("string", StringElementHandler.class); // NON-NLS: the element name
        setElementHandler("object", ObjectElementHandler.class); // NON-NLS: the element name

        setElementHandler("void", VoidElementHandler.class); // NON-NLS: the element name
        setElementHandler("char", CharElementHandler.class); // NON-NLS: the element name
        setElementHandler("byte", ByteElementHandler.class); // NON-NLS: the element name
        setElementHandler("short", ShortElementHandler.class); // NON-NLS: the element name
        setElementHandler("int", IntElementHandler.class); // NON-NLS: the element name
        setElementHandler("long", LongElementHandler.class); // NON-NLS: the element name
        setElementHandler("float", FloatElementHandler.class); // NON-NLS: the element name
        setElementHandler("double", DoubleElementHandler.class); // NON-NLS: the element name
        setElementHandler("boolean", BooleanElementHandler.class); // NON-NLS: the element name

        // some handlers for new elements
        setElementHandler("new", NewElementHandler.class); // NON-NLS: the element name
        setElementHandler("var", VarElementHandler.class); // NON-NLS: the element name
        setElementHandler("true", TrueElementHandler.class); // NON-NLS: the element name
        setElementHandler("false", FalseElementHandler.class); // NON-NLS: the element name
        setElementHandler("field", FieldElementHandler.class); // NON-NLS: the element name
        setElementHandler("method", MethodElementHandler.class); // NON-NLS: the element name
        setElementHandler("property", PropertyElementHandler.class); // NON-NLS: the element name
    }

    /**
     * Returns the class loader used to instantiate objects.
     * If the class loader has not been explicitly set
     * then {@code null} is returned.
     *
     * @return the class loader used to instantiate objects
     */
    public ClassLoader getClassLoader() {
        return (this.loader != null)
                ? this.loader.get()
                : null;
    }

    /**
     * Sets the class loader used to instantiate objects.
     * If the class loader is not set
     * then default class loader will be used.
     *
     * @param loader  a classloader to use
     */
    public void setClassLoader(ClassLoader loader) {
        this.loader = new WeakReference<ClassLoader>(loader);
    }

    /**
     * Returns the exception listener for parsing.
     * The exception listener is notified
     * when handler catches recoverable exceptions.
     * If the exception listener has not been explicitly set
     * then default exception listener is returned.
     *
     * @return the exception listener for parsing
     */
    public ExceptionListener getExceptionListener() {
        return this.listener;
    }

    /**
     * Sets the exception listener for parsing.
     * The exception listener is notified
     * when handler catches recoverable exceptions.
     *
     * @param listener  the exception listener for parsing
     */
    public void setExceptionListener(ExceptionListener listener) {
        this.listener = listener;
    }

    /**
     * Returns the owner of this document handler.
     *
     * @return the owner of this document handler
     */
    public Object getOwner() {
        return this.owner;
    }

    /**
     * Sets the owner of this document handler.
     *
     * @param owner  the owner of this document handler
     */
    public void setOwner(Object owner) {
        this.owner = owner;
    }

    /**
     * Returns the handler for the element with specified name.
     *
     * @param name  the name of the element
     * @return the corresponding element handler
     */
    public Class<? extends ElementHandler> getElementHandler(String name) {
        Class<? extends ElementHandler> type = this.handlers.get(name);
        if (type == null) {
            throw new IllegalArgumentException("Unsupported element: " + name);
        }
        return type;
    }

    /**
     * Sets the handler for the element with specified name.
     *
     * @param name     the name of the element
     * @param handler  the corresponding element handler
     */
    public void setElementHandler(String name, Class<? extends ElementHandler> handler) {
        this.handlers.put(name, handler);
    }

    /**
     * Indicates whether the variable with specified identifier is defined.
     *
     * @param id  the identifier
     * @return @{code true} if the variable is defined;
     *         @{code false} otherwise
     */
    public boolean hasVariable(String id) {
        return this.environment.containsKey(id);
    }

    /**
     * Returns the value of the variable with specified identifier.
     *
     * @param id  the identifier
     * @return the value of the variable
     */
    public Object getVariable(String id) {
        if (!this.environment.containsKey(id)) {
            throw new IllegalArgumentException("Unbound variable: " + id);
        }
        return this.environment.get(id);
    }

    /**
     * Sets new value of the variable with specified identifier.
     *
     * @param id     the identifier
     * @param value  new value of the variable
     */
    public void setVariable(String id, Object value) {
        this.environment.put(id, value);
    }

    /**
     * Returns the array of readed objects.
     *
     * @return the array of readed objects
     */
    public Object[] getObjects() {
        return this.objects.toArray();
    }

    /**
     * Adds the object to the list of readed objects.
     *
     * @param object  the object that is readed from XML document
     */
    void addObject(Object object) {
        this.objects.add(object);
    }

    /**
     * Prepares this handler to read objects from XML document.
     */
    @Override
    public void startDocument() {
        this.objects.clear();
        this.handler = null;
    }

    /**
     * Parses opening tag of XML element
     * using corresponding element handler.
     *
     * @param uri         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 attributes  the attributes attached to the element
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        ElementHandler parent = this.handler;
        try {
            this.handler = getElementHandler(qName).newInstance();
            this.handler.setOwner(this);
            this.handler.setParent(parent);
        }
        catch (Exception exception) {
            throw new SAXException(exception);
        }
        for (int i = 0; i < attributes.getLength(); i++)
            try {
                String name = attributes.getQName(i);
                String value = attributes.getValue(i);
                this.handler.addAttribute(name, value);
            }
            catch (RuntimeException exception) {
                handleException(exception);
            }

        this.handler.startElement();
    }

    /**
     * Parses closing tag of XML element
     * using corresponding element handler.
     *
     * @param uri        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
     */
    @Override
    public void endElement(String uri, String localName, String qName) {
        try {
            this.handler.endElement();
        }
        catch (RuntimeException exception) {
            handleException(exception);
        }
        finally {
            this.handler = this.handler.getParent();
        }
    }

    /**
     * Parses character data inside XML element.
     *
     * @param chars   the array of characters
     * @param start   the start position in the character array
     * @param length  the number of characters to use
     */
    @Override
    public void characters(char[] chars, int start, int length) {
        if (this.handler != null) {
            try {
                while (0 < length--) {
                    this.handler.addCharacter(chars[start++]);
                }
            }
            catch (RuntimeException exception) {
                handleException(exception);
            }
        }
    }

    /**
     * Handles an exception using current exception listener.
     *
     * @param exception  an exception to handle
     * @see #setExceptionListener
     */
    public void handleException(Exception exception) {
        if (this.listener == null) {
            throw new IllegalStateException(exception);
        }
        this.listener.exceptionThrown(exception);
    }

    /**
     * Starts parsing of the specified input source.
     *
     * @param input  the input source to parse
     */
    public void parse(InputSource input) {
        try {
            SAXParserFactory.newInstance().newSAXParser().parse(input, this);
        }
        catch (ParserConfigurationException exception) {
            handleException(exception);
        }
        catch (SAXException wrapper) {
            Exception exception = wrapper.getException();
            if (exception == null) {
                exception = wrapper;
            }
            handleException(exception);
        }
        catch (IOException exception) {
            handleException(exception);
        }
    }

    /**
     * Resolves class by name using current class loader.
     * This method handles exception using current exception listener.
     *
     * @param name  the name of the class
     * @return the object that represents the class
     */
    public Class<?> findClass(String name) {
        try {
            return ClassFinder.resolveClass(name, getClassLoader());
        }
        catch (ClassNotFoundException exception) {
            handleException(exception);
            return null;
        }
    }
}
