/*******************************************************************************
 * Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/

package org.eclipse.persistence.internal.xr;

// Javase imports
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.sql.Blob;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Vector;
import java.util.List;
import org.w3c.dom.Element;

// Java extension imports
import javax.activation.DataHandler;
import javax.xml.namespace.QName;

// EclipseLink imports
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.DBWSException;
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.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 static org.eclipse.persistence.internal.helper.ClassConstants.STRING;
import static org.eclipse.persistence.internal.oxm.Constants.INT_QNAME;
import static org.eclipse.persistence.internal.xr.Util.DEFAULT_ATTACHMENT_MIMETYPE;
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.internal.xr.Util.sqlToXmlName;
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.oxm.XMLConstants.BASE_64_BINARY_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DATE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DATE_TIME_QNAME;
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.TIME_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.XMLNS_URL;

/**
 * <p><b>INTERNAL:</b>An XR QueryOperation is an executable representation of a <tt>SELECT</tt>
 * 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 ORACLESQLXML_STR = "oracle.jdbc.driver.OracleSQLXML";
    public static final String ORACLEOPAQUE_STR = "oracle.sql.OPAQUE";
    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);
        }
    }


    public class DataHandlerInstantiationPolicy extends InstantiationPolicy {
        protected 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(){
                    public void initializeDatabaseQuery(XRServiceAdapter xrService, QueryOperation queryOperation) {
                        // do nothing
                    }
                    public void initializeArguments(XRServiceAdapter xrService,
                        QueryOperation queryOperation, DatabaseQuery databaseQuery) {
                        // do nothing
                    }
                    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(
                        this.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;
                            InputStream is = null;
                            DataHandler dataHandler = (DataHandler)object;
                            try {
                                result = dataHandler.getContent();
                                if (result instanceof 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
                            } finally {
                                try {
                                    is.close();
                                } catch (IOException e) {
                                }
                            }
                            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 <tt>SELECT</tt> 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 <tt>SELECT</tt> operation on
     *          the database, or <code>null</code>.
     *
     * @see  {@link 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
        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()));
                query.addArgumentValue(invocation.getParameter(param.getName()));
            }
        } else {
            List<Object> argVals = new ArrayList<Object>();
            // need to set argument values
            for (Parameter param : getParameters()) {
                argVals.add(invocation.getParameter(param.getName()));
            }
            query.setArgumentValues(argVals);
        }
        // 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);

        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) value).add(1);
                } else  if (value instanceof Vector && ((Vector) value).isEmpty()) {
                    ((Vector) 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) 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 = ((XMLConversionManager) xrService.getOXSession().
                                    getDatasourcePlatform().getConversionManager()).
                                    convertObject((Blob) 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(), (AbstractRecord) 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<DatabaseField>();
            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<DatabaseRecord>();
            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>();
                DatabaseRecord dr = new DatabaseRecord();
                dr.add(new DatabaseField(RESULT_STR), ((Vector)value).firstElement());
                records.add(dr);
            }
        } else {
            records = new Vector<DatabaseRecord>();
            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();
        for (DatabaseRecord dr : records) {
            Element rowElement = TEMP_DOC.createElement(tempXMLTag);
            for (DatabaseField field : (Vector<DatabaseField>)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((Blob) fieldValue, ClassConstants.APBYTE);
                    } else if (fieldValue.getClass().getName().equalsIgnoreCase(ORACLESQLXML_STR)) {
                        // handle XMLType case where an oracle.jdbc.driver.OracleSQLXML instance was returned
                        try {
                            Class oracleSQLXML;
                            Method getStringMethod;
                            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                                oracleSQLXML = AccessController.doPrivileged(new PrivilegedClassForName(ORACLESQLXML_STR, true, this.getClass().getClassLoader()));
                                getStringMethod = AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(oracleSQLXML, GETSTRING_METHOD, new Class[] {}));
                                fieldValue = (String) AccessController.doPrivileged(new PrivilegedMethodInvoker(getStringMethod, fieldValue, new Object[] {}));
                            } else {
                                oracleSQLXML = PrivilegedAccessHelper.getClassForName(ORACLESQLXML_STR, true, this.getClass().getClassLoader());
                                getStringMethod = PrivilegedAccessHelper.getDeclaredMethod(oracleSQLXML, GETSTRING_METHOD, new Class[] {});
                                fieldValue = (String) PrivilegedAccessHelper.invokeMethod(getStringMethod, fieldValue, new Object[] {});
                            }
                        } catch (Exception x) {
                            // if the required resources are not available there's nothing we can do...
                        }
                    } 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(ORACLEOPAQUE_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 = (String) AccessController.doPrivileged(new PrivilegedMethodInvoker(getStringMethod, fieldValue, new Object[] {}));
                            } else {
                                oracleOPAQUE = PrivilegedAccessHelper.getClassForName(ORACLEOPAQUE_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 = (String) PrivilegedAccessHelper.invokeMethod(getStringMethod, xmlTypeFactory, new Object[] {fieldValue});
                            }
                        } catch (Exception x) {
                            // if the required resources are not available there's nothing we can do...
                        }
                    }
                    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;
    }
}
