/*******************************************************************************
 * 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.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.XMLConstants;

import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

/**
 *  Internal:
 *  <p><b>Purpose:</b> An implementation of XMLReader for parsing XMLFragment Nodes 
 *  into SAX events.
 *  <p><b>Responsibilities:</b><ul>
 *  <li>Walk the XMLFragment node's 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>
 *  
 */
public class XMLFragmentReader extends DOMReader {
    protected NamespaceResolver nsresolver;
    protected List<NamespaceResolver> nsresolverList;
    protected Map<Element, NamespaceResolver> tmpresolverMap;
    
    public XMLFragmentReader(NamespaceResolver namespaceResolver) {
        nsresolverList = new ArrayList();
        if(null != namespaceResolver) {
            nsresolverList.add(namespaceResolver);
        }
        tmpresolverMap = new HashMap<Element, NamespaceResolver>();
    }
    
    public void parse (Node node, String uri, String name) throws SAXException {
        if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
        	handleChildNodes(node.getChildNodes());
        } else {
        	super.parse(node, uri, name);
        }
    }
    protected void reportElementEvents(Element elem) throws SAXException {
        super.reportElementEvents(elem);
        // Clean up any temporary namespace resolvers created while processing this element
        cleanupNamespaceResolvers(elem);
    }

    /**
     * Trigger an endDocument event on the contenthandler.
     */
    protected void endDocument() throws SAXException {
        // NOT APPLICABLE FOR FRAGMENTS - DO NOTHING
    }

    /**
     * Trigger a startDocument event on the contenthandler.
     */
    protected void startDocument() throws SAXException {
        // NOT APPLICABLE FOR FRAGMENTS - DO NOTHING
    }
    
    @Override
    protected void handleNewNamespaceDeclaration(Element elem, String prefix, String namespaceURI) {
        String uri = resolveNamespacePrefix(prefix);
        if (uri == null || !uri.equals(namespaceURI)) {
            NamespaceResolver tmpresolver = getTempResolver(elem);
            tmpresolver.put(prefix, namespaceURI);
            if (!nsresolverList.contains(tmpresolver)) {
                nsresolverList.add(tmpresolver);
            }
        }
    }
    
    /**
     * Handle prefixed attribute - may need to declare the namespace 
     * URI locally.
     * 
     */
    @Override
    protected void handlePrefixedAttribute(Element elem) throws SAXException {
        // Need to determine if the URI for the prefix needs to be 
        // declared locally:
        // If the prefix or URI are not in the resolver, or the URI
        // associated with the prefix (in the resolver) is different
        // than node's URI, write out the node's URI locally
        String prefix = elem.getPrefix();
        if(prefix == null) {
           prefix = Constants.EMPTY_STRING;
        }
        String uri = resolveNamespacePrefix(prefix);
        if((uri == null && elem.getNamespaceURI() != null) || (uri != null && !uri.equals(elem.getNamespaceURI()))) {
            NamespaceResolver tmpresolver = getTempResolver(elem);
            tmpresolver.put(prefix, elem.getNamespaceURI());
            if (!nsresolverList.contains(tmpresolver)) {
                nsresolverList.add(tmpresolver);
            }
            String namespaceURI = elem.getNamespaceURI();
            if(null == namespaceURI) {
                namespaceURI = Constants.EMPTY_STRING;
            }
            getContentHandler().startPrefixMapping(prefix, namespaceURI);
        }
        NamedNodeMap attributes = elem.getAttributes();
        if(attributes != null) {
            for(int x=0; x < attributes.getLength(); x++) {
               Node attribute = attributes.item(x);
               if(XMLConstants.XMLNS_ATTRIBUTE.equals(attribute.getPrefix())) {
                   NamespaceResolver tmpresolver = getTempResolver(elem);
                   tmpresolver.put(attribute.getLocalName(), attribute.getNodeValue());
                   if (!nsresolverList.contains(tmpresolver)) {
                       nsresolverList.add(tmpresolver);
                   }
               } else if(XMLConstants.XMLNS_ATTRIBUTE.equals(attribute.getNodeName())) {
                   NamespaceResolver tmpresolver = getTempResolver(elem);
                   String namespace = attribute.getNodeValue();
                   if(null == namespace) {
                       namespace = Constants.EMPTY_STRING;
                   }
                   tmpresolver.put(Constants.EMPTY_STRING, namespace);
                   if (!nsresolverList.contains(tmpresolver)) {
                       nsresolverList.add(tmpresolver);
                   }
               }
            }
        }
    }
    
    /**
     * If there is a temporary namespace resolver for a given element,
     * each entry contains a prefix that requires an endPrefixMapping
     * event to be triggered
     */
    protected void endPrefixMappings(Element elem) throws SAXException {
        NamespaceResolver tmpresolver = getTempResolver(elem);
        if (tmpresolver != null) {
            ContentHandler contentHandler = getContentHandler();
            String defaultNamespace = tmpresolver.getDefaultNamespaceURI();
            if(null != defaultNamespace) {
                contentHandler.endPrefixMapping(Constants.EMPTY_STRING);
            }
            if(tmpresolver.hasPrefixesToNamespaces()) {
                for(Entry<String, String> entry : tmpresolver.getPrefixesToNamespaces().entrySet()) {
                    contentHandler.endPrefixMapping(entry.getKey());
                }
            }
        }
    }

    /**
     * Returns the namespace resolver in the map of temporary namespace
     * resolvers for a given element
     * 
     * @param elem
     * @return the namespace resolver in the map for elem, or a new 
     * resolver if none exists
     */
    protected NamespaceResolver getTempResolver(Element elem) {
        NamespaceResolver tmpresolver = tmpresolverMap.get(elem);
        if (tmpresolver == null) {
            tmpresolver = new NamespaceResolver();
            tmpresolverMap.put(elem, tmpresolver);
        }
        return tmpresolver;
    }
    
    /**
     * Remove any temporary namespace resolvers created while processing
     * a given element.
     * 
     * @param elem
     */
    protected void cleanupNamespaceResolvers(Element elem) {
        NamespaceResolver tmpresolver = tmpresolverMap.get(elem);
        if (tmpresolver != null) {
            tmpresolverMap.remove(elem);
            nsresolverList.remove(tmpresolver);
        }
    }

    /**
     * Convenience method that iterates over each namespace resolver 
     * in the resolver list until it locates a uri for 'prefix' or
     * the final resolver is reached w/o success.
     * @param prefix
     * @return true if a URI exists in one of the resolvers in the 
     * list, false otherwise
     */
    protected String resolveNamespacePrefix(String prefix) {
        String uri = null;
        if (null == prefix || prefix.length() == 0) {
            for (int i = nsresolverList.size() - 1; i >= 0; i--) {
                NamespaceResolver next = nsresolverList.get(i);
                uri = next.getDefaultNamespaceURI();
                if ((uri != null) && uri.length() > 0) {
                    break;
                }
            }
        } else {
            for (int i = nsresolverList.size() - 1; i >= 0; i--) {
                NamespaceResolver next = nsresolverList.get(i);
                uri = next.resolveNamespacePrefix(prefix);
                if ((uri != null) && uri.length() > 0) {
                    break;
                }
            }
        }
        return uri;
    }  
    /**
     * Process namespace declarations on parent elements if not the root.
     * For each parent node from current to root place puch 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 {
        // DO NOTHING FOR FRAGMENTS
    }
    
    protected void handleXsiTypeAttribute(Attr attr) throws SAXException {
        String value = attr.getValue();
        int colon = value.indexOf(':');
        if(colon != -1) {
            String prefix = value.substring(0, colon);
            String uri = this.resolveNamespacePrefix(prefix);
            if(uri == null) {
                uri = XMLPlatformFactory.getInstance().getXMLPlatform().resolveNamespacePrefix(attr.getOwnerElement(), prefix);
                if(uri != null) {
                    this.contentHandler.startPrefixMapping(prefix, uri);
                }
                
            }
        }
    }

}
