/*******************************************************************************
 * 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.Modifier;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Context;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.XPathQName;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.oxm.unmapped.UnmappedContentHandler;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.Locator2;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.internal.oxm.record.XMLReader;
import org.eclipse.persistence.internal.oxm.record.namespaces.StackUnmarshalNamespaceResolver;
import org.eclipse.persistence.internal.oxm.record.namespaces.UnmarshalNamespaceResolver;

/**
 * INTERNAL:
 * <p><b>Purpose:</b>An implementation of ContentHandler used to handle the root element of an
 * XML Document during unmarshal.
 * <p><b>Responsibilities:</b><ul>
 * <li>Implement ContentHandler interface</li>
 * <li>Handle startElement event for the root-level element of an xml document</li>
 * <li>Handle inheritance, and descriptor lookup to determine the correct class associated with
 * this XML Element.</li>
 * </ul>
 *
 * @author bdoughan
 *
 */
public class SAXUnmarshallerHandler implements ExtendedContentHandler {
    private XMLReader xmlReader;
    private Context xmlContext;
    private UnmarshalRecord rootRecord;
    private Object object;
    private Descriptor descriptor;
    private boolean shouldWrap;
    private Unmarshaller unmarshaller;
    private CoreAbstractSession session;
    private UnmarshalNamespaceResolver unmarshalNamespaceResolver;
    private UnmarshalKeepAsElementPolicy keepAsElementPolicy = new UnmarshalKeepAsElementPolicy() {

        @Override
        public boolean isKeepAllAsElement() {
            return false;
        }

        @Override
        public boolean isKeepNoneAsElement() {
            return true;
        }

        @Override
        public boolean isKeepUnknownAsElement() {
            return false;
        }

    };
    private SAXDocumentBuilder documentBuilder;
    private Locator2 locator;
    private boolean isNil;
    
    public SAXUnmarshallerHandler(Context xmlContext) {
        super();
        this.xmlContext = xmlContext;
        this.shouldWrap = true;
        unmarshalNamespaceResolver = new StackUnmarshalNamespaceResolver();
    }

    public XMLReader getXMLReader() {
        return this.xmlReader;
    }

    public void setXMLReader(XMLReader xmlReader) {
        this.xmlReader = xmlReader;
    }

    public Object getObject() {
        if(object == null) {
            if(this.descriptor != null) {            	
                if(this.unmarshaller.isResultAlwaysXMLRoot() || descriptor.isResultAlwaysXMLRoot() || shouldWrap){
                    object = this.descriptor.wrapObjectInXMLRoot(this.rootRecord, (this.unmarshaller.isResultAlwaysXMLRoot() || descriptor.isResultAlwaysXMLRoot()));
            	}else {
            		object = this.rootRecord.getCurrentObject();
            	}
            } else if(documentBuilder != null) {
                Node node = documentBuilder.getDocument().getDocumentElement();
                Root root = unmarshaller.createRoot();
                root.setLocalName(node.getLocalName());
                root.setNamespaceURI(node.getNamespaceURI());
                root.setObject(node);
                object = root;
            } else {
                if(rootRecord != null) {
                    object = this.rootRecord.getCurrentObject();
                }
            }
        }
        return this.object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public void setDocumentLocator(Locator locator) {
        if (locator instanceof Locator2) {
            this.locator = (Locator2)locator;
            if(xmlReader != null){
        	    xmlReader.setLocator(locator);
            }
        }        
    }

    public UnmarshalNamespaceResolver getUnmarshalNamespaceResolver() {
        return this.unmarshalNamespaceResolver;
    }

    public void setUnmarshalNamespaceResolver(UnmarshalNamespaceResolver unmarshalNamespaceResolver) {
        this.unmarshalNamespaceResolver = unmarshalNamespaceResolver;
    }

    public void startDocument() throws SAXException {
    }

    public void endDocument() throws SAXException {
    }

    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        unmarshalNamespaceResolver.push(prefix, uri);
    }

    public void endPrefixMapping(String prefix) throws SAXException {
        unmarshalNamespaceResolver.pop(prefix);
    }

    /**
     * INTERNAL:
     *
     * Resolve any mapping references.
     */
    public void resolveReferences() {
        if(null != rootRecord) {
            rootRecord.resolveReferences(session, unmarshaller.getIDResolver());
        }
    }

    public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        try {           
        	String name;
            if (localName == null || localName.length() == 0) {
                name = qName;
            } else {
                name = localName;
            }

            XPathQName rootQName;
            if (namespaceURI == null || namespaceURI.length() == 0) {
                rootQName = new XPathQName(name, xmlReader.isNamespaceAware() );
            } else {
                rootQName = new XPathQName(namespaceURI, name, xmlReader.isNamespaceAware() );
            }
            
            Class primitiveWrapperClass = null;
            Descriptor xmlDescriptor = xmlContext.getDescriptor(rootQName);
                             
            //if no match on root element look for xsi:type
            if(xmlDescriptor == null){  
            	boolean isPrimitiveType = false;
                String type = null;
                if(xmlReader.isNamespaceAware()){
                    type = atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE);
                }else{
                	type = atts.getValue(Constants.EMPTY_STRING, Constants.SCHEMA_TYPE_ATTRIBUTE);
                }
                if (null != type) {
                    XPathFragment typeFragment = new XPathFragment(type, xmlReader.namespaceSeparator, xmlReader.isNamespaceAware());
                    // set the prefix using a reverse key lookup by uri value on namespaceMap 
                    if (xmlReader.isNamespaceAware() && null != unmarshalNamespaceResolver) {
                        typeFragment.setNamespaceURI(unmarshalNamespaceResolver.getNamespaceURI(typeFragment.getPrefix()));
                    }
                    Descriptor lookupDescriptor = xmlContext.getDescriptorByGlobalType(typeFragment);
                    if(lookupDescriptor == null) {
                    	QName lookupQName = null;
                    	if(typeFragment.getNamespaceURI() == null){
                    		lookupQName= new QName(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI, typeFragment.getLocalName());
                    	}else{
                    		lookupQName= new QName(typeFragment.getNamespaceURI(), typeFragment.getLocalName());
                    	}
                        //check to see if type attribute represents simple type
                	    if(null == session) {
                	       session = (CoreAbstractSession) xmlContext.getSession();
                	    }

                    primitiveWrapperClass = (Class)XMLConversionManager.getDefaultXMLTypes().get(lookupQName);
                    }else{          
                    	//found descriptor based on type attribute
                    	xmlDescriptor = lookupDescriptor;
                    	session = xmlContext.getSession(xmlDescriptor);   
                    }
                }
            } else {
            	if(null != xmlDescriptor.getDefaultRootElementField() && !unmarshaller.isResultAlwaysXMLRoot()){
            	    String descLocalName = xmlDescriptor.getDefaultRootElementField().getXPathFragment().getLocalName();
                	if( descLocalName != null && descLocalName.equals(localName) ){
                	    String descUri = xmlDescriptor.getDefaultRootElementField().getXPathFragment().getNamespaceURI();
                    	if(!xmlReader.isNamespaceAware() || (xmlReader.isNamespaceAware() && ((namespaceURI == null && descUri == null ) || (namespaceURI !=null &&namespaceURI.length() == 0 && descUri == null ) || (namespaceURI != null && namespaceURI.equals(descUri))))){
                 	       //found a descriptor based on root element then know we won't need to wrap in an XMLRoot
                	       shouldWrap = false;
                	    }
                    }
            	}
            	
                if(xmlDescriptor.hasInheritance()){
            	    //if descriptor has inheritance check class indicator
            	    session = xmlContext.getSession(xmlDescriptor);            	
            	    UnmarshalRecord tmpUnmarshalRecord = new UnmarshalRecordImpl(null);
            	    tmpUnmarshalRecord.setUnmarshaller(unmarshaller);
            	    tmpUnmarshalRecord.setUnmarshalNamespaceResolver(unmarshalNamespaceResolver);
            	    tmpUnmarshalRecord.setXMLReader(this.getXMLReader());
            	    tmpUnmarshalRecord.setAttributes(atts);
                 
                    Class classValue = xmlDescriptor.getInheritancePolicy().classFromRow(new org.eclipse.persistence.oxm.record.UnmarshalRecord(tmpUnmarshalRecord), (CoreAbstractSession) session);
                    if (classValue == null) {
                       // no xsi:type attribute - look for type indicator on the default root element
                       QName leafElementType = xmlDescriptor.getDefaultRootElementType();
                       // if we have a user-set type, try to get the class from the inheritance policy
                       if (leafElementType != null) {
                           Object indicator = xmlDescriptor.getInheritancePolicy().getClassIndicatorMapping().get(leafElementType);
                           if(indicator != null) {
                               classValue = (Class)indicator;
                           }
                       }
                    }
                    if (classValue != null) {                	 
                       xmlDescriptor = (Descriptor)session.getDescriptor(classValue);
                    } else {
                       // since there is no xsi:type attribute, we'll use the descriptor
                       // that was retrieved based on the rootQName -  we need to make 
                       // sure it is non-abstract
                       if (Modifier.isAbstract(xmlDescriptor.getJavaClass().getModifiers())) {
                           // need to throw an exception here
                           throw DescriptorException.missingClassIndicatorField((XMLRecord) tmpUnmarshalRecord, (org.eclipse.persistence.oxm.XMLDescriptor)xmlDescriptor.getInheritancePolicy().getDescriptor());
                       }
                   }
                }
            }
            
            if (null == xmlDescriptor) {
                //check for a cached object and look for descriptor by class
                Object obj = this.xmlReader.getCurrentObject(session, null);
                if (obj != null) {
                    xmlDescriptor = (Descriptor)xmlContext.getSession(obj.getClass()).getDescriptor(obj.getClass());
                }              
            }        	
        	
            if (null == xmlDescriptor && primitiveWrapperClass == null){
                if(!this.keepAsElementPolicy.isKeepNoneAsElement()) {
                    this.documentBuilder = new SAXDocumentBuilder();
                    documentBuilder.startDocument();
                    //start any prefixes that have already been started
                    for(String prefix:this.unmarshalNamespaceResolver.getPrefixes()) {
                        documentBuilder.startPrefixMapping(prefix, this.unmarshalNamespaceResolver.getNamespaceURI(prefix));
                    }
                    documentBuilder.startElement(namespaceURI, localName, qName, atts);
                    this.xmlReader.setContentHandler(documentBuilder);
                    return;
                }
                Class unmappedContentHandlerClass = unmarshaller.getUnmappedContentHandlerClass();
                if (null == unmappedContentHandlerClass) {
                    throw XMLMarshalException.noDescriptorWithMatchingRootElement(rootQName.toString());
                } else {
                    UnmappedContentHandler unmappedContentHandler;
                    try {
                        PrivilegedNewInstanceFromClass privilegedNewInstanceFromClass = new PrivilegedNewInstanceFromClass(unmappedContentHandlerClass);
                        unmappedContentHandler = (UnmappedContentHandler)privilegedNewInstanceFromClass.run();
                    } catch (ClassCastException e) {
                        throw XMLMarshalException.unmappedContentHandlerDoesntImplement(e, unmappedContentHandlerClass.getName());
                    } catch (IllegalAccessException e) {
                        throw XMLMarshalException.errorInstantiatingUnmappedContentHandler(e, unmappedContentHandlerClass.getName());
                    } catch (InstantiationException e) {
                        throw XMLMarshalException.errorInstantiatingUnmappedContentHandler(e, unmappedContentHandlerClass.getName());
                    }
	                    
                    UnmappedContentHandlerWrapper unmappedContentHandlerWrapper = new UnmappedContentHandlerWrapper(unmappedContentHandler, this);
                    unmappedContentHandler.startElement(namespaceURI, localName, qName, atts);
                    xmlReader.setContentHandler(unmappedContentHandler);
                    setObject(unmappedContentHandlerWrapper.getCurrentObject());
                    return;
                }
            }
                   
            if (xmlDescriptor == null && primitiveWrapperClass != null) {
            	session = xmlContext.getSession(xmlDescriptor);
            	rootRecord = unmarshaller.createRootUnmarshalRecord(primitiveWrapperClass);
            	rootRecord.setSession((CoreAbstractSession) unmarshaller.getContext().getSession());       
            } else{
            	if(session == null){
                	session = xmlContext.getSession(xmlDescriptor);
                }
            	rootRecord = unmarshaller.createUnmarshalRecord(xmlDescriptor, session);                
            }
            this.descriptor = xmlDescriptor;
            
            rootRecord.setUnmarshaller(this.unmarshaller);
            rootRecord.setXMLReader(this.getXMLReader());

            if (locator != null) {
            	rootRecord.setDocumentLocator(xmlReader.getLocator());
            }
            rootRecord.setAttributes(atts);

            boolean hasNilAttribute = (atts != null && null != atts.getValue(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE));                       
            rootRecord.setNil(isNil || hasNilAttribute);
          
            rootRecord.setUnmarshalNamespaceResolver(unmarshalNamespaceResolver);
            
            rootRecord.startDocument();
            rootRecord.initializeRecord((Mapping) null);
            xmlReader.setContentHandler(rootRecord);
            xmlReader.setLexicalHandler(rootRecord);
            
            Object attributeGroup = this.unmarshaller.getUnmarshalAttributeGroup();
            if(attributeGroup != null) {
                if(attributeGroup.getClass() == ClassConstants.STRING) {
                    CoreAttributeGroup group = descriptor.getAttributeGroup((String)attributeGroup);
                    if(group != null) {
                    	rootRecord.setUnmarshalAttributeGroup(group);
                    } else {
                        //Error
                    }
                } else if(attributeGroup instanceof CoreAttributeGroup) {
                	rootRecord.setUnmarshalAttributeGroup((CoreAttributeGroup)attributeGroup);
                } else {
                    //Error case
                }
            }

            rootRecord.startElement(namespaceURI, localName, qName, atts);

            // if we located the descriptor via xsi:type attribute, create and 
            // return an XMLRoot object 
        } catch (EclipseLinkException e) {
            if (null == xmlReader.getErrorHandler()) {
                throw e;
            } else {
                SAXParseException saxParseException = new SAXParseException(null, null, null, 0, 0, e);
                xmlReader.getErrorHandler().error(saxParseException);
            }
        }
    }

    public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
    }

    public void characters(CharSequence characters) throws SAXException {
    }

    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
    }

    public void processingInstruction(String target, String data) throws SAXException {
    }

    public void skippedEntity(String name) throws SAXException {
    }

    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    public Unmarshaller getUnmarshaller() {
        return this.unmarshaller;
    }
    
    public void setKeepAsElementPolicy(UnmarshalKeepAsElementPolicy policy) {
        this.keepAsElementPolicy = policy;
    }
    
    public UnmarshalKeepAsElementPolicy getKeepAsElementPolicy() {
        return this.keepAsElementPolicy;
    }

	@Override
	public void setNil(boolean isNil) {
		this.isNil = isNil;
		
	}

}