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

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.XMLChoiceFieldToClassAssociation;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.mappings.ChoiceObjectMapping;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.ObjectDescriptor;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.converters.Converter;
import org.eclipse.persistence.mappings.foundation.AbstractCompositeObjectMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.mappings.converters.XMLConverter;
import org.eclipse.persistence.oxm.mappings.converters.XMLRootConverter;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.namespace.QName;

/**
 * PUBLIC:
 * <p><b>Purpose:</b>Provide a mapping that can map a single attribute to a number of
 * different elements in an XML Document. This will be used to map to Choices or Substitution
 * Groups in an XML Schema
 * <p><b>Responsibilities:</b><ul>
 * <li>Allow the user to specify XPath {@literal ->} Type mappings</li>
 * <li>Handle reading and writing of XML Documents containing a single choice or substitution
 * group element</li>
 * </ul>
 * <p>The XMLChoiceMapping allows the user to specify a number of different xpaths, and types associated with those xpaths.
 * When any of these elements are encountered in the XML Document, they are read in as the correct
 * type and set in the object.
 * <p><b>Setting up XPath mappings:</b>Unlike other OXM Mappings, instead of setting a single xpath,
 * the addChoiceElement method is used to specify an xpath and the type associated with this xpath.
 * <br>
 * xmlChoiceCollectionMapping.addChoiceElement("mystring/text()", String.class);
 * <br>
 * xmlChoiceCollectionMapping.addChoiceElement("myaddress", Address.class);
 *
 */

public class XMLChoiceObjectMapping extends DatabaseMapping implements ChoiceObjectMapping<AttributeAccessor, AbstractSession, ContainerPolicy, Converter, ClassDescriptor, DatabaseField, XMLMarshaller, Session, XMLUnmarshaller, XMLField, XMLMapping, XMLRecord>, XMLMapping {
    private Map<XMLField, Class<?>> fieldToClassMappings;
    private Map<Class<?>, XMLField> classToFieldMappings;
    private Map<String, XMLField> classNameToFieldMappings;
    private Map<Class<?>, List<XMLField>> classToSourceFieldsMappings;
    private Map<String, List<XMLField>> classNameToSourceFieldsMappings;
    private Map<XMLField, String> fieldToClassNameMappings;
    private Map<XMLField, XMLMapping> choiceElementMappings;
    private Map<Class<?>, XMLMapping> choiceElementMappingsByClass;
    private Map<String, XMLMapping> choiceElementMappingsByClassName;
    private Map<XMLField, Converter> fieldsToConverters;
    private Map<String, Converter> classNameToConverter;
    private Map<Class<?>, Converter> classToConverter;

    private Converter converter;
    private boolean isWriteOnly;

    private static final AttributeAccessor temporaryAccessor = new InstanceVariableAttributeAccessor();

    private static final String DATA_HANDLER = "jakarta.activation.DataHandler";
    private static final String MIME_MULTIPART = "jakarta.mail.internet.MimeMultipart";
    private static final String IMAGE = "java.awt.Image";

    public XMLChoiceObjectMapping() {
        fieldToClassMappings = new HashMap<>();
        fieldToClassNameMappings = new HashMap<>();
        classToFieldMappings = new HashMap<>();
        classNameToFieldMappings = new HashMap<>();
        choiceElementMappings = new LinkedHashMap<>();
        choiceElementMappingsByClass = new LinkedHashMap<>();
        choiceElementMappingsByClassName = new LinkedHashMap<>();
        fieldsToConverters = new HashMap<>();
    }

    /**
     * Return the converter on the mapping.
     * A converter can be used to convert between the object's value and database value of the attribute.
     */
    @Override
    public Converter getConverter() {
        return converter;
    }

    /**
     * Set the converter on the mapping.
     * A converter can be used to convert between the object's value and database value of the attribute.
     */
    @Override
    public void setConverter(Converter converter) {
        this.converter = converter;
    }

    /**
     * INTERNAL:
     * Clone the attribute from the clone and assign it to the backup.
     */
    @Override
    public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        throw DescriptorException.invalidMappingOperation(this, "buildBackupClone");
    }

    /**
    * INTERNAL:
    * Clone the attribute from the original and assign it to the clone.
    */
    @Override
    public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
        throw DescriptorException.invalidMappingOperation(this, "buildClone");
    }

    @Override
    public void buildCloneFromRow(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey, ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork, AbstractSession executionSession) {
        throw DescriptorException.invalidMappingOperation(this, "buildCloneFromRow");
    }

    /**
     * INTERNAL:
     * Cascade perform delete through mappings that require the cascade
     */
    @Override
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        //objects referenced by this mapping are not registered as they have
        // no identity, this is a no-op.
    }

    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     */
    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        //Our current XML support does not make use of the UNitOfWork.
    }

    /**
     * INTERNAL:
     * This method was created in VisualAge.
     * @return prototype.changeset.ChangeRecord
     */
    @Override
    public ChangeRecord compareForChange(Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) {
        throw DescriptorException.invalidMappingOperation(this, "compareForChange");
    }

    /**
    * INTERNAL:
    * Compare the attributes belonging to this mapping for the objects.
    */
    @Override
    public boolean compareObjects(Object firstObject, Object secondObject, AbstractSession session) {
        throw DescriptorException.invalidMappingOperation(this, "compareObjects");
    }

    /**
    * INTERNAL:
    * An object has been serialized from the server to the client.
    * Replace the transient attributes of the remote value holders
    * with client-side objects.
    */
    @Override
    public void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        throw DescriptorException.invalidMappingOperation(this, "fixObjectReferences");
    }

    /**
    * INTERNAL:
    */
    @Override
    public Object getFieldValue(Object object, CoreAbstractSession session, AbstractMarshalRecord record) {
        Object attributeValue = super.getAttributeValueFromObject(object);
        attributeValue = convertObjectValueToDataValue(attributeValue, (AbstractSession) session, (XMLMarshaller) record.getMarshaller());
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Iterate on the appropriate attribute value.
     */
    @Override
    public void iterate(DescriptorIterator iterator) {
        throw DescriptorException.invalidMappingOperation(this, "iterate");
    }

    /**
     * INTERNAL:
     * Merge changes from the source to the target object.
     */
    @Override
    public void mergeChangesIntoObject(Object target, ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
        throw DescriptorException.invalidMappingOperation(this, "mergeChangesIntoObject");
    }

    /**
    * INTERNAL:
    * Merge changes from the source to the target object.
    */
    @Override
    public void mergeIntoObject(Object target, boolean isTargetUninitialized, Object source, MergeManager mergeManager, AbstractSession targetSession) {
        throw DescriptorException.invalidMappingOperation(this, "mergeIntoObject");
    }

    @Override
    public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey cacheKey, AbstractSession executionSession, boolean isTargetProtected, Boolean[] wasCacheUsed) throws DatabaseException {
        //try each of the fields and see if any of them has a value
        for(XMLMapping nextMapping:this.choiceElementMappings.values()) {
            Object value = ((DatabaseMapping)nextMapping).valueFromRow(row, joinManager, sourceQuery, cacheKey, executionSession, isTargetProtected, wasCacheUsed);
            if(value != null) {
                return value;
            }
        }
        return null;
    }

    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) throws DescriptorException {
        Object value = getAttributeValueFromObject(object);
        Class<?> valueClass = value.getClass();
        if(valueClass == XMLRoot.class) {
            //look for a nested mapping based on the Root's QName
            XMLRoot root = (XMLRoot)value;
            for(DatabaseField next:this.fields) {
                XMLField xmlField = (XMLField)next;
                XPathFragment fragment = xmlField.getXPathFragment();
                while(fragment != null && !fragment.nameIsText()) {
                    if(fragment.getNextFragment() == null || fragment.getHasText()) {
                        if(fragment.getLocalName().equals(root.getLocalName())) {
                            String fragUri = fragment.getNamespaceURI();
                            String namespaceUri = root.getNamespaceURI();
                            if((namespaceUri == null && fragUri == null) || (namespaceUri != null && fragUri != null && namespaceUri.equals(fragUri))) {
                                XMLMapping mapping = choiceElementMappings.get(xmlField);
                                mapping.writeSingleValue(value, object, (XMLRecord)row, session);
                                return;
                            }
                        }
                    }
                    fragment = fragment.getNextFragment();
                }
            }
            //If the root doesn't match any of the types, try the class
            valueClass = root.getObject().getClass();
        }
        XMLField valueField = this.classToFieldMappings.get(valueClass);
        if (valueField == null) {
            List<XMLField> xflds = getClassToSourceFieldsMappings().get(valueClass);
            if (xflds != null) {
                valueField = xflds.get(0);
            }
        }
        XMLMapping mapping = this.choiceElementMappings.get(valueField);
        if (mapping != null) {
            mapping.writeSingleValue(value, object, (XMLRecord)row, session);
        }
    }

    @Override
    public void writeSingleValue(Object value, Object parent, XMLRecord row, AbstractSession session) {
    }

    @Override
    public Object readFromRowIntoObject(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object targetObject, CacheKey parentCacheKey, ObjectBuildingQuery sourceQuery, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
        Object toReturn = super.readFromRowIntoObject(databaseRow, joinManager, targetObject, parentCacheKey, sourceQuery, executionSession, isTargetProtected);
        for(XMLMapping next:choiceElementMappings.values()) {
            if(((DatabaseMapping)next).isObjectReferenceMapping()) {
                ((DatabaseMapping)next).readFromRowIntoObject(databaseRow, joinManager, targetObject, parentCacheKey, sourceQuery, executionSession, isTargetProtected);
            }
        }
        return toReturn;
    }

    @Override
    public boolean isXMLMapping() {
        return true;
    }

    @Override
    public Vector<DatabaseField> getFields() {
        return this.collectFields();
    }

    @Override
    protected Vector<DatabaseField> collectFields() {
        Vector<DatabaseField> fields = new Vector<>(getFieldToClassMappings().keySet());
        return fields;
    }

    public void addChoiceElement(String xpath, Class<?> elementType) {
        XMLField field = new XMLField(xpath);
        addChoiceElement(field, elementType);
    }

    public void addChoiceElement(String srcXPath, Class<?> elementType, String tgtXPath) {
        XMLField srcField = new XMLField(srcXPath);
        XMLField tgtField = new XMLField(tgtXPath);
        addChoiceElement(srcField, elementType, tgtField);
    }

    public void addChoiceElement(String xpath, String elementTypeName, boolean xmlRoot) {
        XMLField field = new XMLField(xpath);
        this.fieldToClassNameMappings.put(field, elementTypeName);
        if(this.classNameToFieldMappings.get(elementTypeName) != null) {
            this.classNameToFieldMappings.put(elementTypeName, field);
        }
        if(xmlRoot) {
            this.fieldsToConverters.put(field, new XMLRootConverter(field));
        }
        addChoiceElementMapping(field, elementTypeName);
    }

    @Override
    public void addChoiceElement(String srcXpath, String elementTypeName, String tgtXpath) {
        XMLField field = new XMLField(srcXpath);
        XMLField tgtField = new XMLField(tgtXpath);
        this.fieldToClassNameMappings.put(field, elementTypeName);
        if(classNameToFieldMappings.get(elementTypeName) == null) {
            classNameToFieldMappings.put(elementTypeName, field);
        }
        addChoiceElementMapping(field, elementTypeName, tgtField);
    }
    public void addChoiceElement(String xpath, String elementTypeName) {
        addChoiceElement(xpath, elementTypeName, false);
    }

    public void addChoiceElement(XMLField xmlField, Class<?> elementType) {
        getFieldToClassMappings().put(xmlField, elementType);
        this.fieldToClassNameMappings.put(xmlField, elementType.getName());
        if (classToFieldMappings.get(elementType) == null) {
            classToFieldMappings.put(elementType, xmlField);
        }
        addChoiceElementMapping(xmlField, elementType);
    }

    public void addChoiceElement(XMLField sourceField, Class<?> elementType, XMLField targetField) {
        getFieldToClassMappings().put(sourceField, elementType);
        this.fieldToClassNameMappings.put(sourceField, elementType.getName());
        if (classToFieldMappings.get(elementType) == null) {
            classToFieldMappings.put(elementType, sourceField);
        }
        addChoiceElementMapping(sourceField, elementType, targetField);
    }

    public void addChoiceElement(XMLField sourceField, String elementTypeName, XMLField targetField) {
        this.fieldToClassNameMappings.put(sourceField, elementTypeName);
        addChoiceElementMapping(sourceField, elementTypeName, targetField);
    }

    public void addChoiceElement(List<XMLField> srcFields, Class<?> elementType, List<XMLField> tgtFields) {
        for(XMLField sourceField:srcFields) {
            getFieldToClassMappings().put(sourceField, elementType);
            this.fieldToClassNameMappings.put(sourceField, elementType.getName());
        }
        if (getClassToSourceFieldsMappings().get(elementType) == null) {
            getClassToSourceFieldsMappings().put(elementType, srcFields);
        }
        addChoiceElementMapping(srcFields, elementType, tgtFields);
    }

    @Override
    public void addChoiceElement(List<XMLField> srcFields, String elementTypeName, List<XMLField> tgtFields) {
        for(XMLField sourceField:srcFields) {
            this.fieldToClassNameMappings.put(sourceField, elementTypeName);
        }
        if (getClassNameToSourceFieldsMappings().get(elementTypeName) == null) {
            getClassNameToSourceFieldsMappings().put(elementTypeName, srcFields);
        }
        addChoiceElementMapping(srcFields, elementTypeName, tgtFields);
    }


    @Override
    public void addChoiceElement(XMLField field, String elementTypeName) {
        this.fieldToClassNameMappings.put(field, elementTypeName);
        if(this.classNameToFieldMappings.get(elementTypeName) == null) {
            this.classNameToFieldMappings.put(elementTypeName, field);
        }
        addChoiceElementMapping(field, elementTypeName);
    }

    @Override
    public Map<XMLField, Class<?>> getFieldToClassMappings() {
        return fieldToClassMappings;
    }

    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);

        if (this.converter != null) {
            this.converter.initialize(this, session);
        }
        ArrayList<XMLMapping> mappingsList = new ArrayList<>();
        mappingsList.addAll(getChoiceElementMappings().values());
        for(XMLMapping next:getChoiceElementMappingsByClass().values()) {
            if(!(mappingsList.contains(next))) {
                mappingsList.add(next);
            }
        }
        Iterator<XMLMapping> mappings = mappingsList.iterator();
        while(mappings.hasNext()){
            DatabaseMapping nextMapping = (DatabaseMapping)mappings.next();

            Converter converter = null;
            if(fieldsToConverters != null) {
                converter = fieldsToConverters.get(nextMapping.getField());
            }

            if(nextMapping.isAbstractDirectMapping()){
                ((XMLDirectMapping)nextMapping).setIsWriteOnly(this.isWriteOnly());
                if(converter != null){
                    ((AbstractDirectMapping)nextMapping).setConverter(converter);
                }

                 XMLConversionManager xmlConversionManager = (XMLConversionManager) session.getDatasourcePlatform().getConversionManager();
                 QName schemaType = xmlConversionManager.schemaType(nextMapping.getAttributeClassification());
                 if(schemaType != null && ((XMLField)nextMapping.getField()).getSchemaType() == null) {
                     ((XMLField)nextMapping.getField()).setSchemaType(schemaType);
                 }

            }else if(nextMapping instanceof XMLObjectReferenceMapping) {
                ((XMLObjectReferenceMapping)nextMapping).setIsWriteOnly(this.isWriteOnly);
            } else if(nextMapping instanceof XMLBinaryDataMapping) {
                ((XMLBinaryDataMapping)nextMapping).setIsCDATA(this.isWriteOnly);
                if(converter != null) {
                    ((XMLBinaryDataMapping)nextMapping).setConverter(converter);
                }
            } else {
                ((XMLCompositeObjectMapping)nextMapping).setIsWriteOnly(this.isWriteOnly());
                if(converter != null){
                    ((AbstractCompositeObjectMapping)nextMapping).setConverter(converter);
                }
            }

            nextMapping.initialize(session);
        }
    }

    @Override
    public Map<Class<?>, XMLField> getClassToFieldMappings() {
        return classToFieldMappings;
    }

    @Override
    public Map<XMLField, XMLMapping> getChoiceElementMappings() {
        return choiceElementMappings;
    }

    @Override
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        Iterator<Entry<XMLField, String>> entries = fieldToClassNameMappings.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<XMLField, String> entry = entries.next();
            String className = entry.getValue();
            Class<?> elementType = null;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        elementType = AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(className, exception.getException());
                    }
                } else {
                    elementType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, classLoader);
                }
            } catch (ClassNotFoundException exc) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(className, exc);
            }

            XMLMapping mapping = this.choiceElementMappings.get(entry.getKey());
            mapping.convertClassNamesToClasses(classLoader);

            if (fieldToClassMappings.get(entry.getKey()) == null) {
                fieldToClassMappings.put(entry.getKey(), elementType);
            }
        }
        for(Entry<String, XMLField> next: this.classNameToFieldMappings.entrySet()) {
            String className = next.getKey();
            Class<?> elementType = null;
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                    try {
                        elementType = AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, classLoader));
                    } catch (PrivilegedActionException exception) {
                        throw ValidationException.classNotFoundWhileConvertingClassNames(className, exception.getException());
                    }
                } else {
                    elementType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, classLoader);
                }
            } catch (ClassNotFoundException exc) {
                throw ValidationException.classNotFoundWhileConvertingClassNames(className, exc);
            }
            classToFieldMappings.put(elementType, next.getValue());

        }
        if(classNameToSourceFieldsMappings != null) {
            Iterator<Entry<String, List<XMLField>>> sourceFieldEntries = classNameToSourceFieldsMappings.entrySet().iterator();
            while(sourceFieldEntries.hasNext()) {
                Entry<String, List<XMLField>> nextEntry = sourceFieldEntries.next();
                String className = nextEntry.getKey();
                List<XMLField> fields = nextEntry.getValue();
                Class<?> elementType = null;
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        try {
                            elementType = AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, classLoader));
                        } catch (PrivilegedActionException exception) {
                            throw ValidationException.classNotFoundWhileConvertingClassNames(className, exception.getException());
                        }
                    } else {
                        elementType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, classLoader);
                    }
                } catch (ClassNotFoundException exc) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(className, exc);
                }
                this.getClassToSourceFieldsMappings().put(elementType,fields);
            }
        }
        if(classNameToConverter != null) {
            if(this.classToConverter == null) {
                this.classToConverter = new HashMap<>();
            }
            for(Entry<String, Converter> next: classNameToConverter.entrySet()) {
                String className = next.getKey();
                Class<?> elementType = null;
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        try {
                            elementType = AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, classLoader));
                        } catch (PrivilegedActionException exception) {
                            throw ValidationException.classNotFoundWhileConvertingClassNames(className, exception.getException());
                        }
                    } else {
                        elementType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, classLoader);
                    }
                } catch (ClassNotFoundException exc) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(className, exc);
                }
                this.classToConverter.put(elementType, next.getValue());
            }
        }
        if(!choiceElementMappingsByClassName.isEmpty()) {
            for(Entry<String, XMLMapping> next:choiceElementMappingsByClassName.entrySet()) {
                Class<?> elementType = null;
                String className = next.getKey();
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        try {
                            elementType = AccessController.doPrivileged(new PrivilegedClassForName<>(className, true, classLoader));
                        } catch (PrivilegedActionException exception) {
                            throw ValidationException.classNotFoundWhileConvertingClassNames(className, exception.getException());
                        }
                    } else {
                        elementType = org.eclipse.persistence.internal.security.PrivilegedAccessHelper.getClassForName(className, true, classLoader);
                    }
                } catch (ClassNotFoundException exc) {
                    throw ValidationException.classNotFoundWhileConvertingClassNames(className, exc);
                }
                if(this.choiceElementMappingsByClass.get(elementType) == null) {
                    this.choiceElementMappingsByClass.put(elementType, next.getValue());
                }
                next.getValue().convertClassNamesToClasses(classLoader);
            }
        }
    }

    @Override
    public void addConverter(XMLField field, Converter converter) {
        if(this.fieldsToConverters == null) {
            fieldsToConverters = new HashMap<>();
        }
        fieldsToConverters.put(field, converter);
    }

    @Override
    public Converter getConverter(XMLField field) {
        if(null != this.fieldsToConverters) {
            Converter converter = fieldsToConverters.get(field);
            if(null != converter) {
                return converter;
            }
            if(null != this.choiceElementMappings) {
                DatabaseMapping mapping = (DatabaseMapping) this.choiceElementMappings.get(field);
                if(null == mapping) {
                    return null;
                }
                if(mapping.isAbstractCompositeDirectCollectionMapping()) {
                    return ((XMLCompositeDirectCollectionMapping)mapping).getValueConverter();
                } else if(mapping.isAbstractDirectMapping()) {
                    return ((XMLDirectMapping)mapping).getConverter();
                }
            }
        }
        return null;
    }

    @Override
    public ArrayList getChoiceFieldToClassAssociations() {
        ArrayList associations = new ArrayList();
        if(this.fieldToClassNameMappings.size() > 0) {
            Set<Entry<XMLField, String>> entries = fieldToClassNameMappings.entrySet();
            Iterator<Entry<XMLField, String>> iter = entries.iterator();
            while(iter.hasNext()){
                Entry<XMLField, String> nextEntry = iter.next();
                XMLField xmlField = nextEntry.getKey();
                String className = nextEntry.getValue();
                XMLChoiceFieldToClassAssociation association = new XMLChoiceFieldToClassAssociation(xmlField, className);
                associations.add(association);
            }
        }
        return associations;
    }


    public void setChoiceFieldToClassAssociations(ArrayList associations) {
        if(associations.size() > 0) {
            for(Object next:associations) {
                XMLChoiceFieldToClassAssociation<Converter, XMLField> association = (XMLChoiceFieldToClassAssociation<Converter, XMLField>)next;
                this.addChoiceElement(association.getXmlField(), association.getClassName());
                if(association.getConverter() != null) {
                    this.addConverter(association.getXmlField(), association.getConverter());
                }
            }
        }
    }
    private void addChoiceElementMapping(XMLField xmlField, String className){
         if (xmlField.getLastXPathFragment().nameIsText() || xmlField.getLastXPathFragment().isAttribute()) {
             XMLDirectMapping xmlMapping = new XMLDirectMapping();
             xmlMapping.setAttributeAccessor(temporaryAccessor);
             xmlMapping.setAttributeClassificationName(className);
             xmlMapping.setField(xmlField);
             if(this.choiceElementMappings.get(xmlField) == null) {
                 this.choiceElementMappings.put(xmlField, xmlMapping);
             }
             if(this.choiceElementMappingsByClassName.get(className) == null) {
                 this.choiceElementMappingsByClassName.put(className, xmlMapping);
             }
         } else {
             if(isBinaryType(className)) {
                 XMLBinaryDataMapping xmlMapping = new XMLBinaryDataMapping();
                 xmlMapping.setField(xmlField);
                 Class<Object> theClass = XMLConversionManager.getDefaultXMLManager().convertClassNameToClass(className);
                 xmlMapping.setAttributeClassification(theClass);
                 xmlMapping.setAttributeAccessor(temporaryAccessor);
                 if(this.choiceElementMappings.get(xmlField) == null) {
                     this.choiceElementMappings.put(xmlField, xmlMapping);
                 }
                 if(this.choiceElementMappingsByClass.get(theClass) == null) {
                     this.choiceElementMappingsByClass.put(theClass, xmlMapping);
                 }
             } else {
                 XMLCompositeObjectMapping xmlMapping = new XMLCompositeObjectMapping();
                 xmlMapping.setAttributeAccessor(temporaryAccessor);
                 if(!className.equals("java.lang.Object")){
                     xmlMapping.setReferenceClassName(className);
                 }
                 xmlMapping.setField(xmlField);
                 if(this.choiceElementMappings.get(xmlField) == null) {
                     this.choiceElementMappings.put(xmlField, xmlMapping);
                 }
                 if(this.choiceElementMappingsByClassName.get(className) == null) {
                     this.choiceElementMappingsByClassName.put(className, xmlMapping);
                 }
             }
         }
    }

    private void addChoiceElementMapping(XMLField xmlField, Class<?> theClass){

        if (xmlField.getLastXPathFragment().nameIsText() || xmlField.getLastXPathFragment().isAttribute()) {
            XMLDirectMapping xmlMapping = new XMLDirectMapping();
            xmlMapping.setAttributeClassification(theClass);
            xmlMapping.setAttributeAccessor(temporaryAccessor);
            xmlMapping.setField(xmlField);
            this.choiceElementMappings.put(xmlField, xmlMapping);
            this.choiceElementMappingsByClass.put(theClass, xmlMapping);
        } else {
            if(isBinaryType(theClass)) {
                XMLBinaryDataMapping xmlMapping = new XMLBinaryDataMapping();
                xmlMapping.setField(xmlField);
                xmlMapping.setAttributeClassification(theClass);
                xmlMapping.setAttributeAccessor(temporaryAccessor);
                this.choiceElementMappings.put(xmlField, xmlMapping);
                this.choiceElementMappingsByClass.put(theClass, xmlMapping);
            } else {
                XMLCompositeObjectMapping xmlMapping = new XMLCompositeObjectMapping();
                xmlMapping.setAttributeAccessor(temporaryAccessor);
                if(!theClass.equals(ClassConstants.OBJECT)){
                    xmlMapping.setReferenceClass(theClass);
                }
                xmlMapping.setField(xmlField);
                this.choiceElementMappings.put(xmlField, xmlMapping);
                this.choiceElementMappingsByClass.put(theClass, xmlMapping);
            }
        }
    }

    private void addChoiceElementMapping(XMLField sourceField, Class<?> theClass, XMLField targetField) {
        XMLObjectReferenceMapping mapping = new XMLObjectReferenceMapping();
        mapping.setReferenceClass(theClass);
        mapping.setAttributeAccessor(temporaryAccessor);
        mapping.addSourceToTargetKeyFieldAssociation(sourceField, targetField);
        this.choiceElementMappings.put(sourceField, mapping);
        this.choiceElementMappingsByClass.put(theClass, mapping);
    }

    private void addChoiceElementMapping(XMLField sourceField, String className, XMLField targetField) {
        XMLObjectReferenceMapping mapping = new XMLObjectReferenceMapping();
        mapping.setReferenceClassName(className);
        mapping.setAttributeAccessor(temporaryAccessor);
        mapping.addSourceToTargetKeyFieldAssociation(sourceField, targetField);
        this.choiceElementMappings.put(sourceField, mapping);
        this.choiceElementMappingsByClassName.put(className, mapping);
    }

    private void addChoiceElementMapping(List<XMLField> sourceFields, Class<?> theClass, List<XMLField> targetFields) {
        XMLObjectReferenceMapping xmlMapping = new XMLObjectReferenceMapping();
        xmlMapping.setReferenceClass(theClass);
        xmlMapping.setAttributeAccessor(temporaryAccessor);
        for(int i = 0; i < sourceFields.size(); i++) {
            XMLField sourceField = sourceFields.get(i);
            xmlMapping.addSourceToTargetKeyFieldAssociation(sourceField, targetFields.get(i));
            this.choiceElementMappings.put(sourceField, xmlMapping);
        }
        this.choiceElementMappingsByClass.put(theClass, xmlMapping);
    }

    private void addChoiceElementMapping(List<XMLField> sourceFields, String theClass, List<XMLField> targetFields) {
        XMLObjectReferenceMapping xmlMapping = new XMLObjectReferenceMapping();
        xmlMapping.setReferenceClassName(theClass);
        xmlMapping.setAttributeAccessor(temporaryAccessor);
        for(int i = 0; i < sourceFields.size(); i++) {
            XMLField sourceField = sourceFields.get(i);
            xmlMapping.addSourceToTargetKeyFieldAssociation(sourceField, targetFields.get(i));
            this.choiceElementMappings.put(sourceField, xmlMapping);
        }
        this.choiceElementMappingsByClassName.put(theClass, xmlMapping);
    }

    @Override
    public boolean isWriteOnly() {
        return this.isWriteOnly;
    }

    @Override
    public void setIsWriteOnly(boolean b) {
        this.isWriteOnly = b;
    }

    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        getAttributeAccessor().setIsWriteOnly(this.isWriteOnly());
        getAttributeAccessor().setIsReadOnly(this.isReadOnly());
        super.preInitialize(session);
        ArrayList<XMLMapping> mappingsList = new ArrayList<>();
        mappingsList.addAll(getChoiceElementMappings().values());
        for(XMLMapping next:getChoiceElementMappingsByClass().values()) {
            if(!(mappingsList.contains(next))) {
                mappingsList.add(next);
            }
        }
        for(XMLMapping next:getChoiceElementMappingsByClass().values()) {
            if(!(mappingsList.contains(next))) {
                mappingsList.add(next);
            }
        }
        Iterator<XMLMapping> mappings = mappingsList.iterator();
        while(mappings.hasNext()){
            DatabaseMapping nextMapping = (DatabaseMapping)mappings.next();
            nextMapping.setDescriptor(getDescriptor());
            nextMapping.setAttributeName(this.getAttributeName());
            if(nextMapping.getAttributeAccessor() == temporaryAccessor){
                nextMapping.setAttributeAccessor(getAttributeAccessor());
            }
            nextMapping.preInitialize(session);
        }

    }

    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        if(isWriteOnly()) {
            return;
        }
        super.setAttributeValueInObject(object, value);
    }

    @Override
    public Map<Class<?>, List<XMLField>> getClassToSourceFieldsMappings() {
        if(this.classToSourceFieldsMappings == null) {
            this.classToSourceFieldsMappings = new HashMap<>();
        }
        return this.classToSourceFieldsMappings;
    }

    private Map<String, List<XMLField>> getClassNameToSourceFieldsMappings() {
        if(this.classNameToSourceFieldsMappings == null) {
            this.classNameToSourceFieldsMappings = new HashMap<>();
        }
        return this.classNameToSourceFieldsMappings;
    }

    private boolean isBinaryType(String className) {
        if(className.equals(byte[].class.getName()) || className.equals(Byte[].class.getName()) || className.equals(DATA_HANDLER)
                || className.equals(IMAGE) || className.equals(MIME_MULTIPART)) {
            return true;
        }
        return false;
    }

    private boolean isBinaryType(Class<?> theClass) {
        String className = theClass.getName();
        if(className.equals(byte[].class.getName()) || className.equals(Byte[].class.getName()) || className.equals(DATA_HANDLER)
                || className.equals(IMAGE) || className.equals(MIME_MULTIPART)) {
            return true;
        }
        return false;
    }

    @Override
    public Map<String, XMLField> getClassNameToFieldMappings() {
        return this.classNameToFieldMappings;
    }

    @Override
    public Map<Class<?>, XMLMapping> getChoiceElementMappingsByClass() {
        return choiceElementMappingsByClass;
    }

    public void setChoiceElementMappingsByClass(Map<Class<?>, XMLMapping> choiceElementMappingsByClass) {
        this.choiceElementMappingsByClass = choiceElementMappingsByClass;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertObjectValueToDataValue(Object value, Session session, XMLMarshaller marshaller) {
        if (null != converter) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertObjectValueToDataValue(value, session, marshaller);
            } else {
                return converter.convertObjectValueToDataValue(value, session);
            }
        }
        return value;
    }

    /**
     * INTERNAL
     * @since EclipseLink 2.5.0
     */
    @Override
    public Object convertDataValueToObjectValue(Object fieldValue, Session session, XMLUnmarshaller unmarshaller) {
        if (null != converter) {
            if (converter instanceof XMLConverter) {
                return ((XMLConverter)converter).convertDataValueToObjectValue(fieldValue, session, unmarshaller);
            } else {
                return converter.convertDataValueToObjectValue(fieldValue, session);
            }
        }
        return fieldValue;
    }

}
