/*******************************************************************************
 * 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:
 *     Denise Smith - 2.5.1 - Initial Implementation
 ******************************************************************************/
package org.eclipse.persistence.internal.oxm;

import java.util.List;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
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.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.DirectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.internal.oxm.mappings.VariableXPathObjectMapping;
import org.eclipse.persistence.internal.oxm.record.MarshalContext;
import org.eclipse.persistence.internal.oxm.record.MarshalRecord;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public abstract class XMLVariableXPathMappingNodeValue extends XMLRelationshipMappingNodeValue{

	  
	/**
     * INTERNAL:
     * @param xPathFragment
     * @return
     */
	 public boolean isOwningNode(XPathFragment xPathFragment) {
	        return null == xPathFragment;
	 }
	 
    protected Descriptor findReferenceDescriptor(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts, Mapping mapping, UnmarshalKeepAsElementPolicy policy) {
       return (Descriptor)mapping.getReferenceDescriptor();
    }
 	
	 public void attribute(UnmarshalRecord unmarshalRecord, String namespaceURI, String localName, String value) {        
	        Descriptor referenceDescriptor = (Descriptor) getMapping().getReferenceDescriptor();
	        ObjectBuilder treeObjectBuilder = (ObjectBuilder) referenceDescriptor.getObjectBuilder();
	        MappingNodeValue textMappingNodeValue = (MappingNodeValue) treeObjectBuilder.getRootXPathNode().getTextNode().getNodeValue();
	        Mapping textMapping = textMappingNodeValue.getMapping();
	        Object childObject = referenceDescriptor.getInstantiationPolicy().buildNewInstance();
	        if(textMapping.isAbstractDirectMapping()) {
	            DirectMapping xmlDirectMapping = (DirectMapping) textMappingNodeValue.getMapping();
	            Field xmlField = (Field) xmlDirectMapping.getField();
	            Object realValue = unmarshalRecord.getXMLReader().convertValueBasedOnSchemaType(xmlField, value, (XMLConversionManager) unmarshalRecord.getSession().getDatasourcePlatform().getConversionManager(), unmarshalRecord);
	            Object convertedValue = xmlDirectMapping.getAttributeValue(realValue, unmarshalRecord.getSession(), unmarshalRecord);
	            xmlDirectMapping.setAttributeValueInObject(childObject, convertedValue);
	        } else {
	            Object oldChildObject = unmarshalRecord.getCurrentObject();
	            CompositeObjectMapping nestedXMLCompositeObjectMapping = (CompositeObjectMapping) textMappingNodeValue.getMapping();
	            unmarshalRecord.setCurrentObject(childObject);
	            textMappingNodeValue.attribute(unmarshalRecord, namespaceURI, localName, value);
	            unmarshalRecord.setCurrentObject(oldChildObject);
	        }	      	        	        
	        setXPathInObject(namespaceURI, localName, childObject);	       
	        setOrAddAttributeValue(unmarshalRecord, childObject, null, null);
	    }
	 	
    public boolean marshalSingleValue(XPathFragment xPathFragment, MarshalRecord marshalRecord, Object object, Object value, CoreAbstractSession session, NamespaceResolver namespaceResolver, MarshalContext marshalContext) {
        if (null == value) {
            return false;
        }

        Object originalValue = value;
	    VariableXPathObjectMapping mapping = (VariableXPathObjectMapping)this.getMapping();
	    Descriptor descriptor = (Descriptor)mapping.getReferenceDescriptor();

	    if(descriptor.hasInheritance()){
	      	Class objectValueClass = value.getClass();
	       	if(!(objectValueClass == descriptor.getJavaClass())){
	       		descriptor = (Descriptor) session.getDescriptor(objectValueClass);
	       	}
	    }
	        
	    Marshaller marshaller = marshalRecord.getMarshaller();	    
	    ObjectBuilder objectBuilder = (TreeObjectBuilder)descriptor.getObjectBuilder();
	    List extraNamespaces = objectBuilder.addExtraNamespacesToNamespaceResolver(descriptor, marshalRecord, session, true, true);
	    //Change to get the value from the object
	    String defaultRootElementString = descriptor.getDefaultRootElement();
	        
	    marshalRecord.beforeContainmentMarshal(value);
	    XPathFragment rootFragment = mapping.getXPathFragmentForValue(value, marshalRecord.getNamespaceResolver(), marshalRecord.isNamespaceAware(), marshalRecord.getNamespaceSeparator());
	    	     
	    XPathFragment groupingFragment = marshalRecord.openStartGroupingElements(namespaceResolver);
	    if(mapping.isAttribute()){	    	
	    	   ObjectBuilder tob = (ObjectBuilder) mapping.getReferenceDescriptor().getObjectBuilder();
	            MappingNodeValue textMappingNodeValue = (MappingNodeValue) tob.getRootXPathNode().getTextNode().getMarshalNodeValue();
	            Mapping textMapping = textMappingNodeValue.getMapping();
	            if(textMapping.isAbstractDirectMapping()) {
	                DirectMapping xmlDirectMapping = (DirectMapping) textMapping;
	                Object fieldValue = xmlDirectMapping.getFieldValue(xmlDirectMapping.valueFromObject(value, xmlDirectMapping.getField(), session), session, marshalRecord);
	                QName schemaType = ((Field) xmlDirectMapping.getField()).getSchemaTypeForValue(fieldValue, session);
	                marshalRecord.attribute(rootFragment, namespaceResolver, fieldValue, schemaType);
	                //marshalRecord.closeStartGroupingElements(groupingFragment);
	                return true;
	            } else {
	                return textMappingNodeValue.marshalSingleValue(rootFragment, marshalRecord, value, textMapping.getAttributeValueFromObject(value), session, namespaceResolver, marshalContext);
	            }
	    }else{
	    	marshalRecord.closeStartGroupingElements(groupingFragment);
	    getXPathNode().startElement(marshalRecord, rootFragment, object, session, marshalRecord.getNamespaceResolver(), objectBuilder, value);                
	    writeExtraNamespaces(extraNamespaces, marshalRecord, session); 
	        
	    marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, (Descriptor)mapping.getReferenceDescriptor(), (Field)mapping.getField(), originalValue, value, false, false);               
	    objectBuilder.buildRow(marshalRecord, value, session, marshaller, null);
	    marshalRecord.afterContainmentMarshal(object, value);
	    marshalRecord.endElement(rootFragment, namespaceResolver);
	    marshalRecord.removeExtraNamespacesFromNamespaceResolver(extraNamespaces, session);
	    }
	    return true;
    }
	  
	public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
	    UnmarshalRecord childRecord = unmarshalRecord.getChildRecord();
	    if(childRecord != null){
	        Object childObject = childRecord.getCurrentObject();
	        String localName = xPathFragment.getLocalName();
	        
	        setXPathInObject(xPathFragment.getNamespaceURI(), localName, childObject);
	        
	        childObject = getMapping().convertDataValueToObjectValue(childObject, unmarshalRecord.getSession(), unmarshalRecord.getUnmarshaller());
	        setOrAddAttributeValue(unmarshalRecord, childObject, xPathFragment, null);
	        unmarshalRecord.setChildRecord(null);
	    } else {                         
	         unmarshalRecord.resetStringBuffer();	               	           
	    }
	}
	    	  	
    public abstract VariableXPathObjectMapping getMapping();
	
    public void setXPathInObject(String uri, String localName, Object childObject) {
    	CoreAttributeAccessor variableAttributeAccessor = ((VariableXPathObjectMapping)this.getMapping()).getVariableAttributeAccessor();
    	if(!variableAttributeAccessor.isWriteOnly()){
    	Object value = null;
    	 if(((VariableXPathObjectMapping)getMapping()).getVariableAttributeAccessor().getAttributeClass() == ClassConstants.QNAME){
	             if(uri != null && uri.length() > 0) {
	            	 value =  new QName(uri, localName);
	             }else{
	            	 value =  new QName( localName);
	             }
	        }else{ 
	        	value = localName;
	        }
    	
    		variableAttributeAccessor.setAttributeValueInObject(childObject, value);
    	}
    }

	public boolean startElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord, Attributes atts) {
       	try {
			processChild(xPathFragment, unmarshalRecord, atts, (Descriptor) getMapping().getReferenceDescriptor(), getMapping());
		} catch (SAXException e) {
			throw XMLMarshalException.unmarshalException(e);
		}
     	return true;
	 }
		   
	@Override
    public boolean isMixedContentNodeValue() {
	     return true;
	}		 		
	
}
