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

// Javase imports
import static org.eclipse.persistence.internal.helper.ClassConstants.STRING;
import static org.eclipse.persistence.internal.oxm.Constants.BASE_64_BINARY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DATE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DATE_TIME_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.INT_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.TIME_QNAME;
import static org.eclipse.persistence.internal.xr.Util.DEFAULT_ATTACHMENT_MIMETYPE;
import static org.eclipse.persistence.internal.xr.Util.EMPTY_STR;
import static org.eclipse.persistence.internal.xr.Util.SLASH_CHAR;
import static org.eclipse.persistence.internal.xr.Util.SXF_QNAME;
import static org.eclipse.persistence.internal.xr.Util.TEMP_DOC;
import static org.eclipse.persistence.internal.xr.Util.sqlToXmlName;
import static org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat.DEFAULT_SIMPLE_XML_FORMAT_TAG;
import static org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat.DEFAULT_SIMPLE_XML_TAG;
import static org.eclipse.persistence.oxm.XMLConstants.SCHEMA_INSTANCE_URL;
import static org.eclipse.persistence.oxm.XMLConstants.SCHEMA_URL;
import static org.eclipse.persistence.oxm.XMLConstants.XMLNS_URL;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.Blob;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Vector;

// Java extension imports
import jakarta.activation.DataHandler;
import javax.xml.namespace.QName;

// EclipseLink imports
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DBWSException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.databaseaccess.OutputParameterForCallableStatement;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.jpa.JPAQuery;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.conversion.Base64;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredMethod;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat;
import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormatModel;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.XMLFragmentCollectionMapping;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaURLReference;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.sessions.DatabaseRecord;
import org.eclipse.persistence.sessions.Session;
import org.w3c.dom.Element;

/**
 * <p><b>INTERNAL:</b>An XR QueryOperation is an executable representation of a <code>SELECT</code>
 * operation on the database.
 *
 * @author Mike Norman - michael.norman@oracle.com
 * @since EclipseLink 1.x
 */
@SuppressWarnings({"serial", "unchecked"/*, "rawtypes"*/})
public class QueryOperation extends Operation {
    public static final String ORACLEOPAQUE_STR = "oracle.sql.OPAQUE";
    private static final String IORACLEOPAQUE_STR = "oracle.jdbc.OracleOpaque";
    protected static final String RESULT_STR = "result";
    protected static final String XMLTYPEFACTORY_STR = "org.eclipse.persistence.internal.platform.database.oracle.xdb.XMLTypeFactoryImpl";
    protected static final String GETSTRING_METHOD = "getString";
    protected static final String ATTACHMENT_STR = "/attachment";
    protected static final String CURSOR_OF_STR = "cursor of ";
    protected static final String DATAHANDLER_STR = "DataHandler";
    protected static final String RESULTS_STR = "results";
    protected static final String VALUEOBJECT_STR = "ValueObject";
    protected static final String VALUE_STR = "value";
    protected static final String SIMPLEXML_FORMAT_STR = "/simple-xml-format";
    protected static final String SIMPLEXML_STR = "simpleXML";
    protected static final String DATABASEQUERY_STR = "databasequery";
    protected static final String ITEMS_STR = "ITEMS";
    protected static final String XSD_STR = "xmlns:xsd";
    protected static final String XSI_STR = "xmlns:xsi";
    protected static final String XSITYPE_STR = "xsi:type";
    protected static final String BASE64_BINARY_STR = "xsd:base64Binary";

    protected Result result;
    protected QueryHandler queryHandler;
    protected boolean userDefined = true;

    public QueryOperation() {
        super();
    }

    public Result getResult() {
        return result;
    }
    public void setResult(Result result) {
        this.result = result;
    }

    public QueryHandler getQueryHandler() {
        return queryHandler;
    }
    public void setQueryHandler(QueryHandler queryHandler) {
        this.queryHandler = queryHandler;
    }

    public boolean isUserDefined() {
        return userDefined;
    }
    public void setUserDefined(boolean userDefined) {
        this.userDefined = userDefined;
    }

    @Override
    public boolean isCollection() {
        return result != null && result.isCollection();
    }

    public boolean isSimpleXMLFormat() {
        return result != null && result.getSimpleXMLFormat() != null;
    }

    public boolean isAttachment() {
        return result != null && result.getAttachment() != null;
    }

    public QName getResultType() {
        if (result != null) {
            return result.getType();
        }
        return null;
    }

    @Override
    public boolean hasResponse() {
        return result != null;
    }

    @Override
    public void validate(XRServiceAdapter xrService) {
        super.validate(xrService);
        QName resultType = result == null ? null : result.getType();
        if (resultType != null) {
            if (!resultType.getNamespaceURI().equals(SCHEMA_URL)) {
                boolean sxf = resultType.getLocalPart().equals(DEFAULT_SIMPLE_XML_FORMAT_TAG) ||
                    resultType.getLocalPart().equals(CURSOR_OF_STR + DEFAULT_SIMPLE_XML_FORMAT_TAG);
                // check descriptor for Schema's high-level element type 'resultType'
                if (!sxf && !xrService.descriptorsByQName.containsKey(resultType)) {
                        throw DBWSException.resultHasNoMapping(resultType.toString(), name);
                }
            }
        }
        if (queryHandler != null) {
            queryHandler.validate(xrService, this);
        }
    }

    // Made static final for performance reasons.
    private static final class DataHandlerInstantiationPolicy extends InstantiationPolicy {
        private String mimeType;
        public DataHandlerInstantiationPolicy(String mimeType) {
            super();
            this.mimeType = mimeType;
        }
        @Override
        public Object buildNewInstance() throws DescriptorException {
            return new DataHandler(null, mimeType);
        }
    }

    @Override
    public void initialize(XRServiceAdapter xrService) {
        super.initialize(xrService);
        if (queryHandler == null) {
            // session query instead of named query
            DatabaseQuery dq = xrService.getORSession().getQuery(name);
            if (dq != null) {
                queryHandler = new QueryHandler(){
                    @Override
                    public void initializeDatabaseQuery(XRServiceAdapter xrService, QueryOperation queryOperation) {
                        // do nothing
                    }
                    @Override
                    public void initializeArguments(XRServiceAdapter xrService,
                        QueryOperation queryOperation, DatabaseQuery databaseQuery) {
                        // do nothing
                    }
                    @Override
                    public void initializeCall(XRServiceAdapter xrService,
                        QueryOperation queryOperation, DatabaseQuery databaseQuery) {
                        // do nothing
                    }
                };
                queryHandler.setDatabaseQuery(dq);
            }
        }
        if (queryHandler == null) {
            throw DBWSException.couldNotLocateQueryForSession(name,
                xrService.getORSession().getName());
        }
        queryHandler.initialize(xrService, this);
        Session oxSession = xrService.getOXSession();
        QName resultType = result == null ? null : result.getType();
        addSimpleXMLFormatModelDescriptor(xrService);
        addValueObjectDescriptor(xrService);
        if (resultType == null) {
            if (isAttachment()) {
                Attachment attachment = result.getAttachment();
                XMLDescriptor descriptor =
                    (XMLDescriptor)oxSession.getProject().getClassDescriptor(DataHandler.class);
                if (descriptor == null) {
                    descriptor = new XMLDescriptor();
                    descriptor.setAlias(DATAHANDLER_STR);
                    descriptor.setJavaClass(DataHandler.class);
                    descriptor.setInstantiationPolicy(new DataHandlerInstantiationPolicy(attachment.getMimeType()));
                    XMLBinaryDataMapping mapping = new XMLBinaryDataMapping();
                    mapping.setAttributeName(RESULTS_STR);
                    mapping.setAttributeAccessor(new AttributeAccessor() {
                        @Override
                        public Object getAttributeValueFromObject(Object object)
                            throws DescriptorException {
                            Object result = null;
                            DataHandler dataHandler = (DataHandler)object;
                            try {
                                result = dataHandler.getContent();
                                if (result instanceof InputStream) {
                                    try (InputStream is = (InputStream) result) {
                                        byte[] buf = new byte[2048];
                                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                        int bytesRead = is.read(buf);
                                        while (bytesRead >= 0) {
                                            baos.write(buf, 0, bytesRead);
                                            bytesRead = is.read(buf);
                                        }
                                        result = baos.toByteArray();
                                    }
                                }
                            } catch (IOException e) {
                                // ignore
                            }
                            return result;
                        }
                        @Override
                        public void setAttributeValueInObject(Object object, Object value)
                            throws DescriptorException {
                        }
                    });
                    mapping.setXPath(DEFAULT_SIMPLE_XML_FORMAT_TAG + SLASH_CHAR +
                        DEFAULT_SIMPLE_XML_TAG + ATTACHMENT_STR);
                    mapping.setSwaRef(true);
                    mapping.setShouldInlineBinaryData(false);
                    mapping.setMimeType(attachment.getMimeType());
                    descriptor.addMapping(mapping);
                    NamespaceResolver nr = new NamespaceResolver();
                    descriptor.setNamespaceResolver(nr);
                    oxSession.getProject().addDescriptor(descriptor);
                    ((DatabaseSessionImpl)oxSession)
                        .initializeDescriptorIfSessionAlive(descriptor);
                    xrService.getXMLContext().storeXMLDescriptorByQName(descriptor);
                }
            }
        }
    }

    protected void addValueObjectDescriptor(XRServiceAdapter xrService) {
        Session oxSession = xrService.getOXSession();
        XMLDescriptor descriptor = (XMLDescriptor)oxSession.getProject().getClassDescriptor(
            ValueObject.class);
        if (descriptor == null) {
            descriptor = new XMLDescriptor();
            descriptor.setAlias(VALUEOBJECT_STR);
            descriptor.setJavaClass(ValueObject.class);
            XMLDirectMapping mapping = new XMLDirectMapping();
            mapping.setAttributeName(VALUE_STR);
            mapping.setXPath(VALUE_STR);
            descriptor.addMapping(mapping);
            NamespaceResolver nr = new NamespaceResolver();
            descriptor.setNamespaceResolver(nr);
            oxSession.getProject().addDescriptor(descriptor);
            ((DatabaseSessionImpl)oxSession)
                .initializeDescriptorIfSessionAlive(descriptor);
            xrService.getXMLContext().storeXMLDescriptorByQName(descriptor);
        }
    }

    protected void addSimpleXMLFormatModelDescriptor(XRServiceAdapter xrService) {
        if (isSimpleXMLFormat()) {
            Session oxSession = xrService.getOXSession();
            XMLDescriptor simpleXMLFormatDescriptor = (XMLDescriptor)oxSession.
                getProject().getClassDescriptor(SimpleXMLFormatModel.class);
            if (simpleXMLFormatDescriptor == null) {
                simpleXMLFormatDescriptor = new XMLDescriptor();
                simpleXMLFormatDescriptor.setJavaClass(SimpleXMLFormatModel.class);
                simpleXMLFormatDescriptor.setAlias(DEFAULT_SIMPLE_XML_FORMAT_TAG);
                simpleXMLFormatDescriptor.setDefaultRootElement(DEFAULT_SIMPLE_XML_FORMAT_TAG);
                XMLFragmentCollectionMapping xmlTag = new XMLFragmentCollectionMapping();
                xmlTag.setAttributeName(SIMPLEXML_STR);
                xmlTag.setXPath(DEFAULT_SIMPLE_XML_TAG);
                simpleXMLFormatDescriptor.addMapping(xmlTag);
                NamespaceResolver nr = new NamespaceResolver();
                simpleXMLFormatDescriptor.setNamespaceResolver(nr);
                XMLSchemaURLReference schemaReference = new XMLSchemaURLReference(EMPTY_STR);
                schemaReference.setSchemaContext(SIMPLEXML_FORMAT_STR);
                schemaReference.setType(XMLSchemaReference.COMPLEX_TYPE);
                simpleXMLFormatDescriptor.setSchemaReference(schemaReference);
                oxSession.getProject().addDescriptor(simpleXMLFormatDescriptor);
                ((DatabaseSessionImpl)oxSession)
                    .initializeDescriptorIfSessionAlive(simpleXMLFormatDescriptor);
                xrService.getXMLContext().storeXMLDescriptorByQName(simpleXMLFormatDescriptor);
            }
        }
    }

    /**
     * Execute <code>SELECT</code> operation on the database
     * @param   xrService parent <code>XRService</code> that owns this <code>Operation</code>
     * @param   invocation contains runtime argument values to be bound to the list of
     *          {@link Parameter}'s.
     * @return  result - the result of the underlying <code>SELECT</code> operation on
     *          the database, or <code>null</code>.
     *
     * @see  Operation
     */
    @Override
    public Object invoke(XRServiceAdapter xrService, Invocation invocation) {
        DatabaseQuery query = queryHandler.getDatabaseQuery();

        if (query.getProperty(DATABASEQUERY_STR) != null) {
            query = (DatabaseQuery) query.getProperty(DATABASEQUERY_STR);
        }

        // a named query created via ORM metadata processing does not have
        // parameters set, however, the operation should
        List<Object> argVals = new ArrayList<>();
        if (query.getArguments().size() == 0) {
            int idx = 0;
            for (Parameter param : getParameters()) {
                // for custom SQL query (as configured via ORM metadata
                // processing) we add args by position
                query.addArgument(Integer.toString(++idx), Util.SCHEMA_2_CLASS.get(param.getType()));
                argVals.add(invocation.getParameter(param.getName()));
            }
        } else {
            // need to set argument values
            for (Parameter param : getParameters()) {
                argVals.add(invocation.getParameter(param.getName()));
            }
        }
        // for SimpleXML + DataReadQuery we need to set MAP result type
        if (isSimpleXMLFormat() && query.isDataReadQuery()) {
            ((DataReadQuery) query).setResultType(DataReadQuery.MAP);
        }

        // now execute the query
        Object value = xrService.getORSession().getActiveSession().executeQuery(query, argVals);

        if (value != null) {
            // a recent change in core results in an empty vector being returned in cases
            // where before we'd expect an int value (typically 1) - need to handle this
            if (result != null && (result.getType() == INT_QNAME || result.getType().equals(SXF_QNAME))) {
                if (value instanceof ArrayList && ((ArrayList<?>) value).isEmpty()) {
                    ((ArrayList<Integer>) value).add(1);
                } else  if (value instanceof Vector && ((Vector<?>) value).isEmpty()) {
                    ((Vector<Integer>) value).add(1);
                }
            }

            // JPA spec returns an ArrayList<Object[]> for stored procedure queries - will need to unwrap.
            // Note that for legacy deployment XML projects this is not the case.
            if (value instanceof ArrayList) {
                ArrayList<?> returnedList = (ArrayList<?>) value;
                if (returnedList.size() > 0 && returnedList.get(0) instanceof Object[]) {
                    Object[] objs = (Object[]) returnedList.get(0);
                    if (isCollection()) {
                        value = new ArrayList<>();
                        for (Object obj : objs) {
                            ((ArrayList<Object>) value).add(obj);
                        }
                    } else {
                        value = objs[0];
                    }
                }
            }

            // handle SimpleXML
            if (isSimpleXMLFormat()) {
                value = createSimpleXMLFormat(xrService, value);
            } else {
                if (!isCollection() && value instanceof Vector) {
                    // JPAQuery will return a single result in a Vector
                    if (((Vector<?>) value).isEmpty()) {
                        return null;
                    }
                    value = ((Vector<?>) value).firstElement();
                }

                QName resultType = getResultType();
                if (resultType != null) {
                    // handle binary content
                    if (isAttachment() || (!isCollection() && resultType.equals(BASE_64_BINARY_QNAME))) {
                        String mimeType = DEFAULT_ATTACHMENT_MIMETYPE;
                        if (isAttachment() && result.getAttachment().getMimeType() != null) {
                            mimeType = result.getAttachment().getMimeType();
                        }
                        // handle BLOB types
                        if (value instanceof Blob) {
                            value = xrService.getOXSession().
                                    getDatasourcePlatform().getConversionManager().
                                    convertObject(value, ClassConstants.APBYTE);
                        }
                        return AttachmentHelper.buildAttachmentHandler((byte[])value, mimeType);
                    }
                    if (resultType.getNamespaceURI().equals(SCHEMA_URL)) {
                        // handle primitive types
                        ValueObject vo = new ValueObject();
                        vo.value = value;
                        value = vo;
                    } else {
                        Object targetObject = value;
                        if (xrService.descriptorsByQName.containsKey(resultType)) {
                            XMLDescriptor xdesc = xrService.descriptorsByQName.get(resultType);
                            ClassDescriptor desc = xrService.getORSession().getDescriptorForAlias(xdesc.getAlias());
                            if (desc.isAggregateDescriptor() && !desc.isObjectRelationalDataTypeDescriptor() && !desc.isRelationalDescriptor()) {
                                if (isCollection()) {
                                    XRDynamicEntity_CollectionWrapper xrCollWrapper = new XRDynamicEntity_CollectionWrapper();
                                    Vector<AbstractRecord> results = (Vector<AbstractRecord>)value;
                                    for (int i = 0, len = results.size(); i < len; i++) {
                                        Object o = desc.getObjectBuilder().buildNewInstance();
                                        populateTargetObjectFromRecord(desc.getMappings(), results.get(i), o, (AbstractSession)xrService.getORSession());
                                        xrCollWrapper.add(o);
                                    }
                                    targetObject = xrCollWrapper;
                                } else {
                                    targetObject = desc.getObjectBuilder().buildNewInstance();
                                    populateTargetObjectFromRecord(desc.getMappings(), (AbstractRecord) value, targetObject, (AbstractSession)xrService.getORSession());
                                }
                            } else if (isCollection() && value instanceof Vector) {
                                // could be a collection of populated objects, in which case we just return it
                                if (((Vector<?>) value).size() > 0 && !(((Vector<?>) value).get(0) instanceof AbstractRecord)) {
                                    return value;
                                }
                                XRDynamicEntity_CollectionWrapper xrCollWrapper = new XRDynamicEntity_CollectionWrapper();
                                Vector<AbstractRecord> results = (Vector<AbstractRecord>)value;
                                for (int i = 0, len = results.size(); i < len; i++) {
                                    Object o = desc.getObjectBuilder().buildNewInstance();
                                    populateTargetObjectFromRecord(desc.getMappings(), results.get(i), o, (AbstractSession)xrService.getORSession());
                                    xrCollWrapper.add(o);
                                }
                                targetObject = xrCollWrapper;
                            } else if (value instanceof AbstractRecord) {
                                targetObject = desc.getObjectBuilder().buildNewInstance();
                                populateTargetObjectFromRecord(desc.getMappings(), (AbstractRecord) value, targetObject, (AbstractSession)xrService.getORSession());
                            }
                        }
                        if (value instanceof ArrayList) {
                            XMLDescriptor xdesc = xrService.descriptorsByQName.get(resultType);
                            ClassDescriptor desc = xrService.getORSession().getDescriptorForAlias(xdesc.getAlias());
                            targetObject = desc.getObjectBuilder().buildNewInstance();
                            Object[] objs = new Object[1];
                            objs[0] = ((ArrayList<?>)value).get(0);
                            DatabaseRecord dr = new DatabaseRecord();
                            dr.add(new DatabaseField(ITEMS_STR), objs);
                            populateTargetObjectFromRecord(desc.getMappings(), dr, targetObject, (AbstractSession)xrService.getORSession());
                        }
                        value = targetObject;
                    }
                }
            }
        }
        return value;
    }

    protected void populateTargetObjectFromRecord(Vector<DatabaseMapping> mappings,
        AbstractRecord record, Object targetObject, AbstractSession session) {
        ReadObjectQuery roq = new ReadObjectQuery();
        roq.setSession(session);
        for (DatabaseMapping dm : mappings) {
            dm.readFromRowIntoObject(record, null, targetObject, null, roq, session, true);
        }
    }

    public Object createSimpleXMLFormat(XRServiceAdapter xrService, Object value) {
        XMLRoot xmlRoot = new XMLRoot();
        SimpleXMLFormat simpleXMLFormat = result.getSimpleXMLFormat();
        String tempSimpleXMLFormatTag = SimpleXMLFormat.DEFAULT_SIMPLE_XML_FORMAT_TAG;
        String simpleXMLFormatTag = simpleXMLFormat.getSimpleXMLFormatTag();
        if (simpleXMLFormatTag != null && !EMPTY_STR.equals(simpleXMLFormatTag)) {
            tempSimpleXMLFormatTag = simpleXMLFormatTag;
        }
        xmlRoot.setLocalName(tempSimpleXMLFormatTag);
        String tempXMLTag = DEFAULT_SIMPLE_XML_TAG;
        String xmlTag = simpleXMLFormat.getXMLTag();
        if (xmlTag != null && !EMPTY_STR.equals(xmlTag)) {
            tempXMLTag = xmlTag;
        }
        Vector<DatabaseRecord> records = null;
        if (value instanceof ArrayList) {
            // JPA query results in a list of raw values
            // Here we have raw values returned as opposed to DatabaseRecords - this means
            // we need to figure out the tag names based on the call's output parameters.
            // assumes JPAQuery
            JPAQuery jpaQuery = (JPAQuery) queryHandler.getDatabaseQuery();
            // to match field names with results, we need to gather the database fields from each of the Output parameters
            List<DatabaseField> paramFlds = new ArrayList<>();
            DatasourceCall dsCall = (DatasourceCall) jpaQuery.getDatabaseQuery().getDatasourceCall();
            for (Object obj : dsCall.getParameters()) {
                if (obj instanceof OutputParameterForCallableStatement) {
                    paramFlds.add(((OutputParameterForCallableStatement) obj).getOutputField());
                } else if (obj instanceof Object[]) {
                    Object[] objArray = (Object[]) obj;
                    for (int i = 0; i < objArray.length; i++) {
                        Object o = objArray[i];
                        if (o instanceof OutputParameterForCallableStatement) {
                            paramFlds.add(((OutputParameterForCallableStatement) o).getOutputField());
                        }
                    }
                }
            }
            // now create a record using DatabaseField/value pairs
            DatabaseRecord dr = new DatabaseRecord();
            if (paramFlds.size() > 0) {
                for (int i=0; i <  ((ArrayList<?>) value).size(); i++) {
                    dr.add(paramFlds.get(i), ((ArrayList<?>) value).get(i));
                }
            } else {
                dr.add(new DatabaseField(RESULT_STR), ((ArrayList<?>) value).get(0));
            }
            records = new Vector<>();
            records.add(dr);
        } else if (value instanceof Vector) {
            Class<?> vectorContent = ((Vector<?>)value).firstElement().getClass();
            if (DatabaseRecord.class.isAssignableFrom(vectorContent)) {
                records = (Vector<DatabaseRecord>)value;
            } else {
                records = new Vector<>();
                DatabaseRecord dr = new DatabaseRecord();
                dr.add(new DatabaseField(RESULT_STR), ((Vector<?>)value).firstElement());
                records.add(dr);
            }
        } else {
            records = new Vector<>();
            DatabaseRecord dr = new DatabaseRecord();
            dr.add(new DatabaseField(RESULT_STR), value);
            records.add(dr);
        }
        SimpleXMLFormatModel simpleXMLFormatModel = new SimpleXMLFormatModel();
        XMLConversionManager conversionManager =
            (XMLConversionManager) xrService.getOXSession().getDatasourcePlatform().getConversionManager();
        SessionLog log = xrService.getOXSession().getSessionLog();
        for (DatabaseRecord dr : records) {
            Element rowElement = TEMP_DOC.createElement(tempXMLTag);
            for (DatabaseField field : dr.getFields()) {
                // handle complex types, i.e. ones we have a descriptor for
                if (field instanceof ObjectRelationalDatabaseField) {
                    ObjectRelationalDatabaseField ordtField = (ObjectRelationalDatabaseField) field;
                    if (xrService.getOXSession().getDescriptor(ordtField.getType()) != null) {
                        xrService.getXMLContext().createMarshaller().marshal(dr.get(field), rowElement);
                        continue;
                    }
                }
                Object fieldValue = dr.get(field);
                if (fieldValue != null) {
                    if (fieldValue instanceof Calendar) {
                        Calendar cValue = (Calendar)fieldValue;
                        fieldValue = conversionManager.convertObject(cValue, STRING, DATE_TIME_QNAME);
                    }
                    if (fieldValue instanceof Date) {
                        Date dValue = (Date)fieldValue;
                        fieldValue = conversionManager.convertObject(dValue, STRING, DATE_QNAME);
                    } else if (fieldValue instanceof Time) {
                        Time tValue = (Time)fieldValue;
                        fieldValue = conversionManager.convertObject(tValue, STRING, TIME_QNAME);
                    } else if (fieldValue instanceof Timestamp) {
                        Timestamp tsValue = (Timestamp)fieldValue;
                        fieldValue = conversionManager.convertObject(tsValue, STRING, DATE_TIME_QNAME);
                    } else if (fieldValue instanceof Blob) {
                        fieldValue = conversionManager.convertObject(fieldValue, ClassConstants.APBYTE);
                    } else if (SQLXML.class.isAssignableFrom(fieldValue.getClass())) {
                        // handle XMLType case where an oracle.jdbc.driver.OracleSQLXML instance was returned
                        SQLXML sqlXml = (SQLXML) fieldValue;
                        try {
                            String str = sqlXml.getString();
                            sqlXml.free();
                            // Oracle 12c appends a \n character to the xml string
                            fieldValue = str.endsWith("\n") ? str.substring(0, str.length() - 1) : str;
                        } catch (SQLException e) {
                            log.logThrowable(SessionLog.FINE, SessionLog.DBWS, e);
                        }
                    } else if (fieldValue.getClass().getName().equalsIgnoreCase(ORACLEOPAQUE_STR)) {
                        // handle XMLType case where an oracle.sql.OPAQUE instance was returned
                        try {
                            Class<?> oracleOPAQUE;
                            Class<?> xmlTypeFactoryClass;
                            Constructor<?> xmlTypeFactoryConstructor;
                            Object xmlTypeFactory;
                            Method getStringMethod;
                            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                                oracleOPAQUE = AccessController.doPrivileged(new PrivilegedClassForName<>(IORACLEOPAQUE_STR, true, this.getClass().getClassLoader()));
                                xmlTypeFactoryClass = AccessController.doPrivileged(new PrivilegedClassForName<>(XMLTYPEFACTORY_STR, true, this.getClass().getClassLoader()));
                                xmlTypeFactoryConstructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<>(xmlTypeFactoryClass, new Class[0], true));
                                xmlTypeFactory = AccessController.doPrivileged(new PrivilegedInvokeConstructor<>(xmlTypeFactoryConstructor, new Object[0]));
                                getStringMethod = AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(xmlTypeFactoryClass, GETSTRING_METHOD, new Class[] {oracleOPAQUE}));
                                fieldValue = AccessController.doPrivileged(new PrivilegedMethodInvoker<>(getStringMethod, fieldValue, new Object[] {}));
                            } else {
                                oracleOPAQUE = PrivilegedAccessHelper.getClassForName(IORACLEOPAQUE_STR, false, this.getClass().getClassLoader());
                                xmlTypeFactoryClass = PrivilegedAccessHelper.getClassForName(XMLTYPEFACTORY_STR, true, this.getClass().getClassLoader());
                                xmlTypeFactoryConstructor = PrivilegedAccessHelper.getConstructorFor(xmlTypeFactoryClass, new Class[0], true);
                                xmlTypeFactory = PrivilegedAccessHelper.invokeConstructor(xmlTypeFactoryConstructor, new Object[0]);
                                getStringMethod = PrivilegedAccessHelper.getDeclaredMethod(xmlTypeFactoryClass, GETSTRING_METHOD, new Class[] {oracleOPAQUE});
                                fieldValue = PrivilegedAccessHelper.invokeMethod(getStringMethod, xmlTypeFactory, new Object[] {fieldValue});
                            }
                        } catch (ReflectiveOperationException | PrivilegedActionException e) {
                            // if the required resources are not available there's nothing we can do...
                            log.logThrowable(SessionLog.FINE, SessionLog.DBWS, e);
                        }
                    }

                    String elementName;
                    if (field.getName() == null || (elementName = sqlToXmlName(field.getName())).equals(EMPTY_STR)) {
                        // return arg from stored function has no name
                       elementName = RESULT_STR;
                    }
                    Element columnElement = TEMP_DOC.createElement(elementName);
                    rowElement.appendChild(columnElement);
                    String fieldValueString = fieldValue.toString();
                    // handle binary content - attachments dealt with in invoke() above
                    if (result.getType().equals(BASE_64_BINARY_QNAME)) {
                        fieldValueString = Helper.buildHexStringFromBytes(Base64.base64Encode((byte[])fieldValue));
                        columnElement.setAttributeNS(XMLNS_URL, XSD_STR, SCHEMA_URL);
                        columnElement.setAttributeNS(XMLNS_URL, XSI_STR, SCHEMA_INSTANCE_URL);
                        columnElement.setAttributeNS(SCHEMA_INSTANCE_URL, XSITYPE_STR, BASE64_BINARY_STR);
                    }
                    columnElement.appendChild(TEMP_DOC.createTextNode(fieldValueString));
                }
            }
            simpleXMLFormatModel.simpleXML.add(rowElement);
        }
        xmlRoot.setObject(simpleXMLFormatModel);
        return xmlRoot;
    }
}
