/*
 * 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.oxm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.XMLConversionPair;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathPredicate;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractUnmarshalRecord;

/**
 * TopLink XML mappings make use of XMLFields based on XPath statements to find the relevant
 * data in an XML document.  The XPath statement is relative to the context node specified in the descriptor.
 * The XPath may contain node type, path, and positional information.  The XPath is specified on the
 * field using the <code>setXPath</code> method or by using the appropriate constructor.
 *
 * <p>The following XPath statements may be used to specify the location of XML data relating to an object's
 * name attribute:
 *
 * <table border="1">
 * <caption>XPath statements</caption>
 * <tr>
 * <th id="c1">XPath</th>
 * <th id="c2">Description</th>
 * </tr>
 * <tr>
 * <td headers="c1">@name</td>
 * <td headers="c2">The "@" character indicates that the node is an attribute.</td>
 * </tr>
 * <tr>
 * <td headers="c1">text()</td>
 * <td headers="c2">"text()" indicates that the node is a text node.  In this case the name value in the
 * text node belongs to the context node.</td>
 * </tr>
 * <tr>
 * <td headers="c1">full-name/text()</td>
 * <td headers="c2">The name information is stored in the text node of the full-name element.</td>
 * </tr>
 * <tr>
 * <td headers="c1" style="nowrap">personal-info/name/text()</td>
 * <td headers="c2">The XPath statement may be used to specify any valid path.</td>
 * </tr>
 * <tr>
 * <td headers="c1">name[2]/text()</td>
 * <td headers="c2">The XPath statement may contain positional information.  In this case the name
 * information is stored in the text node of the second occurrence of the name element.</td>
 * </tr>
 * </table>
 * <p><b>Mapping to a Specific Schema Type</b>: In most cases TopLink can determine the target format in the
 * XML document.  However, there are cases where you must specify which one of a number of possible targets
 * TopLink should use. For example, a java.util.Calendar could be marshalled to a schema date, time, or dateTime,
 * or a byte[] could be marshalled to a schema hexBinary or base64Binary node.
 *
 * <!--
 *    <?xml version="1.0" encoding="UTF-8"?>
 *    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 *        <xsd:element name="customer" type="customer-type"/>
 *        <xsd:complexType name="customer-type">
 *            <xsd:sequence>
 *                <xsd:element name="picture" type="xsd:hexBinary"/>
 *                <xsd:element name="resume" type="xsd:base64Binary"/>
 *            </xsd:sequence>
 *        </xsd:complexType>
 *    </xsd:schema>
 * -->
 *
 * <p><em>XML Schema</em><br>
 * <code>
 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
 * &lt;xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:element name="customer" type="customer-type"/&gt;<br>
 * &nbsp;&nbsp;&lt;xsd:complexType name="customer-type"&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="picture" type="xsd:hexBinary"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name="resume" type="xsd:base64Binary"/&gt;<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;<br>
 * &nbsp;&nbsp;&lt;/xsd:complexType&gt;<br>
 * &lt;/xsd:schema&gt;<br>
 * </code>
 *
 * <p><em>Code Sample</em><br>
 * <code>
 * XMLField pictureField = new XMLField("picture/text()")<br>
 * pictureField.setSchemaType(XMLConstants.HEX_BINARY_QNAME);<br>
 * </code>
 *
 * <p><b>Setting custom conversion pairs</b>: By default in TopLink XML built-in schema types are associated with
 * java classes and vice versa.  These default pairs can be modified by the user using the addJavaConversion and
 * addXMLConversion api.  For example by default a java.util.Calendar is mapped to the dateTime schema type
 * so the XML will be formated based on that type.  Below are the default schema type to java type conversion pairs
 * and the default java type to schema type conversion pairs.
 * <table border="1">
 * <caption>XML schema type to Java type default conversion pairs</caption>
 * <tr>
 * <th id="c3">Schema Type</th>
 * <th id="c4">Java Type</th>
 * </tr>
 * <tr>
 * <td headers="c3">base64Binary</td>
 * <td headers="c4">byte[]</td>
 * </tr>
 * <tr>
 * <td headers="c3">boolean</td>
 * <td headers="c4">boolean</td>
 * </tr>
 * <tr>
 * <td headers="c3">byte</td>
 * <td headers="c4">byte</td>
 * </tr>
 * <tr>
 * <td headers="c3">date</td>
 * <td headers="c4">java.util.Calendar</td>
 * </tr>
 * <tr>
 * <td headers="c3">dateTime</td>
 * <td headers="c4">java.util.Calendar</td>
 * </tr>
 * <tr>
 * <td headers="c3">decimal</td>
 * <td headers="c4">java.math.BigDecimal</td>
 * </tr>
 * <tr>
 * <td headers="c3">double</td>
 * <td headers="c4">double</td>
 * </tr>
 * <tr>
 * <td headers="c3">float</td>
 * <td headers="c4">float</td>
 * </tr>
 * <tr>
 * <td headers="c3">hexBinary</td>
 * <td headers="c4">byte[]</td>
 * </tr>
 * <tr>
 * <td headers="c3">int</td>
 * <td headers="c4">int</td>
 * </tr>
 * <tr>
 * <td headers="c3">integer</td>
 * <td headers="c4">java.math.BigInteger</td>
 * </tr>
 * <tr>
 * <td headers="c3">long</td>
 * <td headers="c4">long</td>
 * </tr>
 * <tr>
 * <td headers="c3">QName</td>
 * <td headers="c4">javax.xml.namespace.QName</td>
 * </tr>
 * <tr>
 * <td headers="c3">time</td>
 * <td headers="c4">java.util.Calendar</td>
 * </tr>
 * <tr>
 * <td headers="c3">unsignedByte</td>
 * <td headers="c4">short</td>
 * </tr>
 * <tr>
 * <td headers="c3">unsignedInt</td>
 * <td headers="c4">long</td>
 * </tr>
 * <tr>
 * <td headers="c3">unsignedShort</td>
 * <td headers="c4">int</td>
 * </tr>
 * <tr>
 * <td headers="c3">anySimpleType</td>
 * <td headers="c4">java.lang.String</td>
 * </tr>
 * </table>
 *
 * <table border="1">
 * <caption>Java type to XML schema type default conversion pairs</caption>
 * <tr>
 * <th id="c5">Java Type</th>
 * <th id="c6">Schema Type</th>
 * </tr>
 * <tr>
 * <td headers="c5">byte[]</td>
 * <td headers="c6">hexBinary</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Byte[]</td>
 * <td headers="c6">hexBinary</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.math.BigDecimal</td>
 * <td headers="c6">decimal</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.math.BigInteger</td>
 * <td headers="c6">integer</td>
 * </tr>
 * <tr>
 * <td headers="c5">boolean</td>
 * <td headers="c6">boolean</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Boolean</td>
 * <td headers="c6">boolean</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Byte</td>
 * <td headers="c6">Byte</td>
 * </tr>
 * <tr>
 * <td headers="c5">byte</td>
 * <td headers="c6">byte</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.util.Calendar</td>
 * <td headers="c6">dateTime</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.util.GregorianCalendar</td>
 * <td headers="c6">dateTime</td>
 * </tr>
 * <tr>
 * <td headers="c5">double</td>
 * <td headers="c6">double</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Double</td>
 * <td headers="c6">double</td>
 * </tr>
 * <tr>
 * <td headers="c5">float</td>
 * <td headers="c6">float</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Float</td>
 * <td headers="c6">float</td>
 * </tr>
 * <tr>
 * <td headers="c5">int</td>
 * <td headers="c6">int</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Integer</td>
 * <td headers="c6">int</td>
 * </tr>
 * <tr>
 * <td headers="c5">long</td>
 * <td headers="c6">long</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Long</td>
 * <td headers="c6">long</td>
 * </tr>
 * <tr>
 * <td headers="c5">short</td>
 * <td headers="c6">short</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.Short</td>
 * <td headers="c6">short</td>
 * </tr>
 * <tr>
 * <td headers="c5">javax.xml.namespace.QName</td>
 * <td headers="c6">QName</td>
 * </tr>
 * <tr>
 * <td headers="c5">java.lang.String</td>
 * <td headers="c6">string</td>
 * </tr>
 * </table>
 * @see org.eclipse.persistence.oxm.XMLUnionField
 */
public class XMLField extends DatabaseField implements Field<XMLConversionManager, NamespaceResolver> {
    private NamespaceResolver namespaceResolver;
    private QName schemaType;
    private XPathFragment xPathFragment;
    private XPathFragment lastXPathFragment;
    private boolean isCDATA = false;
    private boolean isRequired = false;
    private boolean isInitialized = false;
    private boolean nestedArray = false;

    /** Makes this maintain the collection of items in a single attribute or element instead of having one element per item in the collection.
    * Default is false */
    private boolean usesSingleNode;

    // Hashtables for the non-default conversions, these Hashtables are
    // used if the user has made any modifications to the pairs
    protected HashMap userXMLTypes;
    protected HashMap userJavaTypes;
    protected boolean isTypedTextField;
    protected QName leafElementType;

    /**
     * Default constructor, create a new XMLField
     */
    public XMLField() {
        super();
        isTypedTextField = false;
    }

    /**
     * Default constructor, create a new XMLField based on the specified xPath
     * @param xPath The xPath statement for this field
     */
    public XMLField(String xPath) {
        super(xPath, new DatabaseTable());
        isTypedTextField = false;
    }

    @Override
    public void initialize() {
        if(null != xPathFragment) {
           initializeXPathFragment(xPathFragment);
        }
        isInitialized = true;
    }

    private void initializeXPathFragment(XPathFragment xPathFragment) {
        XPathPredicate predicate = xPathFragment.getPredicate();
        if(null != predicate) {
            initializeXPathFragment(predicate.getXPathFragment());
        }

        String localName = xPathFragment.getLocalName();
        if(localName !=null && !localName.equals(XMLConstants.EMPTY_STRING)){
            if(null == xPathFragment.getNamespaceURI()) {
                if(xPathFragment.hasNamespace()) {
                    if(null == namespaceResolver) {
                        throw XMLMarshalException.namespaceNotFound(xPathFragment.getShortName());
                    } else {
                        String uri = namespaceResolver.resolveNamespacePrefix(xPathFragment.getPrefix());
                        if(null == uri && null != xPathFragment.getPrefix()) {
                            throw XMLMarshalException.namespaceNotFound(xPathFragment.getShortName());
                        }
                        xPathFragment.setNamespaceURI(uri);
                    }
                }
                else if(!xPathFragment.isAttribute() && null != namespaceResolver) {
                    xPathFragment.setNamespaceURI(namespaceResolver.getDefaultNamespaceURI());
                }
            }
        }
        XPathFragment nextXPathFragment = xPathFragment.getNextFragment();
        if(null != nextXPathFragment) {
            initializeXPathFragment(nextXPathFragment);
        }
    }

    /**
         * Returns the xpath statement associated with this XMLField
         * @return The xpath statement associated with this XMLField
         */
    @Override
    public String getXPath() {
        return getName();
    }

    /**
        * Set the xpath statment for this XMLField.
        * @param xPath The xpath statement to be associated with this XMLField
        */
    @Override
    public void setXPath(String xPath) {
        setName(xPath);
    }

    /**
     * Get the NamespaceResolver associated with this XMLField
     * @return The NamespaceResolver associated with this XMLField
     * @see org.eclipse.persistence.oxm.NamespaceResolver
     */
    @Override
    public NamespaceResolver getNamespaceResolver() {
        return namespaceResolver;
    }

    /**
     * Set the NamespaceResolver associated with this XMLField
     * @param newNamespaceResolver The namespaceResolver to be associated with this XMLField
     * @see org.eclipse.persistence.oxm.NamespaceResolver
     */
    @Override
    public void setNamespaceResolver(NamespaceResolver newNamespaceResolver) {
        namespaceResolver = newNamespaceResolver;
    }

    /**
    * PUBLIC:
    * Sets whether the mapping uses a single node.
    * @param usesSingleNode True if the items in the collection are in a single node or false if each of the items in the collection is in its own node
    */
    @Override
    public void setUsesSingleNode(boolean usesSingleNode) {
        this.usesSingleNode = usesSingleNode;
    }

    /**
    * PUBLIC:
    * Checks whether the mapping uses a single node.
    *
    * @return True if the items in the collection are in a single node or false if each of the items in the collection is in its own node.
    */
    @Override
    public boolean usesSingleNode() {
        return usesSingleNode;
    }

    /**
     * Sets the schematype associated with this XMLField
     * This is an optional setting; when set the schema type will be used to format the XML appropriately
     * @param value QName to be added to the list of schema types
     */
    @Override
    public void setSchemaType(QName value) {
        this.schemaType = value;
    }

    /**
    * Return the schema type associated with this field
    * @return the schema type
    */
    @Override
    public QName getSchemaType() {
        return schemaType;
    }

    /**
      * Returns if the field is a typed text field
      * True when we should base conversions on the "type" attribute on elements
      * @return True when we should base conversions on the "type" attribute on elements, otherwise false
      */
    @Override
    public boolean isTypedTextField() {
        return isTypedTextField;
    }

    /**
     * Set if the field is a typed text field
     * True when we should base conversions on the "type" attribute on elements
     * @param value The boolean value specifiy if  this is a typed text field
     */
    @Override
    public void setIsTypedTextField(boolean value) {
        isTypedTextField = value;
    }

    /**
     * INTERNAL:
     * Indicates if the xpath for this field is "."
     *
     * @return true if the xpath is ".", false otherwise
     */
    @Override
    public boolean isSelfField() {
        if (null == xPathFragment) {
            return false;
        }
        return xPathFragment.isSelfFragment();
    }

    /**
    * INTERNAL:
    * Returns false since this is a union field
     * The subclass XMLUnionField returns true for this
    */
    @Override
    public boolean isUnionField() {
        return false;
    }

    /**
     * Override setName in superclass
     */
    @Override
    public void setName(String xPath, String startDelimiter, String endDelimiter) {
        super.setName(xPath, null, null);

        if (hasPath(xPath)) {
            buildFragments(xPath);
        } else {
            XPathFragment xPathFragment = new XPathFragment(xPath.intern());
            xPathFragment.setXMLField(this);
            setXPathFragment(xPathFragment);
            setLastXPathFragment(xPathFragment);
        }
    }

    /**
     * This has the same effect as calling the setXPath method
     *
     * @param xPath The xPath associated with this XMLField
     */
    @Override
    public void setName(String xPath) {
        setName(xPath, null, null);
    }

    private boolean hasPath(String xpathString) {
        return ((xpathString != null) && (xpathString.indexOf('/') != -1));
    }

    private void buildFragments(String xpathString) {
        StringTokenizer st = new StringTokenizer(xpathString, "/", true);
        String next;
        int i = 0;
        XPathFragment currentXPathFragment = null;
        XPathFragment nextXPathFragment = null;

        while (st.hasMoreTokens()) {
            next = st.nextToken();
            if (null != next) {
                if ("/".equals(next)) {
                    if (0 == i) {
                        next = "/" + st.nextToken();
                    } else {
                        continue;
                    }
                }
                if (next.contains("[") && !next.contains("]")) {
                    StringBuilder sb = new StringBuilder(next);
                    String more;
                    while (st.hasMoreTokens()) {
                        more = st.nextToken();
                        sb.append(more);
                        if (more.contains("]"))
                            break;
                    }
                    next = sb.toString().intern();
                } else {
                    next = next.intern();
                }
                nextXPathFragment = new XPathFragment(next);
                if (0 == i) {
                    setXPathFragment(nextXPathFragment);
                } else {
                    currentXPathFragment.setNextFragment(nextXPathFragment);
                    if (nextXPathFragment.isAttribute() || nextXPathFragment.nameIsText()) {
                        currentXPathFragment.setHasText(true);
                    }
                }
                nextXPathFragment.setXMLField(this);
                currentXPathFragment = nextXPathFragment;
                i++;
            }
            setLastXPathFragment(currentXPathFragment);
        }
    }

    /**
     * INTERNAL:
     * Maintain a direct pointer to the first XPathFragment.  For example given
     * the following XPath first/middle/@last, first is the first XPathFragment.
     */
    @Override
    public XPathFragment getXPathFragment() {
        return xPathFragment;
    }

    /**
     * INTERNAL:
     * Return the first XPathFragment.
     */
    public void setXPathFragment(XPathFragment xPathFragment) {
        this.xPathFragment = xPathFragment;
    }

    /**
     * INTERNAL:
     * Return the last XPathFragment.
     */
    @Override
    public XPathFragment getLastXPathFragment() {
        return lastXPathFragment;
    }

    /**
     * INTERNAL:
     * Maintain a direct pointer to the last XPathFragment.  For example given
     * the following XPath first/middle/@last, @last is the last XPathFragment.
     */
    public void setLastXPathFragment(XPathFragment lastXPathFragment) {
        this.lastXPathFragment = lastXPathFragment;
    }

    /**
    * INTERNAL
    * Return the class for a given qualified XML Schema type
    * @param qname The qualified name of the XML Schema type to use as a key in the lookup
    * @return The class corresponding to the specified schema type, if no corresponding match found returns null
    */
    public Class getJavaClass(QName qname) {
        return getJavaClass(qname, XMLConversionManager.getDefaultXMLManager());
    }

    /**
     * INTERNAL
     * @return the class for a given qualified XML Schema type.
     * @since EclipseLink 2.6.0
     */
    @Override
    public Class getJavaClass(QName qname, ConversionManager conversionManager) {
        if (userXMLTypes != null) {
            Class theClass = (Class)userXMLTypes.get(qname);
            if(theClass != null){
                return theClass;
            }
        }
        return conversionManager.javaType(qname);
    }

    /**
     * Return the qualified XML Schema type for a given class
     * @param javaClass The class to use as a key in the lookup
     * @return QName The qualified XML Schema type, if no corresponding match found returns null
     */
    public QName getXMLType(Class javaClass) {
        return getXMLType(javaClass, XMLConversionManager.getDefaultXMLManager());
    }

    /**
     * @return the XML Schema type for a given class.
     * @since EclipseLink 2.6.0
     */
    @Override
    public QName getXMLType(Class javaClass, ConversionManager conversionManager) {
        if (userJavaTypes != null) {
            QName theQName = (QName)userJavaTypes.get(javaClass);
            if (theQName !=null) {
                return theQName;
            }
        }

        return conversionManager.schemaType(javaClass);
    }

    /**
    * @return a HashMap of Java to XML Schema type conversion pairs
    */
    private HashMap getUserJavaTypes() {
        // If no manual modifications have been made to the conversion pairs yet,
        // userJavaTypes will be null and needs to be built
        if (userJavaTypes == null) {
            userJavaTypes = new HashMap();
        }
        return userJavaTypes;
    }

    /**
     * @return a HashMap of XML Schema types to Java types conversion pairs
     */
    private HashMap getUserXMLTypes() {
        // If no manual modifications have been made to the conversion pairs yet,
        // userXMLTypes will be null and needs to be built
        if (userXMLTypes == null) {
            userXMLTypes = new HashMap();
        }
        return userXMLTypes;
    }

    /**
    * INTERNAL:
    */
    public ArrayList getUserXMLTypesForDeploymentXML() {
        if (userXMLTypes != null) {
            ArrayList types = new ArrayList(userXMLTypes.size());
            Iterator iter = userXMLTypes.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry)iter.next();
                XMLConversionPair pair = new XMLConversionPair((QName)entry.getKey(),((Class)entry.getValue()).getName());
                types.add(pair);
            }
            return types;
        }
        return null;
    }

    /**
    * INTERNAL:
    */
    public void setUserXMLTypesForDeploymentXML(ArrayList pairs) throws Exception {
        if (pairs.size() > 0) {
            userXMLTypes = new HashMap();
            Iterator iter = pairs.iterator();
            while (iter.hasNext()) {
                XMLConversionPair pair = (XMLConversionPair)iter.next();
                if ((pair.getXmlType() != null) && (pair.getJavaType() != null)) {
                    userXMLTypes.put(pair.getXmlType(), Class.forName(pair.getJavaType()));
                }
            }
        }
    }

    /**
    * INTERNAL:
    */
    public ArrayList getUserJavaTypesForDeploymentXML() {
        if (userJavaTypes != null) {
            ArrayList types = new ArrayList(userJavaTypes.size());
            Iterator iter = userJavaTypes.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry)iter.next();
                XMLConversionPair pair = new XMLConversionPair((QName)entry.getValue(), ((Class)entry.getKey()).getName());
                types.add(pair);
            }
            return types;
        }
        return null;
    }

    /**
    * INTERNAL:
    */
    public void setUserJavaTypesForDeploymentXML(ArrayList pairs) throws Exception {
        if (pairs.size() > 0) {
            userJavaTypes = new HashMap();
            Iterator iter = pairs.iterator();
            while (iter.hasNext()) {
                XMLConversionPair pair = (XMLConversionPair)iter.next();
                if ((pair.getXmlType() != null) && (pair.getJavaType() != null)) {
                    userJavaTypes.put(Class.forName(pair.getJavaType()), pair.getXmlType());
                }
            }
        }
    }

    /**
    * INTERNAL:
    * Called from DOMRecord and XMLReader.  MappingNodeValues call XMLReader which calls this method so that other XMLReader subclasses can override.
    */
    @Override
    public Object convertValueBasedOnSchemaType(Object value, XMLConversionManager xmlConversionManager, AbstractUnmarshalRecord record) {
        if (schemaType != null) {
            if(XMLConstants.QNAME_QNAME.equals(schemaType)){
                return xmlConversionManager.buildQNameFromString((String)value, record);
            }else{
                Class fieldType = getType();
                if (fieldType == null) {
                    fieldType = getJavaClass(schemaType, xmlConversionManager);
                }
                return xmlConversionManager.convertObject(value, fieldType, schemaType);
            }
        }
        return value;
    }


    /**
    * Add an XML to Java Conversion pair entry
    * @param qname The qualified name of the XML schema type
    * @param javaClass The class to add
    */
    public void addXMLConversion(QName qname, Class javaClass) {
        getUserXMLTypes().put(qname, javaClass);
    }

    /**
     * Add a Java to XML Conversion pair entry
     * @param javaClass The class to add
     * @param qname The qualified name of the XML schema type
     */
    public void addJavaConversion(Class javaClass, QName qname) {
        getUserJavaTypes().put(javaClass, qname);
    }

    /**
     * Add an entry for both an XML Conversion and a Java Conversion entry
     * @param qname The qualified name of the XML schema type
     */
    public void addConversion(QName qname, Class javaClass) {
        addJavaConversion(javaClass, qname);
        addXMLConversion(qname, javaClass);
    }

    /**
     * Remove an XML to Java Conversion entry
     */
    public void removeXMLConversion(QName qname) {
        getUserXMLTypes().remove(qname);
    }

    /**
     * Remove a Java to XML Conversion entry
     *
     */
    public void removeJavaConversion(Class javaClass) {
        getUserJavaTypes().remove(javaClass);
    }

    /**
     * Remove both a Java to XML Conversion and the corresponding XML to Java Conversion entry
     *
     */
    public void removeConversion(QName qname, Class javaClass) {
        removeJavaConversion(javaClass);
        removeXMLConversion(qname);
    }

    /**
     * Assumes type is in the format prefix:localPart, or localPart.
     *
     */
    public void setLeafElementType(QName type) {
        leafElementType = type;
        if (hasLastXPathFragment()) {
            getLastXPathFragment().setLeafElementType(type);
        }
    }

    @Override
    public QName getLeafElementType() {
        if (lastXPathFragment != null) {
            return lastXPathFragment.getLeafElementType();
        }
        return leafElementType;
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean hasLastXPathFragment() {
        return lastXPathFragment != null;
    }

    /**
     * INTERNAL:
     */
    @Override
    public QName getSchemaTypeForValue(Object value, CoreAbstractSession session) {
        if(leafElementType != null){
            return leafElementType;
        }else if (isTypedTextField) {
            if (CoreClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(value.getClass())){
                return ((XMLGregorianCalendar) value).getXMLSchemaType();
            }else if (CoreClassConstants.DURATION.isAssignableFrom(value.getClass())){
                ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
                return getXMLType(CoreClassConstants.DURATION, conversionManager);
            }
            ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
            return getXMLType(value.getClass(), conversionManager);
        }
        return schemaType;
    }


    /**
     * INTERNAL:
     */
    @Override
    public void setIsCDATA(boolean CDATA) {
        this.isCDATA = CDATA;
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean isCDATA() {
        return isCDATA;
    }
    /**
     * INTERNAL
     */
    @Override
    public boolean isSchemaType(QName schemaType){
        if(getSchemaType() == null){
            return false;
        }
        return getSchemaType().equals(schemaType);
    }

    /**
     * Indicates if this XMLField represents a "required" XML element or attribute
     * ([minOccurs="1"] for elements, [use="required"] for attributes).  NOTE: This
     * API is used only for Schema Generation.
     *
     * @see org.eclipse.persistence.internal.oxm.schema.SchemaModelGenerator
     */
    @Override
    public boolean isRequired() {
        return isRequired;
    }

    /**
     * Set whether this XMLField represents a "required" XML element or attribute
     * ([minOccurs="1"] for elements, [use="required"] for attributes).  NOTE: This
     * API is used only for Schema Generation.
     *
     * @see org.eclipse.persistence.internal.oxm.schema.SchemaModelGenerator
     */
    @Override
    public void setRequired(boolean isRequired) {
        this.isRequired = isRequired;
    }

    @Override
    public boolean equals(Object object) {
        try {
            if(!isInitialized) {
                return super.equals(object);
            }
            if(this == object) {
                return true;
            }
            XMLField xmlField = (XMLField) object;
            if(!xPathFragment.equals(xmlField.getXPathFragment())) {
                return false;
            }
            XPathFragment xpf = xPathFragment;
            XPathFragment xpf2 = xmlField.getXPathFragment();
            while(xpf.getNextFragment() != null) {
                xpf = xpf.getNextFragment();
                xpf2 = xpf2.getNextFragment();
                if(!xpf.equals(xpf2)) {
                    return false;
                }
            }
            return null == xpf2.getNextFragment();
        } catch(ClassCastException e) {
            return false;
        }
    }

    /**
     * Set nested array flag. Used in JSON marshalling.
     *
     * @param nestedArray flag.
     */
    @Override
    public void setNestedArray(boolean nestedArray) {
        this.nestedArray = nestedArray;
    }

    /**
     * INTERNAL:
     *
     * @return True if content is nested array.
     */
    @Override
    public boolean isNestedArray() {
        return this.nestedArray;
    }

    @Override
    public int hashCode() {
        if(null == xPathFragment && null == xPathFragment.getXPath()) {
            return 1;
        }
        return (xPathFragment.getXPath().replace((xPathFragment.getPrefix() != null) ? xPathFragment.getPrefix() + xPathFragment.getNamespaceSeparator() : "", "")).hashCode();
    }

}
