/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/
package org.eclipse.persistence.internal.oxm.record;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.mappings.Login;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.record.namespaces.StackUnmarshalNamespaceResolver;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.Locator2;

/**
 *  INTERNAL:
 *  <p><b>Purpose:</b> An implementation of XMLReader for parsing DOM Nodes into SAX events.
 *  <p><b>Responsibilities:</b><ul>
 *  <li>Walk the DOM tree and report sax events to the provided content handler</li>
 *  <li>Report lexical events to the lexical handler if it's provided</li>
 *  <li>Listen for callbacks from the Mapping-Level framework to handle caching nodes for document preservation</li>
 *  </ul>
 *  
 */
public class DOMReader extends XMLReaderAdapter {

    private Node currentNode;
    private DocumentPreservationPolicy docPresPolicy;

    public DOMReader() {
        super();
    }

    public DOMReader(Unmarshaller xmlUnmarshaller) {
        super(xmlUnmarshaller);
    }

    @Override
    public void parse(InputSource input) throws SAXException {
        if(input instanceof DOMInputSource) {
            Node node = ((DOMInputSource) input).getNode();
            if(contentHandler != null && contentHandler.getClass() == SAXUnmarshallerHandler.class){
                ((SAXUnmarshallerHandler)contentHandler).setUnmarshalNamespaceResolver(new StackUnmarshalNamespaceResolver());
            }
            parse(node);
        }
    }

    public void parse (Node node, String newURI, String newName) throws SAXException {
        if(null == contentHandler) {
            return;
        }
        Element rootNode = null;
        if(node.getNodeType() == Node.DOCUMENT_NODE) {
            rootNode = ((Document)node).getDocumentElement();
        }  else {
            rootNode = (Element)node;
        }
        if(rootNode == null) {
            return;
        }
        processParentNamespaces(rootNode);
        startDocument();
        setupLocator(rootNode.getOwnerDocument());
              
        reportElementEvents(rootNode, newURI, newName);
        
        
        endDocument();
    }
    
    public void parse (Node node) throws SAXException {
        parse(node, null, null);
    }

    /**
     * Process namespace declarations on parent elements if not the root.
     * For each parent node from current to root push each onto a stack, 
     * then pop each off, calling startPrefixMapping for each XMLNS 
     * attribute.  Using a stack ensures that the parent nodes are 
     * processed top down.
     * 
     * @param element
     */
    protected void processParentNamespaces(Element element) throws SAXException {
        Node parent = element.getParentNode();
        // If we're already at the root, do nothing
        if (parent != null && parent.getNodeType() == Node.DOCUMENT_NODE) {
            return;
        }
        // Add each parent node up to root to the stack
        List<Node> parentElements = new ArrayList<Node>();
        while (parent != null && parent.getNodeType() != Node.DOCUMENT_NODE) {
            parentElements.add(parent);
            parent = parent.getParentNode();
        }        
        // Pop off each node and call startPrefixMapping for each XMLNS attribute
        for (Iterator stackIt = parentElements.iterator(); stackIt.hasNext(); ) {
            NamedNodeMap attrs = parentElements.remove(parentElements.size() - 1).getAttributes();
            if (attrs != null) {
                for (int i=0, length = attrs.getLength(); i < length; i++) {
                    Attr next = (Attr)attrs.item(i);
                    String attrPrefix = next.getPrefix();
                    if (attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                        contentHandler.startPrefixMapping(next.getLocalName(), next.getValue());
                    }
                }
            }
        }
    }
    protected void reportElementEvents(Element elem) throws SAXException {
        reportElementEvents(elem, null, null);
    }
    protected void reportElementEvents(Element elem, String newUri, String newName) throws SAXException {
        this.currentNode = elem;
        IndexedAttributeList attributes = buildAttributeList(elem);
        String namespaceUri = null;
        String qname = null;
        String lname = null;

        if(newName == null){
            // Handle null local name           
            lname = elem.getLocalName();
            if (lname == null) {
                // If local name is null, use the node name
                lname = elem.getNodeName();
                qname = lname;
                handlePrefixedAttribute(elem);
            } else {
                qname = getQName(elem);
            }
            namespaceUri = elem.getNamespaceURI();
            if(namespaceUri == null) {
                namespaceUri = "";
            }
        } else {
            namespaceUri = newUri;
            lname = newName;            
            qname = newName;
            if(namespaceUri != null && isNamespaceAware()){
                NamespaceResolver tmpNR = new NamespaceResolver();
                tmpNR.setDOM(elem);

                 String prefix = tmpNR.resolveNamespaceURI(namespaceUri);
                 if(prefix == null || prefix.length() == 0){
                     String defaultNamespace = elem.getAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE);
            
                     if(defaultNamespace == null){
                         prefix = tmpNR.generatePrefix();    
                         contentHandler.startPrefixMapping(prefix, namespaceUri);
                     }else if(defaultNamespace != namespaceUri){
                         prefix = tmpNR.generatePrefix();
                         contentHandler.startPrefixMapping(prefix, namespaceUri);
                     }else{
                         prefix = Constants.EMPTY_STRING;
                     }      
                 }                 
                 
                 if(prefix != null && prefix.length() >0){
                    qname = prefix + Constants.COLON + qname;      
                 }
            }
           
        }
        
      
        
        contentHandler.startElement(namespaceUri, lname, qname, attributes);
       
        handleChildNodes(elem.getChildNodes());
        contentHandler.endElement(namespaceUri, lname, qname);
        endPrefixMappings(elem);
    }
 
    protected IndexedAttributeList buildAttributeList(Element elem) throws SAXException {
        IndexedAttributeList attributes = new IndexedAttributeList();
        NamedNodeMap attrs = elem.getAttributes();
        for (int i = 0, length = attrs.getLength(); i < length; i++) {
            Attr next = (Attr)attrs.item(i);
            String attrPrefix = next.getPrefix();
            if(attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                contentHandler.startPrefixMapping(next.getLocalName(), next.getValue());
                // Handle XMLNS prefixed attributes
                handleNewNamespaceDeclaration(elem, next.getLocalName(), next.getValue());

            } else if(attrPrefix == null) {
                String name = next.getLocalName();
                if(name == null) {
                    name = next.getNodeName();
                }
                if(name != null && name.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                    contentHandler.startPrefixMapping(Constants.EMPTY_STRING, next.getValue());
                    handleNewNamespaceDeclaration(elem, Constants.EMPTY_STRING, next.getValue());
                }
            }
            if(next.getNamespaceURI() != null && next.getNamespaceURI().equals(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI) && next.getLocalName().equals("type")) {
                handleXsiTypeAttribute(next);
            }
            attributes.addAttribute(next);
        }
        return attributes;
    }

    protected void endPrefixMappings(Element elem) throws SAXException {
        NamedNodeMap attrs = elem.getAttributes();
        for(int i = 0, numOfAtts = attrs.getLength(); i < numOfAtts; i++) {
            Attr next = (Attr)attrs.item(i);
            String attrPrefix = next.getPrefix();
            if (attrPrefix != null && attrPrefix.equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE)) {
                contentHandler.endPrefixMapping(next.getLocalName());
            } else if(attrPrefix == null) {
                String name = next.getLocalName();
                if(name == null) {
                    name = next.getNodeName();
                }
                if(javax.xml.XMLConstants.XMLNS_ATTRIBUTE.equals(name)) {
                    contentHandler.endPrefixMapping(Constants.EMPTY_STRING);
                }
            }
        }
    }

    protected String getQName(Element elem) throws SAXException {
        handlePrefixedAttribute(elem);
        String prefix = elem.getPrefix();
        if (prefix != null && prefix.length() > 0) {
            String qname = prefix + Constants.COLON + elem.getLocalName();
            return qname;
        } else {
            return elem.getLocalName();
        }
    }

    protected void handleNewNamespaceDeclaration(Element elem, String emptyString, String value) {
        // DO NOTHING
    }

    protected void handleXsiTypeAttribute(Attr attr) throws SAXException {
        
    }

    /**
     * Handle prefixed attribute - may need to declare the namespace 
     * URI locally.
     * 
     */
    protected void handlePrefixedAttribute(Element elem) throws SAXException {
        // DO NOTHING
    }

    protected void handleChildNodes(NodeList children) throws SAXException {
        Node nextChild = null;
        if(children.getLength() > 0) {
            nextChild = children.item(0);
        }
        while(nextChild != null) {
            if(nextChild.getNodeType() == Node.TEXT_NODE) {
                char[] value = ((Text)nextChild).getNodeValue().toCharArray();
                contentHandler.characters(value, 0, value.length);
            } else if(nextChild.getNodeType() == Node.COMMENT_NODE) {
                char[] value = ((Comment)nextChild).getNodeValue().toCharArray();
                if (lexicalHandler != null) {
                    lexicalHandler.comment(value, 0, value.length);
                }
            } else if(nextChild.getNodeType() == Node.ELEMENT_NODE) {
                Element childElement = (Element)nextChild;
                reportElementEvents(childElement);
            } else if(nextChild.getNodeType() == Node.CDATA_SECTION_NODE) {
                if(lexicalHandler != null) {
                    lexicalHandler.startCDATA();
                }
                char[] value = ((CDATASection)nextChild).getData().toCharArray();
                contentHandler.characters(value, 0, value.length);
                if(lexicalHandler != null) {
                    lexicalHandler.endCDATA();
                }
            }
            nextChild = nextChild.getNextSibling();
        }
    }

    /**
     * Trigger an endDocument event on the contenthandler.
     */
    protected void endDocument() throws SAXException {
        contentHandler.endDocument();
    }

    /**
     * Trigger a startDocument event on the contenthandler.
     */
    protected void startDocument() throws SAXException {
        contentHandler.startDocument();
    }

    /**
     * An EclipseLink specific callback into the Reader. This allows Objects to be 
     * associated with the XML Nodes they came from.
     */
    @Override
    public void newObjectEvent(Object object, Object parent, Mapping selfRecordMapping) {
        docPresPolicy.addObjectToCache(object, currentNode, selfRecordMapping);
    }

    @Override
    public Object getCurrentObject(CoreAbstractSession session, Mapping selfRecordMapping) {
        //if session == null then this is a marshal of a non-root
        //if docPres policy is null, then we never unmarshalled anything, and can
        //safely return null;
        if(session == null && docPresPolicy == null) {
            return null;
        }
        if(docPresPolicy == null) {
            Login login = (Login)session.getDatasourceLogin();
            docPresPolicy = login.getDocumentPreservationPolicy();
        }
        return docPresPolicy.getObjectForNode(currentNode, selfRecordMapping);
    }

    public DocumentPreservationPolicy getDocPresPolicy() {
        return docPresPolicy;
    }

    public void setDocPresPolicy(DocumentPreservationPolicy policy) {
        docPresPolicy = policy;
    }

    protected void setupLocator(Document doc) {
        LocatorImpl locator = new LocatorImpl();
        try {
            Method getEncoding = PrivilegedAccessHelper.getMethod(doc.getClass(), "getXmlEncoding", new Class[]{}, true);
            Method getVersion = PrivilegedAccessHelper.getMethod(doc.getClass(), "getXmlVersion", new Class[]{}, true);
            
            String encoding = (String)PrivilegedAccessHelper.invokeMethod(getEncoding, doc, new Object[]{});
            String version = (String)PrivilegedAccessHelper.invokeMethod(getVersion, doc, new Object[]{});
            
            locator.setEncoding(encoding);
            locator.setXMLVersion(version);
        } catch(Exception ex) {
            //if unable to invoke these methods, just return and don't invoke
            return;
        }
        this.contentHandler.setDocumentLocator(locator);
    }

    /**
     * Implementation of Attributes - used to pass along a given node's attributes
     * to the startElement method of the reader's content handler.
     */
    protected class IndexedAttributeList implements org.xml.sax.Attributes {

        private List<Attr> attrs;

        public IndexedAttributeList() {
            attrs = new ArrayList();
        }

        public void addAttribute(Attr attribute) {
            attrs.add(attribute);
        }

        public String getQName(int index) {
            try {
                Attr item = attrs.get(index);
                if (item.getName() != null) {
                    return item.getName();
                }
                return Constants.EMPTY_STRING;
            } catch (IndexOutOfBoundsException iobe) {
                return null;
            }
        }

        public String getType(String namespaceUri, String localName) {
            return Constants.CDATA;
        }

        public String getType(int index) {
            return Constants.CDATA;
        }

        public String getType(String qname) {
            return Constants.CDATA;
        }

        public int getIndex(String qname) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                if (attrs.get(i).getName().equals(qname)) {
                    return i;
                }
            }
            return -1;
        }

        public int getIndex(String uri, String localName) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                try {
                    if (item.getNamespaceURI().equals(uri) && item.getLocalName().equals(localName)) {
                        return i;
                    }
                } catch (Exception x) {}
            }
            return -1;
        }

        public int getLength() {
            return attrs.size();
        }

        public String getLocalName(int index) {
            try {
                Attr item = attrs.get(index);
                if (item.getLocalName() != null) {
                    return item.getLocalName();
                }
                return item.getName();
            } catch (IndexOutOfBoundsException iobe) {
                return null;
            }
        }

        public String getURI(int index) {
            String uri = attrs.get(index).getNamespaceURI();
            if(uri == null) {
                uri = Constants.EMPTY_STRING;
            }
            return uri;
        }

        public String getValue(int index) {
            return (attrs.get(index)).getValue();
        }

        public String getValue(String qname) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                if (item.getName().equals(qname)) {
                    return item.getValue();
                }
            }
            return null;
        }

        public String getValue(String uri, String localName) {
            for (int i=0, size = attrs.size(); i<size; i++) {
                Attr item = attrs.get(i);
                if (item != null) {
                    String itemNS = item.getNamespaceURI();  
                    // Need to handle null/empty URI
                    if (item.getNamespaceURI() == null) {
                        itemNS = Constants.EMPTY_STRING;
                    }
                    
                    String itemName = item.getLocalName();
                    if(itemName == null){
                    	itemName = item.getNodeName();
                    }
                    if ((itemNS.equals(uri)) && (itemName != null && itemName.equals(localName))) {
                 	   return item.getValue();   
                    }                   
                }
            }
            return null;
        }
    }

    protected class LocatorImpl implements Locator2 {

        private String encoding;
        private String version;

        public LocatorImpl() {
            encoding = "UTF-8";
            version = "1.0";
        }

        public String getEncoding() {
            return encoding;
        }

        public int getColumnNumber() {
            //not supported here
            return 0;
        }

        public String getSystemId() {
            return Constants.EMPTY_STRING;
        }

        public String getPublicId() {
            return Constants.EMPTY_STRING;
        }

        public String getXMLVersion() {
            return version;
        }

        public int getLineNumber() {
            //not supported
            return 0;
        }

        protected void setEncoding(String enc) {
            this.encoding = enc;
        }

        protected void setXMLVersion(String xmlVersion) {
            this.version = xmlVersion;
        }

    }

}