/*
 * 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:
//     Mike Norman - from Proof-of-concept, become production code
package org.eclipse.persistence.tools.dbws.oracle;

import static java.sql.Types.ARRAY;
import static java.sql.Types.OTHER;
import static java.sql.Types.STRUCT;
import static java.util.logging.Level.FINEST;
// EclipseLink imports
import static org.eclipse.persistence.internal.helper.ClassConstants.Object_Class;
import static org.eclipse.persistence.internal.oxm.Constants.ANY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.COLON;
import static org.eclipse.persistence.internal.oxm.Constants.DATE_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.DOT;
import static org.eclipse.persistence.internal.oxm.Constants.EMPTY_STRING;
import static org.eclipse.persistence.internal.oxm.Constants.INT;
import static org.eclipse.persistence.internal.oxm.Constants.SCHEMA_INSTANCE_PREFIX;
import static org.eclipse.persistence.internal.oxm.Constants.SCHEMA_PREFIX;
import static org.eclipse.persistence.internal.oxm.Constants.TEXT;
import static org.eclipse.persistence.internal.xr.Util.SXF_QNAME;
import static org.eclipse.persistence.internal.xr.Util.getClassFromJDBCType;
import static org.eclipse.persistence.internal.xr.Util.getJDBCTypeForTypeName;
import static org.eclipse.persistence.internal.xr.XRDynamicClassLoader.COLLECTION_WRAPPER_SUFFIX;
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.mappings.nullpolicy.XMLNullRepresentationType.XSI_NIL;
import static org.eclipse.persistence.tools.dbws.Util.APP_OCTET_STREAM;
import static org.eclipse.persistence.tools.dbws.Util.AT_SIGN;
import static org.eclipse.persistence.tools.dbws.Util.BUILDING_QUERYOP_FOR;
import static org.eclipse.persistence.tools.dbws.Util.CLOSE_PAREN;
import static org.eclipse.persistence.tools.dbws.Util.CURSOR_OF_STR;
import static org.eclipse.persistence.tools.dbws.Util.CURSOR_STR;
import static org.eclipse.persistence.tools.dbws.Util.OPEN_PAREN;
import static org.eclipse.persistence.tools.dbws.Util.PERCENT;
import static org.eclipse.persistence.tools.dbws.Util.SLASH;
import static org.eclipse.persistence.tools.dbws.Util.SXF_QNAME_CURSOR;
import static org.eclipse.persistence.tools.dbws.Util.TOPLEVEL;
import static org.eclipse.persistence.tools.dbws.Util.TYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.UNDERSCORE;
import static org.eclipse.persistence.tools.dbws.Util.XMLTYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.buildCustomQName;
import static org.eclipse.persistence.tools.dbws.Util.getAttributeClassForDatabaseType;
import static org.eclipse.persistence.tools.dbws.Util.getGeneratedAlias;
import static org.eclipse.persistence.tools.dbws.Util.getGeneratedJavaClassName;
import static org.eclipse.persistence.tools.dbws.Util.getXMLTypeFromJDBCType;
import static org.eclipse.persistence.tools.dbws.Util.hasComplexArgs;
import static org.eclipse.persistence.tools.dbws.Util.hasPLSQLCursorArg;
import static org.eclipse.persistence.tools.dbws.Util.qNameFromString;
import static org.eclipse.persistence.tools.dbws.Util.shouldSetJavaType;
import static org.eclipse.persistence.tools.dbws.Util.sqlMatch;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.IN;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.INOUT;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.OUT;

import java.sql.Array;
import java.sql.Struct;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Level;

import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.ComplexDatabaseType;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.StringHelper;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.xr.Attachment;
import org.eclipse.persistence.internal.xr.CollectionResult;
import org.eclipse.persistence.internal.xr.NamedQueryHandler;
import org.eclipse.persistence.internal.xr.Parameter;
import org.eclipse.persistence.internal.xr.ProcedureArgument;
import org.eclipse.persistence.internal.xr.ProcedureOutputArgument;
import org.eclipse.persistence.internal.xr.QueryHandler;
import org.eclipse.persistence.internal.xr.QueryOperation;
import org.eclipse.persistence.internal.xr.Result;
import org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler;
import org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.mappings.structures.ArrayMapping;
import org.eclipse.persistence.mappings.structures.ObjectArrayMapping;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDataTypeDescriptor;
import org.eclipse.persistence.mappings.structures.ObjectRelationalDatabaseField;
import org.eclipse.persistence.mappings.structures.StructureMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.schema.XMLSchemaURLReference;
import org.eclipse.persistence.platform.database.jdbc.JDBCTypes;
import org.eclipse.persistence.platform.database.oracle.jdbc.OracleObjectType;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLCollection;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredFunctionCall;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLStoredProcedureCall;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLargument;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLrecord;
import org.eclipse.persistence.queries.DataReadQuery;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.StoredFunctionCall;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.queries.ValueReadQuery;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.tools.dbws.BaseDBWSBuilderHelper;
import org.eclipse.persistence.tools.dbws.DBWSBuilder;
import org.eclipse.persistence.tools.dbws.DBWSBuilderHelper;
import org.eclipse.persistence.tools.dbws.NamingConventionTransformer.ElementStyle;
import org.eclipse.persistence.tools.dbws.ProcedureOperationModel;
import org.eclipse.persistence.tools.dbws.Util;
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType;
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
import org.eclipse.persistence.tools.oracleddl.metadata.FunctionType;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectTableType;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLRecordType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;
import org.eclipse.persistence.tools.oracleddl.metadata.ROWTYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum;
import org.eclipse.persistence.tools.oracleddl.metadata.TYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType;
import org.eclipse.persistence.tools.oracleddl.metadata.visit.BaseDatabaseTypeVisitor;
import org.eclipse.persistence.tools.oracleddl.metadata.visit.DatabaseTypeVisitor;
import org.eclipse.persistence.tools.oracleddl.parser.ParseException;
import org.eclipse.persistence.tools.oracleddl.util.DatabaseTypeBuilder;

public class OracleHelper extends BaseDBWSBuilderHelper implements DBWSBuilderHelper {

    protected DatabaseTypeBuilder dtBuilder = new DatabaseTypeBuilder();
    public static final String NO_PKG_MSG = "No packages were found matching the following: ";

    public OracleHelper(DBWSBuilder dbwsBuilder) {
        super(dbwsBuilder);
    }

    /**
     * Indicates if this helper instance contains one or more
     * TableType instances in TableType List "dbTables".
     */
    @Override
    public boolean hasTables() {
        return dbTables.size() == 0 ? false : true;
    }

    @Override
    public void buildDbArtifacts() {
        super.buildDbArtifacts();
        //list of all directly-referenced packages
        Set<PLSQLPackageType> directPackages = new HashSet<PLSQLPackageType>();
        for (ProcedureType procedureType : dbStoredProcedures) {
            for (ArgumentType argumentType : procedureType.getArguments()) {
                DatabaseType argumentDataType = argumentType.getEnclosedType();
                if (argumentDataType.isPLSQLType()) {
                    PLSQLType plsqlType = (PLSQLType)argumentDataType;
                    directPackages.add(plsqlType.getParentType());
                }
            }
        }
        //any indirectly-referenced packages?
        final Set<PLSQLPackageType> indirectPackages = new HashSet<PLSQLPackageType>();
        DatabaseTypeVisitor indirectVisitor = new BaseDatabaseTypeVisitor() {
            @Override
            public void beginVisit(PLSQLPackageType databaseType) {
                indirectPackages.add(databaseType);
            }
        };
        for (PLSQLPackageType pckage : directPackages) {
            pckage.accept(indirectVisitor);
        }
        Set<PLSQLPackageType> packages = new HashSet<PLSQLPackageType>();
        packages.addAll(directPackages);
        packages.addAll(indirectPackages);
        for (PLSQLPackageType pckage : packages) {
            ShadowDDLGenerator ddlGenerator = new ShadowDDLGenerator(pckage);
            dbwsBuilder.getTypeDDL().addAll(ddlGenerator.getAllCreateDDLs());
            dbwsBuilder.getTypeDropDDL().addAll(ddlGenerator.getAllDropDDLs());
        }
    }

    /**
     * Builds query operations for a given ProcedureOperationModel.
     */
    @Override
    public void buildProcedureOperation(ProcedureOperationModel procedureOperationModel) {
        for (ProcedureType storedProcedure : procedureOperationModel.getDbStoredProcedures()) {
            boolean hasComplexArgs = hasComplexArgs(storedProcedure);
            QueryOperation qo = new QueryOperation();
            qo.setName(getNameForQueryOperation(procedureOperationModel, storedProcedure));

            String qualifiedProcName = getQualifiedProcedureName(procedureOperationModel, storedProcedure);
            dbwsBuilder.logMessage(FINEST, BUILDING_QUERYOP_FOR + qualifiedProcName);

            QueryHandler qh = null;
            // before assigning queryHandler, check for named query in OR project
            List<DatabaseQuery> queries = dbwsBuilder.getOrProject().getQueries();
            if (queries.size() > 0) {
                for (DatabaseQuery q : queries) {
                    if (q.getName().equals(qo.getName())) {
                        qh = new NamedQueryHandler();
                        ((NamedQueryHandler) qh).setName(qo.getName());
                    }
                }
            }
            if (qh == null) {
                if (storedProcedure.isFunctionType()) {
                    qh = new StoredFunctionQueryHandler();
                } else {
                    qh = new StoredProcedureQueryHandler();
                }
                ((StoredProcedureQueryHandler) qh).setName(qualifiedProcName);
            }
            qo.setQueryHandler(qh);

            String returnType = procedureOperationModel.getReturnType();
            boolean isCollection = procedureOperationModel.isCollection();
            boolean isSimpleXMLFormat = procedureOperationModel.isSimpleXMLFormat();
            Result result = null;

            /**
             * For multiple OUT args as well as a stored function with OUT args, we want
             * the result to be a collection and the type to be "xsd:any".  We will
             * force SimpleXMLFormat for now as well.
             */
            int outArgCount = 0;
            for (ArgumentType argument : storedProcedure.getArguments()) {
                ArgumentTypeDirection argDirection = argument.getDirection();
                if (argDirection == OUT) {
                    outArgCount++;
                }
            }
            if (outArgCount > 1 || (outArgCount > 0 && storedProcedure.isFunctionType())) {
                isCollection = true;
                isSimpleXMLFormat = true;
                result = new CollectionResult();
                result.setType(ANY_QNAME);
            } else {
                if (storedProcedure.isFunctionType()) {
                    ArgumentType returnArg = ((FunctionType)storedProcedure).getReturnArgument();
                    result = buildResultForStoredFunction(returnArg, returnType);
                    // for strongly typed ref cursors we will customize the simple-xml-format
                    // tags to better represent the PL/SQL record/table/column type
                    if (returnArg.getEnclosedType().isPLSQLCursorType()) {
                        customizeSimpleXMLTagNames((PLSQLCursorType) returnArg.getEnclosedType(), procedureOperationModel);
                    }
                } else if (hasComplexArgs) {
                    if (Util.noOutArguments(storedProcedure)) {
                        result = new Result();
                        result.setType(new QName(SCHEMA_URL, INT, SCHEMA_PREFIX)); // rowcount
                    }
                } else { // !hasComplexArgs
                    // if user overrides returnType, assume they're right
                    if (returnType != null) {
                        result = new Result();
                        result.setType(buildCustomQName(returnType, dbwsBuilder));
                    } else {
                        if (isCollection) {
                            result = new CollectionResult();
                            if (isSimpleXMLFormat) {
                                result.setType(SXF_QNAME_CURSOR);
                            }
                        } else {
                            result = new Result();
                            result.setType(SXF_QNAME);
                        }
                    }
                }
            }
            for (ArgumentType arg : storedProcedure.getArguments()) {
                String argName = arg.getArgumentName();
                if (argName != null) {
                    QName xmlType = null;
                    ProcedureArgument pa = null;
                    ProcedureArgument paShadow = null; // for INOUT's
                    Parameter parm = null;
                    ArgumentTypeDirection direction = arg.getDirection();
                    if (!hasComplexArgs) {
                        if (arg.getEnclosedType().isPLSQLCursorType()) {
                            PLSQLCursorType cursorType = (PLSQLCursorType)arg.getEnclosedType();
                            if (cursorType.isWeaklyTyped()) {
                                xmlType = buildCustomQName("SYS_REFCURSOR", dbwsBuilder);
                            }
                        } else {
                            xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                        }
                    } else {
                        // handle PL/SQL records and collections
                        if (arg.getEnclosedType().isPLSQLType()) {
                            String packageName = ((PLSQLType) arg.getEnclosedType()).getParentType().getPackageName();
                            // may need to prepend package name
                            String typeString = (packageName != null && packageName.length() > 0) ? packageName + UNDERSCORE + arg.getTypeName() : arg.getTypeName();
                            // may need to strip off %
                            typeString = typeString.contains(PERCENT) ? typeString.replace(PERCENT, UNDERSCORE) : typeString;
                            xmlType = buildCustomQName(nct.generateSchemaAlias(typeString), dbwsBuilder);
                        } else if (arg.getEnclosedType().isVArrayType() || arg.getEnclosedType().isObjectType() || arg.getEnclosedType().isObjectTableType()) {
                            // handle advanced JDBC types
                            xmlType = buildCustomQName(nct.generateSchemaAlias(arg.getTypeName()), dbwsBuilder);
                        } else {
                            switch (Util.getJDBCTypeFromTypeName(arg.getTypeName())) {
                                case STRUCT:
                                case ARRAY:
                                    String typeString = nct.generateSchemaAlias(arg.getTypeName());
                                    xmlType = buildCustomQName(typeString, dbwsBuilder);
                                    break;
                                default :
                                    xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                                    break;
                            }
                        }
                    }
                    if (direction == null || direction == IN) {
                        parm = new Parameter();
                        parm.setName(argName);
                        parm.setType(xmlType);

                        // handle optional arg
                        parm.setOptional(arg.optional());

                        pa = new ProcedureArgument();
                        pa.setName(argName);
                        pa.setParameterName(argName);
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler)qh).getInArguments().add(pa);
                        }
                    } else {
                        // the first OUT/INOUT arg determines singleResult vs. collectionResult
                        pa = new ProcedureOutputArgument();
                        ProcedureOutputArgument pao = (ProcedureOutputArgument)pa;
                        pao.setName(argName);
                        pao.setParameterName(argName);
                        boolean isCursor = arg.isPLSQLCursorType() || arg.getTypeName().contains(CURSOR_STR);

                        // for strongly typed ref cursors we will customize the simple-xml-format
                        // tags to better represent the PL/SQL record/table/column type
                        if (arg.isPLSQLCursorType()) {
                            customizeSimpleXMLTagNames((PLSQLCursorType) arg.getEnclosedType(), procedureOperationModel);
                        }
                        if (isCursor && returnType == null) { // if user overrides returnType, assume they're right
                            pao.setResultType(SXF_QNAME_CURSOR);
                            if (result == null) {
                                result = new CollectionResult();
                                result.setType(SXF_QNAME_CURSOR);
                            }
                        } else {
                            // if user overrides returnType, assume they're right
                            // Hmm, multiple OUT's gonna be a problem - later!
                            if (returnType != null && !isSimpleXMLFormat) {
                                xmlType = qNameFromString(OPEN_PAREN + dbwsBuilder.getTargetNamespace() + CLOSE_PAREN + returnType, dbwsBuilder.getSchema());
                            }
                            if (isCursor) {
                                pao.setResultType(new QName(EMPTY_STRING, CURSOR_OF_STR + returnType));
                                Result newResult = new CollectionResult();
                                newResult.setType(result.getType());
                                result = newResult;
                            } else {
                                pao.setResultType(xmlType);
                            }
                            if (result == null) {
                                if (isCollection) {
                                    result = new CollectionResult();
                                } else {
                                    result = new Result();
                                }
                                result.setType(xmlType);
                            }
                        }
                        if (direction == INOUT) {
                            parm = new Parameter();
                            parm.setName(argName);
                            parm.setType(xmlType);
                            result.setType(xmlType);
                            if (qh instanceof StoredProcedureQueryHandler) {
                                ((StoredProcedureQueryHandler)qh).getInOutArguments().add(pao);
                            }
                            paShadow = new ProcedureArgument();
                            paShadow.setName(argName);
                            paShadow.setParameterName(argName);
                        } else { // OUT arg
                            if (qh instanceof StoredProcedureQueryHandler) {
                                ((StoredProcedureQueryHandler)qh).getOutArguments().add(pao);
                            }
                        }
                    }
                    // for XMLType, we want the type code to be 'OPAQUE' (2007)
                    if (arg.getEnclosedType() == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                        pa.setJdbcType(getJDBCTypeForTypeName(XMLTYPE_STR));
                    }
                    if (hasComplexArgs && arg.getEnclosedType().isPLSQLType()) {
                        pa.setComplexTypeName(storedProcedure.getCatalogName() + UNDERSCORE + arg.getTypeName());
                        if (paShadow != null) {
                            paShadow.setComplexTypeName(pa.getComplexTypeName());
                        }
                    }
                    if (parm != null) {
                        qo.getParameters().add(parm);
                    }
                }
            }
            if (procedureOperationModel.getBinaryAttachment()) {
                Attachment attachment = new Attachment();
                attachment.setMimeType(APP_OCTET_STREAM);
                result.setAttachment(attachment);
            }
            // the user may want simpleXMLFormat
            handleSimpleXMLFormat(isSimpleXMLFormat, result, procedureOperationModel);
            qo.setResult(result);
            dbwsBuilder.getXrServiceModel().getOperations().put(qo.getName(), qo);
        }
        finishProcedureOperation();
    }

    /**
     * Build and return a Result instance based on a given ProcedureType
     * and return type name.
     */
    protected Result buildResultForStoredFunction(ArgumentType returnArgument, String returnType) {
        Result result = null;
        DatabaseType rargDataType = returnArgument.getEnclosedType();

        // handle ref cursor
        if (rargDataType.isPLSQLCursorType() || returnArgument.getTypeName().contains(CURSOR_STR)) {
            result = new CollectionResult();
            result.setType(SXF_QNAME_CURSOR);
        } else {
            result = new Result();
            int rargJdbcType = OTHER;
            if (rargDataType.isComposite()) {
                if (rargDataType.isObjectType()) {
                    rargJdbcType = STRUCT;
                } else if (rargDataType.isVArrayType() || rargDataType.isObjectTableType()) {
                    rargJdbcType = ARRAY;
                }
            } else {
                rargJdbcType = Util.getJDBCTypeFromTypeName(returnArgument.getTypeName());
            }
            switch (rargJdbcType) {
                case OTHER:
                    String returnTypeName;
                    // if user overrides returnType, assume they're right
                    if (returnType != null && returnType.length() > 0) {
                        returnTypeName = returnType;
                    } else {
                        returnType = rargDataType.getTypeName();
                        // packages only apply to PL/SQL types
                        String packageName = null;
                        if (rargDataType.isPLSQLType()) {
                            packageName = ((PLSQLType) rargDataType).getParentType().getPackageName();
                        }
                        // may need to prepend a package name
                        returnTypeName = (packageName != null && packageName.length() > 0) ? packageName + UNDERSCORE + returnType : returnType;
                        // may need to strip off %
                        returnTypeName = returnTypeName.contains(PERCENT) ? returnTypeName.replace(PERCENT, UNDERSCORE) : returnTypeName;
                        returnTypeName = nct.generateSchemaAlias(returnTypeName);
                    }
                    result.setType(buildCustomQName(returnTypeName, dbwsBuilder));
                    break;
                case STRUCT:
                case ARRAY:
                    // if user overrides returnType, assume they're right
                    if (returnType == null || returnType.length() == 0) {
                        returnType = rargDataType.getTypeName().toLowerCase().concat(TYPE_STR);
                    }
                    result.setType(buildCustomQName(returnType, dbwsBuilder));
                    break;
                default :
                    // scalar types
                    result.setType(getXMLTypeFromJDBCType(rargJdbcType));
                    break;
            }
        }
        // for XMLType, we want the type code to be 'OPAQUE' (2007)
        if (rargDataType == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
            result.setJdbcType(getJDBCTypeForTypeName(XMLTYPE_STR));
        }
        return result;
    }


    /**
     * Returns the name to be used for a QueryOperation (or Query) based on a
     * given ProcedureType and ProcedureOperationModel.
     *
     * The returned string will be:
     *
     * 1) If the given ProcedureOperationModel 'name' is a non-null &amp; non-empty
     * string, the returned string will be one of the following:
     *   a) 'modelName' if no pattern matching or overloading
     *   b) 'modelName_procedureName' if pattern matching and no overloading
     *   c) 'modelName_overload' if overloading and no pattern matching
     *   d) 'modelName_procedureName_overload' if pattern matching &amp; overloading
     *
     * OR
     *
     * 2) If the given ProcedureOperationModel 'name' is a null or empty string, the
     * returned string will be in the format: 'overload_catalog_schema_procedureName'
     */
    protected String getNameForQueryOperation(ProcedureOperationModel opModel, ProcedureType storedProcedure) {
        StringBuilder sb = new StringBuilder();
        String modelName = opModel.getName();

        if (modelName != null && modelName.length() > 0) {
            sb.append(modelName);
            // handle pattern matching
            if (opModel.getProcedurePattern().contains(Util.PERCENT)) {
                sb.append(UNDERSCORE);
                sb.append(storedProcedure.getProcedureName());
            }
            // handle overload
            if (storedProcedure.getOverload() != 0) {
                sb.append(UNDERSCORE);
                sb.append(storedProcedure.getOverload());
            }
        } else {
            if (storedProcedure.getOverload() > 0) {
                sb.append(storedProcedure.getOverload());
                sb.append(UNDERSCORE);
            }
            if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
                sb.append(storedProcedure.getCatalogName());
                sb.append(UNDERSCORE);
            }
            if (storedProcedure.getSchema() != null && storedProcedure.getSchema().length() > 0) {
                sb.append(storedProcedure.getSchema());
                sb.append(UNDERSCORE);
            }
            sb.append(storedProcedure.getProcedureName());
        }
        return sb.toString();
    }

    /**
     * Returns the qualified stored procedure name based on a given ProcedureType
     * and ProcedureOperationModel.
     *
     * The returned string will be in the format: 'schema.catalog.procedureName'
     *
     */
    protected String getQualifiedProcedureName(ProcedureOperationModel procedureOperationModel, ProcedureType storedProcedure) {
        StringBuilder sb = new StringBuilder();
        if (procedureOperationModel.getSchemaPattern() != null &&
            procedureOperationModel.getSchemaPattern().length() > 0 &&
            storedProcedure.getSchema() != null &&
            storedProcedure.getSchema().length() > 0) {
            sb.append(storedProcedure.getSchema());
            sb.append(DOT);
        }
        if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
            sb.append(storedProcedure.getCatalogName());
            sb.append(DOT);
        }
        sb.append(storedProcedure.getProcedureName());
        return sb.toString();
    }

    /**
     * Generates a {@code List<TableType>} based on a given set of patterns.
     */
    @Override
    protected List<TableType> loadTables(List<String> catalogPatterns, List<String> schemaPatterns, List<String> tableNamePatterns) {
        try {
            return dtBuilder.buildTables(dbwsBuilder.getConnection(), schemaPatterns, tableNamePatterns);
        } catch (ParseException e) {
            dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
        }
        return null;
    }

    /**
     * Build list of name patterns separated by vertical bar.
     * @param namePatterns {@link List} of name patterns.
     * @return String containing list of name patterns separated by vertical bar.
     */
    private static String buildNamePatternsList(List<String> namePatterns) {
        final int count = namePatterns.size();
        if (count > 0) {
            int lenhth = count - 1;
            for (Iterator<String> i = namePatterns.iterator(); i.hasNext(); ) {
                lenhth += i.next().length();
            }
            StringBuilder out = new StringBuilder(lenhth);
            for (Iterator<String> i = namePatterns.iterator(); i.hasNext(); ) {
                out.append(i.next());
                if (i.hasNext()) {
                    out.append(StringHelper.VERTICAL_BAR);
                }
            }
            return out.toString();
        } else {
            return StringHelper.EMPTY_STRING;
        }
    }

    /**
     * Generates a {@code List<ProcedureType>} based on a given set of patterns.
     */
    @Override
    protected List<ProcedureType> loadProcedures(List<String> catalogPatterns, List<String> schemaPatterns, List<String> procedureNamePatterns) {
        List<ProcedureType> allProcsAndFuncs = new ArrayList<ProcedureType>();
        List<String> topLevelSchemaPatterns = new ArrayList<String>();
        List<String> topLevelProcedureNamePatterns = new ArrayList<String>();
        Map<String, Set<String>> packagePatterns = new HashMap<String,Set<String>>();
        for (int i = 0, len = catalogPatterns.size(); i < len; i++) {
            String catalogPattern = catalogPatterns.get(i);
            String schemaPattern = schemaPatterns.get(i);
            if (schemaPattern == null) {
                schemaPattern = dbwsBuilder.getUsername().toUpperCase();
            }
            if (catalogPattern == null || catalogPattern.length() == 0 || TOPLEVEL.equals(catalogPattern)) {
                topLevelSchemaPatterns.add(schemaPattern);
                topLevelProcedureNamePatterns.add(procedureNamePatterns.get(i));
            } else {
                Set<String> packageNames = packagePatterns.get(schemaPattern);
                if (packageNames == null) {
                    packageNames = new HashSet<String>();
                    packagePatterns.put(schemaPattern, packageNames);
                }
                packageNames.add(catalogPattern);
            }
        }
        if (topLevelProcedureNamePatterns.size() > 0) {
            try {
                List<ProcedureType> topLevelProcedures = dtBuilder.buildProcedures(dbwsBuilder.getConnection(), topLevelSchemaPatterns, topLevelProcedureNamePatterns);
                if (topLevelProcedures != null && topLevelProcedures.size() > 0) {
                    allProcsAndFuncs.addAll(topLevelProcedures);
                }
            } catch (ParseException e) {
                dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
            }
            try {
                List<FunctionType> topLevelFunctions = dtBuilder.buildFunctions(dbwsBuilder.getConnection(), topLevelSchemaPatterns, topLevelProcedureNamePatterns);
                if (topLevelFunctions != null && topLevelFunctions.size() > 0) {
                    allProcsAndFuncs.addAll(topLevelFunctions);
                }
            } catch (ParseException e) {
                dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
            }
        }
        if (packagePatterns.size() > 0) {
            try {
                //unravel map
                List<String> schemaPats = new ArrayList<String>();
                List<String> packagePats = new ArrayList<String>();
                for (Map.Entry<String, Set<String>> entry : packagePatterns.entrySet()) {
                    String schema = entry.getKey();
                    for (String packageName : entry.getValue()) {
                        schemaPats.add(schema);
                        packagePats.add(packageName);
                    }
                }
                List<PLSQLPackageType> packages = dtBuilder.buildPackages(dbwsBuilder.getConnection(), schemaPats, packagePats);
                if (packages == null || packages.isEmpty()) {
                    logPackageNotFoundWarnings(NO_PKG_MSG, schemaPats, packagePats);
                } else {
                    for (PLSQLPackageType pakage : packages) {
                        //check DDL generation
                        ShadowDDLGenerator ddlGenerator = new ShadowDDLGenerator(pakage);
                        dbwsBuilder.getTypeDDL().addAll(ddlGenerator.getAllCreateDDLs());
                        dbwsBuilder.getTypeDropDDL().addAll(ddlGenerator.getAllDropDDLs());
                        //check for overloading
                        Map<String, List<ProcedureType>> overloadMap = new HashMap<String, List<ProcedureType>>();
                        List<ProcedureType> procedures = pakage.getProcedures();
                        for (ProcedureType procedure : procedures) {
                            String procedureName = procedure.getProcedureName();
                            List<ProcedureType> multipleProcedures = overloadMap.get(procedureName);
                            if (multipleProcedures == null) {
                                multipleProcedures = new ArrayList<ProcedureType>();
                                overloadMap.put(procedureName, multipleProcedures);
                            }
                            multipleProcedures.add(procedure);
                        }
                        for (List<ProcedureType> procs : overloadMap.values()) {
                            if (procs.size() >1) {
                                for (int i = 0, len = procs.size(); i < len; i++) {
                                    procs.get(i).setOverload(i);
                                }
                            }
                        }
                        // Check against procedureNamePatterns
                        String tmp = buildNamePatternsList(procedureNamePatterns);
                        for (ProcedureType procedure : procedures) {
                            if (sqlMatch(tmp, procedure.getProcedureName())) {
                                allProcsAndFuncs.add(procedure);
                            }
                        }
                    }
                }
            } catch (ParseException e) {
                dbwsBuilder.logMessage(Level.WARNING, e.getMessage());
            }
        }
        return allProcsAndFuncs.isEmpty() ? null : allProcsAndFuncs;
    }

    /**
     * Create OR/OX projects for complex types, i.e. PLSQLTypes, VArray, etc.
     */
    @Override
    public void addToOROXProjectsForComplexTypes(List<CompositeDatabaseType> types, Project orProject, Project oxProject) {
        for (DatabaseType dbType : types) {
            String name;
            String alias;
            if (dbType.isPLSQLType()) {
                // set type name to upper case to avoid runtime SQLException
                dbType.setTypeName(dbType.getTypeName().toUpperCase());

                String catalogPattern = ((PLSQLType) dbType).getParentType().getPackageName();
                String targetTypeName;
                // for types enclosed in a ROWTYPEType, package doesn't apply
                if (catalogPattern == null) {
                    name = dbType.getTypeName();
                    targetTypeName = dbType.getTypeName();
                } else {
                    name = catalogPattern + DOT + dbType.getTypeName();
                    targetTypeName = catalogPattern + UNDERSCORE + dbType.getTypeName();
                }
                alias = targetTypeName.toLowerCase();

                // remove '%' from target, alias, and name
                name = name.replace(PERCENT, UNDERSCORE);
                targetTypeName = targetTypeName.replace(PERCENT, UNDERSCORE);
                alias = alias.replace(PERCENT, UNDERSCORE);

                // handle PL/SQL record type
                if (dbType.isPLSQLRecordType()) {
                    addToOXProjectForPLSQLRecordArg(dbType, oxProject, name, alias, targetTypeName, catalogPattern);
                    addToORProjectForPLSQLRecordArg(dbType, orProject, name, alias, targetTypeName, catalogPattern);
                }  // handle PL/SQL collection type
                else {
                    addToOXProjectForPLSQLTableArg(dbType, oxProject, name, alias, targetTypeName, catalogPattern);
                    addToORProjectForPLSQLTableArg(dbType, orProject, name, alias, targetTypeName, catalogPattern);
                }
            } else {
                // Advanced JDBC types need the (Java) package name prepended to the type name
                if (Util.isTypeComplex(dbType)) {
                    name = getGeneratedJavaClassName(dbType.getTypeName(), dbwsBuilder.getProjectName());
                } else {
                    name = dbType.getTypeName();
                }
                alias = getGeneratedAlias(dbType.getTypeName());
                // handle VArray type
                if (dbType.isVArrayType()) {
                    addToOXProjectForVArrayArg(dbType, oxProject, name, alias);
                    addToORProjectForVArrayArg(dbType, orProject, name, alias);
                }  // handle ObjectType type
                else if (dbType.isObjectType()) {
                    addToOXProjectForObjectTypeArg(dbType, oxProject, name, alias);
                    addToORProjectForObjectTypeArg(dbType, orProject, name, alias);
                } // handle ObjectTable type
                else if (dbType.isObjectTableType()) {
                    addToOXProjectForObjectTableTypeArg(dbType, oxProject, name, alias);
                    addToORProjectForObjectTableTypeArg(dbType, orProject, name, alias);
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for a PL/SQL record argument.  The newly
     * created descriptor will be added to the given OX project.
     */
    protected void addToOXProjectForPLSQLRecordArg(DatabaseType dbType, Project oxProject, String recordName, String recordAlias, String targetTypeName, String catalogPattern) {
        XMLDescriptor xdesc = (XMLDescriptor) oxProject.getDescriptorForAlias(recordAlias);
        if (xdesc == null) {
            xdesc = buildAndAddNewXMLDescriptor(oxProject, recordAlias, recordName.toLowerCase(), nct.generateSchemaAlias(targetTypeName), buildCustomQName(targetTypeName, dbwsBuilder).getNamespaceURI());
        }
        // handle fields
        PLSQLRecordType plsqlRecType = (PLSQLRecordType) dbType;
        for (FieldType fType : plsqlRecType.getFields()) {
            // custom naming transformer may exclude some fields
            if (nct.styleForElement(fType.getFieldName()) == ElementStyle.NONE) {
                continue;
            }
            String lFieldName = fType.getFieldName().toLowerCase();
            if (xdesc.getMappingForAttributeName(lFieldName) == null) {
                if (fType.isComposite()) {
                    // handle pl/sql record and pl/sql table fields
                    if (fType.getEnclosedType().isPLSQLRecordType()) {
                        buildAndAddXMLCompositeObjectMapping(xdesc, lFieldName, (catalogPattern + DOT + fType.getEnclosedType()).toLowerCase());
                    } else if (fType.getEnclosedType().isPLSQLCollectionType()) {
                        PLSQLCollectionType tableType = (PLSQLCollectionType) fType.getEnclosedType();
                        if (tableType.getEnclosedType().isComposite()) {
                            buildAndAddXMLCompositeObjectMapping(xdesc, lFieldName, (catalogPattern + DOT + tableType.getTypeName()).toLowerCase() + COLLECTION_WRAPPER_SUFFIX);
                        } else {
                            Class<?> attributeElementClass = String.class;
                            XMLDescriptor refDesc = (XMLDescriptor) oxProject.getDescriptorForAlias((catalogPattern + UNDERSCORE + tableType.getTypeName()).toLowerCase());
                            if (refDesc != null) {
                                attributeElementClass = ((XMLCompositeDirectCollectionMapping)refDesc.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME)).getAttributeElementClass();
                            }
                            buildAndAddXMLCompositeDirectCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + ITEM_MAPPING_NAME + SLASH + TEXT, attributeElementClass);
                        }
                    } else if (fType.getEnclosedType().isObjectType()) {
                        buildAndAddXMLCompositeObjectMapping(xdesc, lFieldName, getGeneratedJavaClassName(fType.getEnclosedType().getTypeName(), dbwsBuilder.getProjectName()));
                    } else if (fType.getEnclosedType().isVArrayType()) {
                        if (((VArrayType)fType.getEnclosedType()).getEnclosedType().isComposite()) {
                            String nestedTypeAlias = ((VArrayType) fType.getEnclosedType()).getEnclosedType().getTypeName().toLowerCase();
                            String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                            buildAndAddXMLCompositeCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + ITEM_MAPPING_NAME, nestedTypeName);
                        } else {
                            buildAndAddXMLCompositeDirectCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + ITEM_MAPPING_NAME + SLASH + TEXT, getAttributeClassForDatabaseType(fType.getEnclosedType()));
                        }
                    } else if (fType.getEnclosedType().isObjectTableType()) {
                        ObjectTableType nestedType = (ObjectTableType) fType.getEnclosedType();
                        if (nestedType.getEnclosedType().isComposite()) {
                            String nestedTypeAlias = nestedType.getEnclosedType().getTypeName().toLowerCase();
                            String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                            // ObjectType is composite
                            buildAndAddXMLCompositeCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + ITEM_MAPPING_NAME, nestedTypeName);
                        } else {
                            buildAndAddXMLCompositeDirectCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + TEXT, getAttributeClassForDatabaseType(nestedType));
                        }
                    } else if (fType.getEnclosedType().isTYPEType()) {  // handle %TYPE
                        TYPEType typeType = (TYPEType) fType.getEnclosedType();
                        if (typeType.getEnclosedType().isFieldType()) {
                            // direct mapping
                            addDirectMappingForFieldType(xdesc, lFieldName, (FieldType)typeType.getEnclosedType());
                        }
                    }
                } else {
                    // direct mapping
                    addDirectMappingForFieldType(xdesc, lFieldName, fType);
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for a PL/SQL record argument.  The newly
     * created descriptor will be added to the given OR project.
     */
    @SuppressWarnings("rawtypes")
    protected void addToORProjectForPLSQLRecordArg(DatabaseType dbType, Project orProject, String recordName, String recordAlias, String targetTypeName, String catalogPattern) {
        ObjectRelationalDataTypeDescriptor ordtDesc = (ObjectRelationalDataTypeDescriptor) orProject.getDescriptorForAlias(recordAlias);
        if (ordtDesc == null) {
            ordtDesc = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, recordAlias, recordName.toLowerCase());
        }
        // handle fields
        PLSQLRecordType plsqlRecType = (PLSQLRecordType) dbType;
        for (FieldType fType : plsqlRecType.getFields()) {
            String fieldName = fType.getFieldName();
            String lFieldName = fieldName.toLowerCase();
            // handle field ordering
            boolean found = false;
            Vector orderedFields = ordtDesc.getOrderedFields();
            for (Iterator i = orderedFields.iterator(); i.hasNext();) {
                Object o = i.next();
                if (o instanceof DatabaseField) {
                    DatabaseField field = (DatabaseField)o;
                    if (field.getName().equalsIgnoreCase(fieldName)) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                ordtDesc.addFieldOrdering(fieldName);
            }
            if (ordtDesc.getMappingForAttributeName(lFieldName) == null) {
                if (fType.isComposite()) {
                    if (fType.getEnclosedType().isPLSQLRecordType()) {
                        buildAndAddStructureMapping(ordtDesc, lFieldName, fieldName, recordName.toLowerCase());
                    } else if (fType.getEnclosedType().isPLSQLCollectionType()) {
                        PLSQLCollectionType tableType = (PLSQLCollectionType) fType.getEnclosedType();
                        if (tableType.getEnclosedType().isComposite()) {
                            buildAndAddObjectArrayMapping(ordtDesc, lFieldName, fieldName, (catalogPattern + "." + tableType.getTypeName()).toLowerCase() + COLLECTION_WRAPPER_SUFFIX, getStructureNameForField(fType, catalogPattern));
                        } else {
                            buildAndAddArrayMapping(ordtDesc, lFieldName, fieldName, getStructureNameForField(fType, catalogPattern));
                        }
                    } else if (fType.getEnclosedType().isObjectType()) {
                        buildAndAddStructureMapping(ordtDesc, lFieldName, fieldName, getGeneratedJavaClassName(fType.getEnclosedType().getTypeName(), dbwsBuilder.getProjectName()));
                    } else if (fType.getEnclosedType().isVArrayType()) {
                        if (((VArrayType)fType.getEnclosedType()).getEnclosedType().isComposite()) {
                            buildAndAddObjectArrayMapping(ordtDesc, lFieldName, fieldName, getGeneratedJavaClassName(((VArrayType)fType.getEnclosedType()).getEnclosedType().getTypeName(), dbwsBuilder.getProjectName()), getStructureNameForField(fType, null));
                        } else {
                            buildAndAddArrayMapping(ordtDesc, lFieldName, fieldName, getStructureNameForField(fType, null));
                        }
                    } else if (fType.getEnclosedType().isObjectTableType()) {
                        ObjectTableType nestedType = (ObjectTableType) fType.getEnclosedType();
                        if (nestedType.getEnclosedType().isComposite()) {
                            ObjectType oType = (ObjectType) nestedType.getEnclosedType();
                            String oTypeAlias = oType.getTypeName().toLowerCase();
                            String oTypeName = getGeneratedJavaClassName(oTypeAlias, dbwsBuilder.getProjectName());
                            // ObjectType is composite
                            buildAndAddObjectArrayMapping(ordtDesc, lFieldName, fieldName, oTypeName, oTypeAlias.toUpperCase());
                        } else {
                            buildAndAddArrayMapping(ordtDesc, lFieldName, fieldName, nestedType.getTypeName().toUpperCase());
                        }
                    } else if (fType.getEnclosedType().isTYPEType()) {  // handle %TYPE
                        TYPEType typeType = (TYPEType) fType.getEnclosedType();
                        if (typeType.getEnclosedType().isFieldType()) {
                            // direct mapping
                            AbstractDirectMapping absDirectMapping = (AbstractDirectMapping) ordtDesc.addDirectMapping(lFieldName, fieldName);
                            try {
                                absDirectMapping.setAttributeClassificationName(getClassFromJDBCType(fType.getTypeName(), dbwsBuilder.getDatabasePlatform()).getName());
                            } catch (Exception x) {}
                        }
                    }
                } else {
                    // direct mapping
                    DirectToFieldMapping dfm = new DirectToFieldMapping();
                    dfm.setFieldName(fieldName);
                    dfm.setAttributeName(lFieldName);
                    dfm.setAttributeClassification(getAttributeClassForDatabaseType(fType.getEnclosedType()));
                    ordtDesc.addMapping(dfm);
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for a PL/SQL collection argument.  The newly
     * created descriptor will be added to the given OX project.
     */
    protected void addToOXProjectForPLSQLTableArg(DatabaseType dbType, Project oxProject, String tableName, String tableAlias, String targetTypeName, String catalogPattern) {
        XMLDescriptor xdesc = (XMLDescriptor) oxProject.getDescriptorForAlias(tableAlias);
        if (xdesc == null) {
            xdesc = buildAndAddNewXMLDescriptor(oxProject, tableAlias, tableName.toLowerCase() + COLLECTION_WRAPPER_SUFFIX, nct.generateSchemaAlias(targetTypeName), buildCustomQName(targetTypeName, dbwsBuilder).getNamespaceURI());
        }

        boolean itemsMappingFound = xdesc.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            DatabaseType nestedType = ((PLSQLCollectionType)dbType).getEnclosedType();
            if (nestedType.isPLSQLRecordType()) {
                String referenceClassName = (catalogPattern + DOT + ((PLSQLRecordType)nestedType).getTypeName()).toLowerCase();
                buildAndAddXMLCompositeCollectionMapping(xdesc, referenceClassName);
                if (oxProject.getDescriptorForAlias(referenceClassName) == null) {
                    String refTypeName = catalogPattern + UNDERSCORE + ((PLSQLRecordType)nestedType).getTypeName();
                    addToOXProjectForPLSQLRecordArg(nestedType, oxProject, referenceClassName, refTypeName.toLowerCase(), refTypeName, catalogPattern);
                }
            } else if (nestedType.isObjectType()) {
                buildAndAddXMLCompositeCollectionMapping(xdesc, getGeneratedJavaClassName(nestedType.getTypeName(), dbwsBuilder.getProjectName()));
            } else {
                if (nestedType.isComposite()) {
                    buildAndAddXMLCompositeCollectionMapping(xdesc, tableName.toLowerCase() + COLLECTION_WRAPPER_SUFFIX);
                } else {
                    buildAndAddXMLCompositeDirectCollectionMapping(xdesc, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEM_MAPPING_NAME + SLASH + TEXT, getAttributeClassForDatabaseType(nestedType));
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for a PL/SQL collection argument.  The newly
     * created descriptor will be added to the given OR project.
     */
    protected void addToORProjectForPLSQLTableArg(DatabaseType dbType, Project orProject, String tableName, String tableAlias, String targetTypeName, String catalogPattern) {
        ObjectRelationalDataTypeDescriptor ordt = (ObjectRelationalDataTypeDescriptor) orProject.getDescriptorForAlias(tableAlias);
        if (ordt == null) {
            ordt = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, tableAlias, tableName.toLowerCase() + COLLECTION_WRAPPER_SUFFIX);
        }
        boolean itemsMappingFound = ordt.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            DatabaseType nestedType = ((PLSQLCollectionType) dbType).getEnclosedType();
            if (nestedType.isPLSQLRecordType()) {
                String referenceClassName = (catalogPattern + DOT + ((PLSQLRecordType)nestedType).getTypeName()).toLowerCase();
                buildAndAddObjectArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, referenceClassName, targetTypeName);
                if (orProject.getDescriptorForAlias(referenceClassName) == null) {
                    String refTypeName = catalogPattern + UNDERSCORE + ((PLSQLRecordType)nestedType).getTypeName();
                    addToORProjectForPLSQLRecordArg(nestedType, orProject, referenceClassName, refTypeName.toLowerCase(), refTypeName, catalogPattern);
                }
            } else if (nestedType.isObjectType()) {
                buildAndAddObjectArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, getGeneratedJavaClassName(nestedType.getTypeName(), dbwsBuilder.getProjectName()), targetTypeName);
            } else {
                buildAndAddArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, targetTypeName);
            }
        }
    }

    /**
     * Build descriptor and mappings for a VArray argument.  The newly
     * created descriptor will be added to the given OX project.
     */
    protected void addToOXProjectForVArrayArg(DatabaseType dbType, Project oxProject, String arrayName, String arrayAlias) {
        DatabaseType nestedDbType = ((VArrayType)dbType).getEnclosedType();
        String referenceTypeAlias = getGeneratedAlias(nestedDbType.getTypeName());

        String referenceTypeName = getGeneratedJavaClassName(referenceTypeAlias, dbwsBuilder.getProjectName());
        XMLDescriptor xdesc = (XMLDescriptor)oxProject.getDescriptorForAlias(arrayAlias);
        if (xdesc == null) {
            xdesc = buildAndAddNewXMLDescriptor(oxProject, arrayAlias, arrayName + COLLECTION_WRAPPER_SUFFIX, nct.generateSchemaAlias(arrayAlias), buildCustomQName(arrayName, dbwsBuilder).getNamespaceURI());
            // before we add this descriptor, check if the nested type's descriptor
            // should be built and added first
            XMLDescriptor refXdesc = (XMLDescriptor)oxProject.getDescriptorForAlias(referenceTypeAlias);
            if (refXdesc == null) {
                if (nestedDbType.isObjectType()) {
                    addToOXProjectForObjectTypeArg(nestedDbType, oxProject, referenceTypeName, referenceTypeAlias);
                }
            }
        }
        boolean itemsMappingFound = xdesc.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            if (nestedDbType.isComposite()) {
                buildAndAddXMLCompositeCollectionMapping(xdesc, referenceTypeName);
            } else {
                buildAndAddXMLCompositeDirectCollectionMapping(xdesc, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEM_MAPPING_NAME + SLASH + TEXT, getAttributeClassForDatabaseType(nestedDbType));
            }
        }
    }

    /**
     * Build descriptor and mappings for a VArray argument.  The newly
     * created descriptor will be added to the given OX project.
     */
    protected void addToORProjectForVArrayArg(DatabaseType dbType, Project orProject, String arrayName, String arrayAlias) {
        DatabaseType nestedDbType = ((VArrayType)dbType).getEnclosedType();
        String referenceTypeAlias = getGeneratedAlias(nestedDbType.getTypeName());
        String referenceTypeName = getGeneratedJavaClassName(referenceTypeAlias, dbwsBuilder.getProjectName());
        ObjectRelationalDataTypeDescriptor ordt = (ObjectRelationalDataTypeDescriptor)orProject.getDescriptorForAlias(arrayAlias);
        if (ordt == null) {
            ordt = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, arrayAlias, arrayName + COLLECTION_WRAPPER_SUFFIX);
            // before we add this descriptor, check if the nested type's descriptor
            // should be built and added first
            ClassDescriptor refdesc = orProject.getDescriptorForAlias(referenceTypeAlias);
            if (refdesc == null) {
                if (nestedDbType.isObjectType()) {
                    addToORProjectForObjectTypeArg(nestedDbType, orProject, referenceTypeName, referenceTypeAlias);
                }
            }
        }
        boolean itemsMappingFound = ordt.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            if (nestedDbType.isComposite()) {
                buildAndAddObjectArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, referenceTypeName, arrayName);
            } else {
                buildAndAddArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, arrayAlias.toUpperCase(), nestedDbType.getTypeName());
            }
        }
    }

    /**
     * Build descriptor and mappings for an Object type argument.  The
     * newly created descriptor will be added to the given OX project.
     */
    protected void addToOXProjectForObjectTypeArg(DatabaseType dbType, Project oxProject, String objectName, String objectAlias) {
        XMLDescriptor xdesc = (XMLDescriptor) oxProject.getDescriptorForAlias(objectAlias);
        if (xdesc == null) {
            xdesc = buildAndAddNewXMLDescriptor(oxProject, objectAlias, objectName, nct.generateSchemaAlias(dbType.getTypeName()), buildCustomQName(objectName, dbwsBuilder).getNamespaceURI());
        }
        ObjectType oType = (ObjectType) dbType;
        for (FieldType field : oType.getFields()) {
            // custom transformer may exclude some fields
            if (nct.styleForElement(field.getFieldName()) == ElementStyle.NONE) {
                continue;
            }
            String lFieldName = field.getFieldName().toLowerCase();
            if (xdesc.getMappingForAttributeName(lFieldName) == null) {
                if (field.isComposite()) {
                    String targetTypeName2 = field.getEnclosedType().getTypeName();
                    String alias = getGeneratedAlias(targetTypeName2);
                    XMLDescriptor xdesc2 = (XMLDescriptor) oxProject.getDescriptorForAlias(alias);
                    boolean buildDescriptor = xdesc2 == null;
                    if (buildDescriptor) {
                        xdesc2 = buildAndAddNewXMLDescriptor(oxProject, alias, nct.generateSchemaAlias(targetTypeName2), buildCustomQName(targetTypeName2, dbwsBuilder).getNamespaceURI());
                    }
                    // handle ObjectType field
                    if (field.getEnclosedType().isObjectType()) {
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            xdesc2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            addToOXProjectForObjectTypeArg(field.getEnclosedType(), oxProject, xdesc2.getJavaClassName(), alias);
                        }
                        buildAndAddXMLCompositeObjectMapping(xdesc, lFieldName, xdesc2.getJavaClassName());
                    } else if (field.getEnclosedType().isVArrayType()) {
                        // handle VArray field
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            xdesc2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            addToOXProjectForVArrayArg(field.getEnclosedType(), oxProject, xdesc2.getJavaClassName(), alias);
                        }
                        buildAndAddXMLCompositeDirectCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + TEXT, getAttributeClassForDatabaseType(field.getEnclosedType()));
                    } else if (field.getEnclosedType().isObjectTableType()) {
                        // handle ObjectTableType field
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            xdesc2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            // make sure the descriptor is built for the enclosed ObjectType
                            addToOXProjectForObjectTableTypeArg(field.getEnclosedType(), oxProject, targetTypeName2, alias);
                        }
                        ObjectTableType tableType = (ObjectTableType) field.getEnclosedType();
                        if (tableType.getEnclosedType().isComposite()) {
                            String nestedTypeAlias = getGeneratedAlias(((ObjectTableType) field.getEnclosedType()).getEnclosedType().getTypeName());
                            String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                            buildAndAddXMLCompositeCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + ITEM_MAPPING_NAME, nestedTypeName);
                        } else {
                            buildAndAddXMLCompositeDirectCollectionMapping(xdesc, lFieldName, lFieldName + SLASH + TEXT, getAttributeClassForDatabaseType(tableType));
                        }
                    }
                } else {
                    // direct mapping
                    addDirectMappingForFieldType(xdesc, lFieldName, field);
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for an Object type argument.  The
     * newly created descriptor will be added to the given OX project.
     */
    @SuppressWarnings("rawtypes")
    protected void addToORProjectForObjectTypeArg(DatabaseType dbType, Project orProject, String objectName, String objectAlias) {
        ObjectRelationalDataTypeDescriptor ordt = (ObjectRelationalDataTypeDescriptor)orProject.getDescriptorForAlias(objectAlias);
        if (ordt == null) {
            ordt = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, objectAlias, objectName);
        }
        ObjectType oType = (ObjectType) dbType;
        for (FieldType fType : oType.getFields()) {
            String fieldName = fType.getFieldName();
            String lFieldName = fieldName.toLowerCase();

            // handle field ordering
            boolean found = false;
            Vector orderedFields = ordt.getOrderedFields();
            for (Iterator i = orderedFields.iterator(); i.hasNext();) {
                Object o = i.next();
                if (o instanceof DatabaseField) {
                    DatabaseField field = (DatabaseField)o;
                    if (field.getName().equalsIgnoreCase(fieldName)) {
                        found = true;
                        break;
                    }
                }
            }
            if (!found) {
                ordt.addFieldOrdering(fieldName);
            }
            if (ordt.getMappingForAttributeName(lFieldName) == null) {
                if (fType.isComposite()) {
                    String targetTypeName2 = fType.getEnclosedType().getTypeName();
                    String alias = getGeneratedAlias(targetTypeName2);
                    ObjectRelationalDataTypeDescriptor ordt2 = (ObjectRelationalDataTypeDescriptor)orProject.getDescriptorForAlias(alias);
                    boolean buildDescriptor = ordt2 == null;
                    if (buildDescriptor) {
                        ordt2 = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, alias);
                    }
                    // handle ObjectType field
                    if (fType.getEnclosedType().isObjectType()) {
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            ordt2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            addToORProjectForObjectTypeArg(fType.getEnclosedType(), orProject, ordt2.getJavaClassName(), alias);
                        }
                        buildAndAddStructureMapping(ordt, lFieldName, fieldName, ordt2.getJavaClassName());
                    } else if (fType.getEnclosedType().isVArrayType()) {
                        // handle VArray field
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            ordt2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            addToORProjectForVArrayArg(fType.getEnclosedType(), orProject, ordt2.getJavaClassName(), alias);
                        }
                        buildAndAddArrayMapping(ordt, lFieldName, fieldName, getStructureNameForField(fType, null));
                    } else if (fType.getEnclosedType().isObjectTableType()) {
                        if (buildDescriptor) {
                            // need to update the java class name on the descriptor to include package (project) name
                            ordt2.setJavaClassName(getGeneratedJavaClassName(alias, dbwsBuilder.getProjectName()));
                            // make sure the descriptor is built for the enclosed ObjectType
                            addToORProjectForObjectTableTypeArg(fType.getEnclosedType(), orProject, targetTypeName2, alias);
                        }
                        if (((ObjectTableType) fType.getEnclosedType()).getEnclosedType().isComposite()) {
                            ObjectType nestedType = (ObjectType)((ObjectTableType) fType.getEnclosedType()).getEnclosedType();
                            String nestedTypeAlias = getGeneratedAlias(nestedType.getTypeName());
                            String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                            buildAndAddObjectArrayMapping(ordt, lFieldName, fieldName, nestedTypeName, nestedTypeAlias.toUpperCase());
                        } else {
                            buildAndAddArrayMapping(ordt, lFieldName, fieldName, alias.toUpperCase());
                        }
                    }
                } else {
                    // direct mapping
                    DirectToFieldMapping dfm = new DirectToFieldMapping();
                    dfm.setFieldName(fieldName);
                    dfm.setAttributeName(lFieldName);
                    dfm.setAttributeClassification(getAttributeClassForDatabaseType(fType.getEnclosedType()));
                    ordt.addMapping(dfm);
                }
            }
        }
    }

    /**
     * Build descriptor and mappings for an OracleTableType argument.  The
     * newly created descriptor will be added to the given OX project.
     */
    protected void addToOXProjectForObjectTableTypeArg(DatabaseType dbType, Project oxProject, String objectTableName, String objectTableAlias) {
        XMLDescriptor xdesc = (XMLDescriptor) oxProject.getDescriptorForAlias(objectTableAlias);
        if (xdesc == null) {
            xdesc = buildAndAddNewXMLDescriptor(oxProject, objectTableAlias, objectTableName + COLLECTION_WRAPPER_SUFFIX, nct.generateSchemaAlias(dbType.getTypeName()), buildCustomQName(objectTableName, dbwsBuilder).getNamespaceURI());
        }
        boolean itemsMappingFound = xdesc.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            DatabaseType nType = ((ObjectTableType) dbType).getEnclosedType();
            if (nType.isObjectType()) {
                ObjectType oType = (ObjectType)nType;
                String nestedTypeAlias = getGeneratedAlias(oType.getTypeName());
                String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                addToOXProjectForObjectTypeArg(oType, oxProject, nestedTypeName, nestedTypeAlias);
                // ObjectType is composite
                buildAndAddXMLCompositeCollectionMapping(xdesc, nestedTypeName);
            } else {
                buildAndAddXMLCompositeDirectCollectionMapping(xdesc, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEM_MAPPING_NAME + SLASH + TEXT, getAttributeClassForDatabaseType(nType));
            }
        }
    }

    /**
     * Build descriptor and mappings for an OracleTableType argument.  The
     * newly created descriptor will be added to the given OR project.
     */
    protected void addToORProjectForObjectTableTypeArg(DatabaseType dbType, Project orProject, String objectTableName, String objectTableAlias) {
        ObjectRelationalDataTypeDescriptor ordt = (ObjectRelationalDataTypeDescriptor)orProject.getDescriptorForAlias(objectTableAlias);
        if (ordt == null) {
            ordt = buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, objectTableAlias, objectTableName + COLLECTION_WRAPPER_SUFFIX);
        }
        boolean itemsMappingFound = ordt.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (!itemsMappingFound) {
            DatabaseType nestedType = ((ObjectTableType) dbType).getEnclosedType();
            if (nestedType.isObjectType()) {
                ObjectType oType = (ObjectType) nestedType;
                String nestedTypeAlias = getGeneratedAlias(oType.getTypeName());
                String nestedTypeName = getGeneratedJavaClassName(nestedTypeAlias, dbwsBuilder.getProjectName());
                addToORProjectForObjectTypeArg(oType, orProject, nestedTypeName, nestedTypeAlias);
                // ObjectType is composite
                buildAndAddObjectArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, nestedTypeName, nestedTypeAlias.toUpperCase());
            } else {
                buildAndAddArrayMapping(ordt, ITEMS_MAPPING_ATTRIBUTE_NAME, ITEMS_MAPPING_FIELD_NAME, objectTableAlias.toUpperCase());
            }
        }
    }

    /**
     * Build a Query for the given ProcedureType instance and add
     * it to the given OR project's list of queries.
     */
    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected void buildQueryForProcedureType(ProcedureType procType, Project orProject, Project oxProject, ProcedureOperationModel opModel, boolean hasPLSQLArgs) {
        // if there are one or more PL/SQL args, then we need a PLSQLStoredProcedureCall
        StoredProcedureCall call;
        ArgumentType returnArg = procType.isFunctionType() ? ((FunctionType)procType).getReturnArgument() : null;

        // check for PL/SQL cursor arg
        boolean hasCursor = hasPLSQLCursorArg(getArgumentListForProcedureType(procType));
        hasPLSQLArgs = hasPLSQLArgs || hasCursor || opModel.isPLSQLProcedureOperation();

        if (hasPLSQLArgs) {
            if (procType.isFunctionType()) {
                org.eclipse.persistence.internal.helper.DatabaseType dType = buildDatabaseTypeFromMetadataType(returnArg, procType.getCatalogName());
                if (hasCursor) {
                    call = new PLSQLStoredFunctionCall();
                    // constructor by default adds a RETURN argument, so remove it
                    ((PLSQLStoredFunctionCall)call).getArguments().remove(0);
                    ((PLSQLStoredFunctionCall)call).useNamedCursorOutputAsResultSet(CURSOR_STR, dType);
                } else {
                    Class wrapperClass = getWrapperClass(dType);
                    if (wrapperClass != null) {
                        ((ComplexDatabaseType) dType).setJavaType(wrapperClass);
                    }
                    call = new PLSQLStoredFunctionCall(dType);
                    // check for non-associative collection
                    if (returnArg.getEnclosedType().isPLSQLCollectionType() && !((PLSQLCollectionType)returnArg.getEnclosedType()).isIndexed()) {
                        PLSQLargument plsqlArg = ((PLSQLStoredFunctionCall)call).getArguments().get(0);
                        ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                    }
                }
            } else {
                call = new PLSQLStoredProcedureCall();
            }
        } else {
            if (procType.isFunctionType()) {
                String javaTypeName = returnArg.getTypeName();
                ClassDescriptor desc = oxProject.getDescriptorForAlias(getGeneratedAlias(javaTypeName));
                if (desc != null) {
                    javaTypeName = desc.getJavaClassName();
                }

                if (returnArg.isComposite()) {
                    DatabaseType dataType = returnArg.getEnclosedType();
                    if (dataType.isVArrayType() || dataType.isObjectTableType()) {
                        call = new StoredFunctionCall(Types.ARRAY, returnArg.getTypeName(), javaTypeName, buildFieldForNestedType(dataType));
                    } else {
                        // assumes ObjectType
                        call = new StoredFunctionCall(Types.STRUCT, returnArg.getTypeName(), javaTypeName);
                    }
                } else {
                    // scalar
                    call = new StoredFunctionCall();
                    if (returnArg.getEnclosedType().isBlobType()) {
                        // handle BLOBs
                        ((StoredFunctionCall) call).setResult(null, ClassConstants.BLOB);
                    } else {
                        int resultType = Util.getJDBCTypeFromTypeName(javaTypeName);
                        // need special handling for Date types
                        if (resultType == Types.DATE || resultType == Types.TIME || resultType == Types.TIMESTAMP) {
                            ((StoredFunctionCall) call).setResult(null, ClassConstants.TIMESTAMP);
                        } else if (returnArg.getEnclosedType() == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                            // special handling for XMLType types
                            ((StoredFunctionCall) call).setResult(getJDBCTypeForTypeName(XMLTYPE_STR), XMLTYPE_STR, ClassConstants.OBJECT);
                        } else if (resultType == Types.OTHER || resultType == Types.CLOB) {
                            // default to OBJECT for OTHER, CLOB and LONG types
                            ((StoredFunctionCall) call).setResult(null, ClassConstants.OBJECT);
                        } else {
                            ((StoredFunctionCall) call).setResult(null, resultType);
                        }
                    }
                }
            } else {
                call = new StoredProcedureCall();
            }
        }

        String cat = procType.getCatalogName();
        String catalogPrefix = (cat == null || cat.length() == 0) ? EMPTY_STRING : cat + DOT;
        call.setProcedureName(catalogPrefix + procType.getProcedureName());
        String returnType = opModel.getReturnType();
        boolean hasResponse = returnType != null;

        DatabaseQuery dq = null;
        if (hasCursor || (hasResponse && opModel.isCollection())) {
            dq = new DataReadQuery();
        } else {
            dq = new ValueReadQuery();
        }
        dq.bindAllParameters();
        dq.setName(getNameForQueryOperation(opModel, procType));
        dq.setCall(call);

        for (ArgumentType arg : procType.getArguments()) {
            // handle optional arg
            if (arg.optional()) {
                call.addOptionalArgument(arg.getArgumentName());
            }

            DatabaseType argType = arg.getEnclosedType();
            ArgumentTypeDirection direction = arg.getDirection();

            // for PL/SQL
            org.eclipse.persistence.internal.helper.DatabaseType databaseType = null;
            // for Advanced JDBC
            String javaTypeName = null;

            if (hasPLSQLArgs) {
                databaseType = buildDatabaseTypeFromMetadataType(argType, cat);
            } else {
                javaTypeName = argType.getTypeName();
                ClassDescriptor desc = oxProject.getDescriptorForAlias(getGeneratedAlias(javaTypeName));
                if (desc != null) {
                    // anything there's a descriptor for will include "packagename." in the class name
                    javaTypeName = desc.getJavaClassName();
                }
            }

            if (direction == IN) {
                if (hasPLSQLArgs) {
                    Class wrapperClass = getWrapperClass(databaseType);
                    if (wrapperClass != null) {
                        ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                    }
                    ((PLSQLStoredProcedureCall)call).addNamedArgument(arg.getArgumentName(), databaseType);
                    // check for non-associative collection
                    if (argType.isPLSQLCollectionType() && !((PLSQLCollectionType)argType).isIndexed()) {
                        PLSQLargument plsqlArg = ((PLSQLStoredProcedureCall)call).getArguments().get(((PLSQLStoredProcedureCall)call).getArguments().size()-1);
                        ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                    }
                } else {
                    if (argType.isVArrayType()) {
                        dq.addArgument(arg.getArgumentName());
                        call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), javaTypeName);
                    } else if (argType.isObjectType()) {
                        dq.addArgument(arg.getArgumentName());
                        call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName(), javaTypeName);
                    } else if (argType.isObjectTableType()) {
                        dq.addArgument(arg.getArgumentName(), java.sql.Array.class);
                        call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), getWrapperClass(javaTypeName), buildFieldForNestedType(argType));
                    } else {
                        dq.addArgument(arg.getArgumentName());
                        call.addNamedArgument(arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()));
                    }
                }
            } else if (direction == OUT) {
                if (hasPLSQLArgs) {
                    if (arg.isPLSQLCursorType()) {
                        ((PLSQLStoredProcedureCall)call).useNamedCursorOutputAsResultSet(arg.getArgumentName(), databaseType);
                    } else {
                        Class wrapperClass = getWrapperClass(databaseType);
                        if (wrapperClass != null) {
                            ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                        }
                        ((PLSQLStoredProcedureCall)call).addNamedOutputArgument(arg.getArgumentName(), databaseType);
                    }
                } else {
                    if (argType.isComposite()) {
                        Class wrapperClass = getWrapperClass(javaTypeName);

                        if (argType.isVArrayType() || argType.isObjectTableType()) {
                            call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), wrapperClass, buildFieldForNestedType(argType));
                        } else {
                            // assumes ObjectType
                            call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName(), wrapperClass);
                        }
                    } else {
                        // need special handling for XMLType - we want the type code to be 'OPAQUE' (2007)
                        if (argType == ScalarDatabaseTypeEnum.XMLTYPE_TYPE) {
                            call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), getJDBCTypeForTypeName(XMLTYPE_STR), XMLTYPE_STR);
                        } else if (argType == ScalarDatabaseTypeEnum.SYS_REFCURSOR_TYPE) {
                            call.addNamedCursorOutputArgument(arg.getArgumentName());
                        } else {
                            call.addNamedOutputArgument(arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()));
                        }
                    }
                }
            } else {  // INOUT
                if (hasPLSQLArgs) {
                    Class wrapperClass = getWrapperClass(databaseType);
                    if (wrapperClass != null) {
                        ((ComplexDatabaseType) databaseType).setJavaType(wrapperClass);
                    }
                    ((PLSQLStoredProcedureCall)call).addNamedInOutputArgument(arg.getArgumentName(), databaseType);
                    // check for non-associative collection
                    if (argType.isPLSQLCollectionType() && !((PLSQLCollectionType)argType).isIndexed()) {
                        PLSQLargument plsqlArg = ((PLSQLStoredProcedureCall)call).getArguments().get(((PLSQLStoredProcedureCall)call).getArguments().size()-1);
                        ((PLSQLCollection) plsqlArg.databaseType).setIsNestedTable(true);
                    }
                } else {
                    dq.addArgument(arg.getArgumentName());
                    if (argType.isComposite()) {
                        Class wrapperClass = getWrapperClass(javaTypeName);

                        if (argType.isVArrayType() || argType.isObjectTableType()) {
                            call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Types.ARRAY, argType.getTypeName(), wrapperClass, buildFieldForNestedType(argType));
                        } else {
                            // assumes ObjectType
                            call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Types.STRUCT, argType.getTypeName());
                        }
                    } else {
                        // for some reason setting "java.lang.String" as the java type causes problems at runtime
                        Class javaType = getClassFromJDBCType(argType.getTypeName(), dbwsBuilder.getDatabasePlatform());
                        if (shouldSetJavaType(javaType.getName())) {
                            call.addNamedInOutputArgument(arg.getArgumentName(), arg.getArgumentName(), arg.getArgumentName(), Util.getJDBCTypeFromTypeName(argType.getTypeName()), argType.getTypeName(), javaType);
                        } else {
                            call.addNamedInOutputArgument(arg.getArgumentName());
                        }
                    }
                }
            }
            if (hasPLSQLArgs && (direction == IN || direction == INOUT)) {
                ClassDescriptor xdesc = null;
                if (hasResponse) {
                    int idx = returnType.indexOf(COLON);
                    if (idx == -1) {
                        idx = returnType.indexOf(CLOSE_PAREN);
                    }
                    if (idx > 0) {
                        String typ = returnType.substring(idx+1);
                        for (XMLDescriptor xd : (List<XMLDescriptor>)(List)oxProject.getOrderedDescriptors()) {
                            if (xd.getSchemaReference() != null) {
                                String context = xd.getSchemaReference().getSchemaContext();
                                if (context.substring(1).equals(typ)) {
                                    xdesc = xd;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (xdesc != null) {
                    dq.addArgumentByTypeName(arg.getArgumentName(), xdesc.getJavaClassName());
                } else {
                    if (databaseType instanceof PLSQLCollection || databaseType instanceof VArrayType) {
                        dq.addArgument(arg.getArgumentName(), Array.class);
                    } else if (databaseType instanceof PLSQLrecord || databaseType instanceof OracleObjectType) {
                        dq.addArgument(arg.getArgumentName(), Struct.class);
                    } else {
                        dq.addArgument(arg.getArgumentName(), JDBCTypes.getClassForCode(databaseType.getConversionCode()));
                    }
                }
            }
        }
        orProject.getQueries().add(dq);
    }

    /**
     * Build an OR database field for a given type's nested type.
     */
    protected ObjectRelationalDatabaseField buildFieldForNestedType(DatabaseType owningType) {
        ObjectRelationalDatabaseField nestedField = new ObjectRelationalDatabaseField("");
        DatabaseType nestedType;
        if (owningType.isVArrayType()) {
            nestedType = ((VArrayType)owningType).getEnclosedType();
            if (nestedType.isComposite()) {
                nestedField.setSqlTypeName(nestedType.getTypeName());
                nestedField.setSqlType(Types.STRUCT);
            } else {
                nestedField.setSqlTypeName(Util.getJDBCTypeNameFromType(Types.ARRAY));
                nestedField.setSqlType(Types.ARRAY);
            }
        } else {
            nestedType = ((ObjectTableType)owningType).getEnclosedType();
            nestedField.setSqlTypeName(nestedType.getTypeName());
            nestedField.setSqlType(Types.STRUCT);
        }
        nestedField.setTypeName(getGeneratedJavaClassName(nestedType.getTypeName().toLowerCase(), dbwsBuilder.getProjectName()));
        return nestedField;
    }

    /**
     * Create an XMLDirectMapping for a given FieldType instance, and add the
     * newly created mapping to the given XMLDescriptor.
     */
    protected void addDirectMappingForFieldType(XMLDescriptor xdesc, String attributeName, FieldType fType) {
        XMLDirectMapping fieldMapping = new XMLDirectMapping();
        fieldMapping.setAttributeName(attributeName);

        XMLField xField;
        if (nct.styleForElement(attributeName) == ElementStyle.ATTRIBUTE) {
            xField = new XMLField(AT_SIGN + attributeName);
        } else {
            xField = new XMLField(attributeName + SLASH + TEXT);
        }

        QName qnameFromDatabaseType = getXMLTypeFromJDBCType(org.eclipse.persistence.tools.dbws.Util.getJDBCTypeFromTypeName(fType.getTypeName()));
        xField.setSchemaType(qnameFromDatabaseType);
        // special case to avoid Calendar problems
        if (qnameFromDatabaseType == DATE_QNAME) {
            fieldMapping.setAttributeClassification(java.sql.Date.class);
            xField.addXMLConversion(DATE_QNAME, java.sql.Date.class);
            xField.addJavaConversion(java.sql.Date.class, DATE_QNAME);
            xdesc.getNamespaceResolver().put(SCHEMA_PREFIX, SCHEMA_URL);
        } else {
            Class<?> attributeClass = (Class<?>)XMLConversionManager.getDefaultXMLTypes().get(qnameFromDatabaseType);
            if (attributeClass == null) {
                attributeClass =  Object_Class;
            }
            fieldMapping.setAttributeClassification(attributeClass);
        }
        fieldMapping.setField(xField);
        AbstractNullPolicy nullPolicy = fieldMapping.getNullPolicy();
        nullPolicy.setNullRepresentedByEmptyNode(false);
        nullPolicy.setMarshalNullRepresentation(XSI_NIL);
        nullPolicy.setNullRepresentedByXsiNil(true);
        fieldMapping.setNullPolicy(nullPolicy);
        xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX, SCHEMA_INSTANCE_URL); // to support xsi:nil policy
        xdesc.addMapping(fieldMapping);
    }

    /**
     * Build an XMLCompositeObjectMapping based on given attribute and reference
     * class names, and add the newly created mapping to the given descriptor.
     */
    protected void buildAndAddXMLCompositeObjectMapping(XMLDescriptor xdesc, String attributeName, String referenceClassName) {
        xdesc.addMapping(buildXMLCompositeObjectMapping(attributeName, referenceClassName));
    }
    /**
     * Build an XMLCompositeObjectMapping based on given attribute and reference
     * class names, and add the newly created mapping to the given descriptor.
     */
    protected void buildAndAddXMLCompositeObjectMapping(XMLDescriptor xdesc, String attributeName, String xpath, String referenceClassName) {
        xdesc.addMapping(buildXMLCompositeObjectMapping(attributeName, referenceClassName));
    }
    /**
     * Build an XMLCompositeObjectMapping based on given attribute
     * and reference class names.
     */
    protected XMLCompositeObjectMapping buildXMLCompositeObjectMapping(String attributeName, String referenceClassName) {
        return buildXMLCompositeObjectMapping(attributeName, attributeName, referenceClassName);
    }
    /**
     * Build an XMLCompositeObjectMapping based on given attribute
     * and reference class names.
     */
    protected XMLCompositeObjectMapping buildXMLCompositeObjectMapping(String attributeName, String xpath, String referenceClassName) {
        XMLCompositeObjectMapping mapping = new XMLCompositeObjectMapping();
        mapping.setAttributeName(attributeName);
        mapping.setXPath(xpath);
        XMLField xField = (XMLField)mapping.getField();
        xField.setRequired(true);
        mapping.setReferenceClassName(referenceClassName);
        return mapping;
    }

    /**
     * Build an XMLCompositeCollectionMapping based on a given attribute name,  xpath,
     * and reference class, and add the newly created mapping to the given descriptor.
     */
    protected void buildAndAddXMLCompositeCollectionMapping(XMLDescriptor xdesc, String attributeName, String xPath, String referenceClassName) {
        xdesc.addMapping(buildXMLCompositeCollectionMapping(attributeName, xPath, referenceClassName));
    }
    /**
     * Build an XMLCompositeCollectionMapping based on a given reference class
     * name, and add the newly created mapping to the given descriptor.
     */
    protected void buildAndAddXMLCompositeCollectionMapping(XMLDescriptor xdesc, String referenceClassName) {
        xdesc.addMapping(buildXMLCompositeCollectionMapping(referenceClassName));
    }
    /**
     * Build an XMLCompositeCollectionMapping based on a given reference class name.
     * The attribute name will be set to 'items', and the xpath set to 'item'.
     */
    protected XMLCompositeCollectionMapping buildXMLCompositeCollectionMapping(String referenceClassName) {
        return buildXMLCompositeCollectionMapping(ITEMS_MAPPING_ATTRIBUTE_NAME, ITEM_MAPPING_NAME, referenceClassName);
    }
    /**
     * Build an XMLCompositeCollectionMapping based on a given attribute name, xpath,
     * and reference class.
     */
    protected XMLCompositeCollectionMapping buildXMLCompositeCollectionMapping(String attributeName, String xPath, String referenceClassName) {
        XMLCompositeCollectionMapping itemsMapping = new XMLCompositeCollectionMapping();
        itemsMapping.setAttributeName(attributeName);
        itemsMapping.setXPath(xPath);
        ((XMLField)itemsMapping.getField()).setRequired(true);
        itemsMapping.useCollectionClass(ArrayList.class);
        itemsMapping.setReferenceClassName(referenceClassName);
        return itemsMapping;
    }

    /**
     * Build an XMLCompositeDirectCollectionMapping based on a given attribute name, xpath,
     * and attribute element class.  The newly created mapping will be added to the given
     * XML descriptor.
     */
    protected XMLCompositeDirectCollectionMapping buildAndAddXMLCompositeDirectCollectionMapping(XMLDescriptor xdesc, String attributeName, String xPath, Class<?> attributeElementClass) {
        XMLCompositeDirectCollectionMapping itemsMapping = buildXMLCompositeDirectCollectionMapping(attributeName, xPath, attributeElementClass);
        xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX, SCHEMA_INSTANCE_URL); // to support xsi:nil policy
        xdesc.addMapping(itemsMapping);
        return itemsMapping;
    }
    /**
     * Build an XMLCompositeDirectCollectionMapping based on a given attribute name, xpath,
     * and attribute element class.
     */
    protected XMLCompositeDirectCollectionMapping buildXMLCompositeDirectCollectionMapping(String attributeName, String xPath, Class<?> attributeElementClass) {
        XMLCompositeDirectCollectionMapping itemsMapping = new XMLCompositeDirectCollectionMapping();
        itemsMapping.setAttributeElementClass(attributeElementClass);
        itemsMapping.setAttributeName(attributeName);
        itemsMapping.setUsesSingleNode(true);
        itemsMapping.setXPath(xPath);
        ((XMLField)itemsMapping.getField()).setRequired(true);
        itemsMapping.useCollectionClass(ArrayList.class);
        AbstractNullPolicy nullPolicy = itemsMapping.getNullPolicy();
        nullPolicy.setNullRepresentedByEmptyNode(false);
        nullPolicy.setMarshalNullRepresentation(XSI_NIL);
        nullPolicy.setNullRepresentedByXsiNil(true);
        itemsMapping.setNullPolicy(nullPolicy);
        return itemsMapping;
    }

    /**
     * Builds a StructureMapping based on a given attributeName, fieldName and reference
     * class name, and adds the newly created mapping to the given OR descriptor.
     */
    protected StructureMapping buildAndAddStructureMapping(ObjectRelationalDataTypeDescriptor orDesc, String attributeName, String fieldName, String referenceClassName) {
        StructureMapping structureMapping = buildStructureMapping(attributeName, fieldName, referenceClassName);
        orDesc.addMapping(structureMapping);
        return structureMapping;
    }
    /**
     * Builds a StructureMapping based on a given attributeName, fieldName
     * and reference class name.
     */
    protected StructureMapping buildStructureMapping(String attributeName, String fieldName, String referenceClassName) {
        StructureMapping structureMapping = new StructureMapping();
        structureMapping.setAttributeName(attributeName);
        structureMapping.setFieldName(fieldName);
        structureMapping.setReferenceClassName(referenceClassName);
        // we have a map of created descriptors, keyed on javaClassName, which - along with a
        // list of referenceClassNames (set upon reference mapping creation) will allow us
        // to set aggregate descriptors as required.
        referencedORDescriptors.add(referenceClassName);

        return structureMapping;
    }

    /**
     * Builds an ObjectArrayMapping based on a given attribute name, field name,
     * reference class name, field type and package name, and adds the newly
     * created mapping to the given OR descriptor.
     */
    protected ObjectArrayMapping buildAndAddObjectArrayMapping(ObjectRelationalDataTypeDescriptor orDesc, String attributeName, String fieldName, String referenceClassName, String structureName) {
        ObjectArrayMapping objectArrayMapping = buildObjectArrayMapping(attributeName, fieldName, referenceClassName, structureName);
        orDesc.addMapping(objectArrayMapping);
        return objectArrayMapping;
    }
    /**
     * Builds an ObjectArrayMapping based on a given attribute name, field name,
     * reference class name and structureName.
     */
    protected ObjectArrayMapping buildObjectArrayMapping(String attributeName, String fieldName, String referenceClassName, String structureName) {
        ObjectArrayMapping objectArrayMapping = new ObjectArrayMapping();
        objectArrayMapping.setAttributeName(attributeName);
        objectArrayMapping.setFieldName(fieldName);
        objectArrayMapping.setStructureName(structureName);
        objectArrayMapping.useCollectionClass(ArrayList.class);
        objectArrayMapping.setReferenceClassName(referenceClassName);
        // we have a map of created descriptors, keyed on javaClassName, which - along with a
        // list of referenceClassNames (set upon reference mapping creation) will allow us
        // to set aggregate descriptors as required.
        referencedORDescriptors.add(referenceClassName);

        return objectArrayMapping;
    }

    /**
     * Build an ArrayMapping based on a given attribute name, field name, structure name and
     * nested type name.  The newly created mapping will be added to the given OR descriptor.
     */
    protected ArrayMapping buildAndAddArrayMapping(ObjectRelationalDataTypeDescriptor orDesc, String attributeName, String fieldName, String structureName, String nestedTypeName) {
        ArrayMapping arrayMapping = buildArrayMapping(attributeName, fieldName, structureName);
        arrayMapping.setElementDataTypeName(nestedTypeName);
        orDesc.addMapping(arrayMapping);
        return arrayMapping;
    }
    /**
     * Build an ArrayMapping based on a given attribute name, field name and structure
     * name.  The newly created mapping will be added to the given OR descriptor.
     */
    protected ArrayMapping buildAndAddArrayMapping(ObjectRelationalDataTypeDescriptor orDesc, String attributeName, String fieldName, String structureName) {
        ArrayMapping arrayMapping = buildArrayMapping(attributeName, fieldName, structureName);
        orDesc.addMapping(arrayMapping);
        return arrayMapping;
    }
    /**
     * Build an ArrayMapping based on a given attribute name, field name and structure
     * name.
     */
    protected ArrayMapping buildArrayMapping(String attributeName, String fieldName, String structureName) {
        ArrayMapping arrayMapping = new ArrayMapping();
        arrayMapping.setAttributeName(attributeName);
        arrayMapping.setFieldName(fieldName);
        arrayMapping.setStructureName(structureName);
        arrayMapping.useCollectionClass(ArrayList.class);
        return arrayMapping;
    }

    /**
     * Build an XMLDescriptor based on a given descriptor alias, schema alias and target
     * namespace, and add the newly created descriptor to the given OX Project.
     */
    protected XMLDescriptor buildAndAddNewXMLDescriptor(Project oxProject, String objectAlias, String userType, String targetNamespace) {
        return buildAndAddNewXMLDescriptor(oxProject, objectAlias, objectAlias, userType, targetNamespace);
    }
    /**
     * Build an XMLDescriptor based on a given descriptor alias, schema alias, java class name
     * and target namespace, and add the newly created descriptor to the given OX Project.
     */
    protected XMLDescriptor buildAndAddNewXMLDescriptor(Project oxProject, String objectAlias, String javaClassName, String userType, String targetNamespace) {
        XMLDescriptor xdesc = buildNewXMLDescriptor(objectAlias, javaClassName, userType, targetNamespace);
        oxProject.addDescriptor(xdesc);
        return xdesc;
    }
    /**
     * Build an XMLDescriptor based on a given descriptor alias,
     * schema alias, and target namespace.
     */
    protected XMLDescriptor buildNewXMLDescriptor(String objectAlias, String userType, String targetNamespace) {
        return buildNewXMLDescriptor(objectAlias, objectAlias, userType, targetNamespace);
    }
    /**
     * Build an XMLDescriptor based on a given descriptor alias,
     * java class name schema alias, and target namespace.
     */
    protected XMLDescriptor buildNewXMLDescriptor(String objectAlias, String javaClassName, String userType, String targetNamespace) {
        XMLDescriptor xdesc = new XMLDescriptor();
        xdesc.setAlias(objectAlias);
        xdesc.setJavaClassName(javaClassName);
        xdesc.getQueryManager();
        XMLSchemaURLReference schemaReference = new XMLSchemaURLReference();
        schemaReference.setSchemaContext(SLASH + userType);
        schemaReference.setType(org.eclipse.persistence.platform.xml.XMLSchemaReference.COMPLEX_TYPE);
        xdesc.setSchemaReference(schemaReference);
        NamespaceResolver nr = new NamespaceResolver();
        nr.setDefaultNamespaceURI(targetNamespace);
        xdesc.setNamespaceResolver(nr);
        xdesc.setDefaultRootElement(userType);
        return xdesc;
    }

    /**
     * Build an ObjectRelationalDataTypeDescriptor based on a given
     * descriptor alias and add it to the given OR Project.
     */
    protected ObjectRelationalDataTypeDescriptor buildAndAddNewObjectRelationalDataTypeDescriptor(Project orProject, String alias) {
        return buildAndAddNewObjectRelationalDataTypeDescriptor(orProject, alias, alias);
    }
    /**
     * Build an ObjectRelationalDataTypeDescriptor based on a given descriptor
     * alias and java class name, and add it to the given OR Project.
     */
    protected ObjectRelationalDataTypeDescriptor buildAndAddNewObjectRelationalDataTypeDescriptor(Project orProject, String alias, String javaClassName) {
        ObjectRelationalDataTypeDescriptor ordesc = buildNewObjectRelationalDataTypeDescriptor(alias, javaClassName);
        orProject.addDescriptor(ordesc);
        return ordesc;
    }
    /**
     * Build an ObjectRelationalDataTypeDescriptor based on a given
     * descriptor alias.
     */
    protected ObjectRelationalDataTypeDescriptor buildNewObjectRelationalDataTypeDescriptor(String alias) {
        return buildNewObjectRelationalDataTypeDescriptor(alias, alias);
    }
    /**
     * Build an ObjectRelationalDataTypeDescriptor based on a given
     * descriptor alias and java class name.
     */
    protected ObjectRelationalDataTypeDescriptor buildNewObjectRelationalDataTypeDescriptor(String alias, String javaClassName) {
        ObjectRelationalDataTypeDescriptor ordt = new ObjectRelationalDataTypeDescriptor();
        ordt.setStructureName(alias.toUpperCase());
        ordt.descriptorIsAggregate();

        // we have a map of created descriptors, keyed on javaClassName, which - along with a
        // list of referenceClassNames (set upon reference mapping creation) - will allow us
        // to set aggregate descriptors as required.
        createdORDescriptors.put(javaClassName, ordt);

        ordt.setAlias(alias);
        ordt.setJavaClassName(javaClassName);
        ordt.getQueryManager();
        return ordt;
    }

    /**
     * Return the structure name to be set on a mapping based on a given
     * FieldType and packageName.
     */
    protected String getStructureNameForField(FieldType fType, String packageName) {
        DatabaseType type = fType.getEnclosedType();
        String structureName = type.getTypeName();
        if (packageName != null && packageName.length() > 0 && !packageName.equals(TOPLEVEL)) {
            structureName = packageName + UNDERSCORE + structureName;
        }
        return structureName;
    }

    /**
     * Customizes the simple-xml-format tags names to better represent the
     * PL/SQL record/table/column type. This is possible only with
     * strongly-typed ref cursors, since for weakly-typed ones we
     * don't know anything about the cursor's output type.
     */
    protected void customizeSimpleXMLTagNames(PLSQLCursorType plsqlCursor, ProcedureOperationModel procedureOperationModel) {
        if (!plsqlCursor.isWeaklyTyped()) {
            // do not override user tag customization
            if (procedureOperationModel.getSimpleXMLFormatTag() == null) {
                procedureOperationModel.setSimpleXMLFormatTag(plsqlCursor.getCursorName());
            }

            // Enclosed type could be one of:
            // - PLSQLRecordType
            // - ROWTYPEType
            // - TYPEType
            if (procedureOperationModel.getXmlTag() == null) {
                if (plsqlCursor.getEnclosedType().isPLSQLRecordType()) {
                    PLSQLRecordType recType = (PLSQLRecordType) plsqlCursor.getEnclosedType();
                    procedureOperationModel.setXmlTag(recType.getTypeName());
                } else if (plsqlCursor.getEnclosedType().isROWTYPEType()) {
                    // assumes ROWTYPEType has an enclosed TableType
                    ROWTYPEType rowType = (ROWTYPEType) plsqlCursor.getEnclosedType();
                    TableType tableType = (TableType) rowType.getEnclosedType();
                    procedureOperationModel.setXmlTag(tableType.getTableName());
                 }
            }
        }
    }

    /**
     * Overridden for wrapping call with call to {@link #translateToOracleType} method.
     */
    @Override
    protected org.eclipse.persistence.internal.helper.DatabaseType buildDatabaseTypeFromMetadataType(DatabaseType dType, String catalog) {
        org.eclipse.persistence.internal.helper.DatabaseType databaseType = super.buildDatabaseTypeFromMetadataType(dType, catalog);
        return translateToOracleType(databaseType);
    }

    /**
     * Provides the possibility to override generic type with applicable Oracle specific type.
     *
     * @param databaseType the generic DatabaseType to override
     * @return the Oracle specific DatabaseType if such exists
     */
    private org.eclipse.persistence.internal.helper.DatabaseType translateToOracleType(org.eclipse.persistence.internal.helper.DatabaseType databaseType) {
        switch (databaseType.getTypeName()) {
            case "NVARCHAR":
                return JDBCTypes.NVARCHAR2_TYPE;
            default:
                return databaseType;
        }
    }
}
