/*
 * Copyright (c) 1998, 2021 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 v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper;


import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.mappings.AttributeAccessor;
import commonj.sdo.Property;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.w3c.dom.Node;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import commonj.sdo.helper.HelperContext;
import org.w3c.dom.Document;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDODataObject;

import org.eclipse.persistence.platform.xml.XMLPlatform;

/**
 * <p><b>Purpose</b>: A wrapper class for handling cases when the domain object attributes are
 * to be accessed thru the accessor methods that are called "get" and "set". This is to be used
 * when marsalling/unmarshalling SDODataObjects. The propertyName is the name of the property on
 * the DataObject and that must be set on this accessor.
 */
public class SDOFragmentMappingAttributeAccessor extends AttributeAccessor {
    protected SDOProperty property;
    protected HelperContext helperContext;

    public SDOFragmentMappingAttributeAccessor(SDOProperty property, HelperContext helper) {
        this.property = property;
        this.helperContext = helper;
    }

    /**
     * Gets the value of an instance variable in the object.
     */
    @Override
    public Object getAttributeValueFromObject(Object anObject) throws DescriptorException {
        Object attributeValue = ((SDODataObject)anObject).get(property);
        if (attributeValue != null) {
            if (property.isMany()) {
                //  handle collection case
                ArrayList<Object> fragments = new ArrayList<Object>();
                Iterator<Object> objects = ((Collection)attributeValue).iterator();
                while (objects.hasNext()) {
                    fragments.add(buildFragment(property, (SDODataObject)anObject, ((SDODataObject)objects.next())));
                }
                attributeValue = fragments;
            } else {
                attributeValue = buildFragment(property, (SDODataObject)anObject, (SDODataObject)attributeValue);
            }
        }

        return attributeValue;
    }

    /**
     * Set get and set method after creating these methods by using
     * get and set method names
     */
    @Override
    public void initializeAttributes(Class<?> theJavaClass) throws DescriptorException {
        if (getAttributeName() == null) {
            throw DescriptorException.attributeNameNotSpecified();
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isMethodAttributeAccessor() {
        return true;
    }

    /**
     * Sets the value of the instance variable in the object to the value.
     */
    @Override
    public void setAttributeValueInObject(Object domainObject, Object attributeValue) throws DescriptorException {
        XMLUnmarshaller unmarshaller = ((SDOXMLHelper)helperContext.getXMLHelper()).getXmlContext().createUnmarshaller();
        unmarshaller.setUnmarshalListener(new org.eclipse.persistence.sdo.helper.SDOCSUnmarshalListener(helperContext));

        if (attributeValue instanceof Collection) {
            //handle collection case
            ArrayList result = new ArrayList();
            Iterator fragments = ((Collection)attributeValue).iterator();
            while (fragments.hasNext()) {
                Node next = (Node)fragments.next();

                //Handle Simple Case here
                Object dataObject = unmarshaller.unmarshal(next);
                if(dataObject instanceof org.eclipse.persistence.oxm.XMLRoot) {
                    dataObject = ((XMLRoot)dataObject).getObject();
                }
                result.add(dataObject);
            }
            ((SDODataObject)domainObject).set(property, result);
        } else {
            Object result = null;
            if (!(attributeValue == null)) {
                Node value = (Node)attributeValue;
                result = unmarshaller.unmarshal(value);
            if(result instanceof org.eclipse.persistence.oxm.XMLRoot) {
                    result = ((XMLRoot)result).getObject();
                }
            }
            ((SDODataObject)domainObject).set(property, result);
        }
    }

    /**
      * INTERNAL:
      */
    public void setProperty(SDOProperty property) {
        this.property = property;
    }

    /**
     * INTERNAL:
     */
    public SDOProperty getPropertyName() {
        return property;
    }

    private Object buildFragment(Property property, SDODataObject parentObject, SDODataObject value) {
        //build an XML Fragment from this SDO
        XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
        XMLMarshaller xmlMarshaller = ((SDOXMLHelper)helperContext.getXMLHelper()).getXmlContext().createMarshaller();
        Document doc = xmlPlatform.createDocument();
        XMLRoot root = new XMLRoot();
        root.setObject(value);
        root.setLocalName(property.getName());
        if(((SDOProperty)property).isNamespaceQualified()){
          root.setNamespaceURI(parentObject.getType().getURI());
        }
        xmlMarshaller.marshal(root, doc);
        return doc.getDocumentElement();
    }
}
