/*
 * Copyright (c) 1998, 2020 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:
// mmacivor - June 05/2008 - 1.0 - Initial implementation
package org.eclipse.persistence.oxm.mappings.converters;

import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.sessions.Session;

/**
 * <p><b>Purpose: </b> Provides an implementation of XMLConverter to wrap/unwrap objects in an
 * XMLRoot in order to capture element name information.
 * <p><b>Responsibilities</b>
 * <ul>
 * <li>Wrap an object in an XMLRoot on unmarshal. Do any required conversions based on type for
 * simple mappings.
 * <li>Unwrap an XMLRoot from the object and pass it along to be marshalled.
 * </ul>
 * @see XMLConverter
 * @see org.eclipse.persistence.mappings.converters.Converter Converter
 */
public class XMLRootConverter implements XMLConverter {
    private XPathFragment rootFragment;
    private XMLField associatedField;
    private DatabaseMapping mapping;

    public XMLRootConverter(XMLField associatedField) {
        this.associatedField = associatedField;
    }

    @Override
    public Object convertDataValueToObjectValue(Object dataValue,
            Session session, XMLUnmarshaller unmarshaller) {
        return convertDataValueToObjectValue(dataValue, session);
    }

    @Override
    public Object convertObjectValueToDataValue(Object objectValue,
            Session session, XMLMarshaller marshaller) {
        return convertObjectValueToDataValue(objectValue, session);
    }

    @Override
    public Object convertDataValueToObjectValue(Object dataValue,
            Session session) {
        XMLRoot root = new XMLRoot();
        root.setLocalName(this.rootFragment.getLocalName());
        root.setNamespaceURI(this.rootFragment.getNamespaceURI());

        if(mapping.isAbstractDirectMapping()){
            if ((dataValue == null) || (dataValue.getClass() != mapping.getAttributeClassification())) {
                try {
                    dataValue = session.getDatasourcePlatform().convertObject(dataValue, mapping.getAttributeClassification());
                } catch (ConversionException e) {
                    throw ConversionException.couldNotBeConverted(this, mapping.getDescriptor(), e);
                }
            }
        }

        root.setObject(dataValue);

        return root;
    }

    @Override
    public Object convertObjectValueToDataValue(Object objectValue,
            Session session) {
        if(objectValue instanceof XMLRoot) {
            return ((XMLRoot)objectValue).getObject();
        } else {
            return objectValue;
        }
    }

    @Override
    public void initialize(DatabaseMapping mapping, Session session) {
        XPathFragment fragment = associatedField.getXPathFragment();
        while(fragment.getNextFragment() != null && !(fragment.getNextFragment().nameIsText())) {
            fragment = fragment.getNextFragment();
        }
        if(fragment.hasNamespace() && associatedField.getNamespaceResolver() != null){
            String uri = associatedField.getNamespaceResolver().resolveNamespacePrefix(fragment.getPrefix());
            fragment.setNamespaceURI(uri);
        }
        this.rootFragment = fragment;
        this.mapping = mapping;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

}
