/*
 * 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:
//     David McCann - 2.6.0 - July 09, 2013 - Initial Implementation
package org.eclipse.persistence.tools.metadata.generation;

import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.EL_ACCESS_VIRTUAL;
import static org.eclipse.persistence.tools.metadata.generation.Util.ALL_QUERYNAME;
import static org.eclipse.persistence.tools.metadata.generation.Util.AND_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.ARRAYLIST_CLS_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.CLOSE_BRACKET;
import static org.eclipse.persistence.tools.metadata.generation.Util.COMMA_SPACE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.CREATE_OPERATION_NAME;
import static org.eclipse.persistence.tools.metadata.generation.Util.CURSOR_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.DELETE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.DOT;
import static org.eclipse.persistence.tools.metadata.generation.Util.EQUALS_BINDING1_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.EQUALS_BINDING_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.INSERT_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.ITEMS_COL_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.ITEMS_FLD_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.OPEN_BRACKET;
import static org.eclipse.persistence.tools.metadata.generation.Util.OUT_CURSOR_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.PERCENT;
import static org.eclipse.persistence.tools.metadata.generation.Util.PK_QUERYNAME;
import static org.eclipse.persistence.tools.metadata.generation.Util.REMOVE_OPERATION_NAME;
import static org.eclipse.persistence.tools.metadata.generation.Util.RESULT_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.ROWTYPE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.SELECT_FROM_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.SET_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.SINGLE_SPACE;
import static org.eclipse.persistence.tools.metadata.generation.Util.TYPE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.UNDERSCORE;
import static org.eclipse.persistence.tools.metadata.generation.Util.UPDATE_OPERATION_NAME;
import static org.eclipse.persistence.tools.metadata.generation.Util.UPDATE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.VALUES_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.WHERE_STR;
import static org.eclipse.persistence.tools.metadata.generation.Util.getAttributeTypeNameForFieldType;
import static org.eclipse.persistence.tools.metadata.generation.Util.getClassNameFromJDBCTypeName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getEntityName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getGeneratedJavaClassName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getJDBCTypeFromTypeName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getJDBCTypeName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getOraclePLSQLTypeForName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getQualifiedCompatibleTypeName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getQualifiedTypeName;
import static org.eclipse.persistence.tools.metadata.generation.Util.getUnqualifiedEntityName;
import static org.eclipse.persistence.tools.metadata.generation.Util.handleOverloading;
import static org.eclipse.persistence.tools.metadata.generation.Util.isArgPLSQLScalar;
import static org.eclipse.persistence.tools.metadata.generation.Util.processTypeName;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.jpa.metadata.accessors.MetadataHelper;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.MappedSuperclassAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.XMLAttributes;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicCollectionAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicMapAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ElementCollectionAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.IdAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToManyAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.OneToManyAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.OneToOneAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.TransformationAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.TransientAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.VariableOneToOneAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.VersionAccessor;
import org.eclipse.persistence.internal.jpa.metadata.columns.ColumnMetadata;
import org.eclipse.persistence.internal.jpa.metadata.columns.TenantDiscriminatorColumnMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.MixedConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.ObjectTypeConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.SerializedConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.StructConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.converters.TypeConverterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.HashPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.PartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.PinnedPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.RangePartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.ReplicationPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.RoundRobinPartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.partitioning.ValuePartitioningMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedNativeQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedPLSQLStoredFunctionQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedPLSQLStoredProcedureQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedStoredFunctionQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.NamedStoredProcedureQueryMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.OracleArrayTypeMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.OracleObjectTypeMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.PLSQLParameterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.PLSQLRecordMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.PLSQLTableMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.SQLResultSetMappingMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.StoredProcedureParameterMetadata;
import org.eclipse.persistence.internal.jpa.metadata.sequencing.SequenceGeneratorMetadata;
import org.eclipse.persistence.internal.jpa.metadata.sequencing.TableGeneratorMetadata;
import org.eclipse.persistence.internal.jpa.metadata.structures.ArrayAccessor;
import org.eclipse.persistence.internal.jpa.metadata.structures.StructMetadata;
import org.eclipse.persistence.internal.jpa.metadata.structures.StructureAccessor;
import org.eclipse.persistence.internal.jpa.metadata.tables.TableMetadata;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
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.CompositeDatabaseTypeWithEnclosedType;
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.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.TYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType;

/**
 * This class is responsible for generating an XMLEntityMappings instance based
 * on a given list of meta-model database types.
 *
 * @see org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings
 * @see org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType
 */
public class JPAMetadataGenerator {
    protected XMLEntityMappings xmlEntityMappings;
    protected DatabasePlatform dbPlatform;
    protected String defaultPackage;
    protected boolean generateCRUDOps = false;

    // keep track of processed composite types to avoid duplicates and wasted effort
    protected List<String> processedTypes = null;

    // keep track of processed embeddables to avoid duplicates and wasted effort
    protected List<String> generatedEmbeddables = null;

    // default platform will be Oracle11Platform
    protected static final String DEFAULT_PLATFORM = "org.eclipse.persistence.platform.database.oracle.Oracle11Platform";

    /**
     * Default constructor.  Sets the default package name to null, and dbPlatform to
     * org.eclipse.persistence.platform.database.oracle.Oracle11Platform.
     *
     * The default package name will be prepended to generated class names for database
     * artifacts that are not in a PL/SQL package.
     *
     * The database platform is used to get class names for database types, i.e.
     * java.math.BigDecimal for DECIMAL.
     *
     * @see "org.eclipse.persistence.platform.database.oracle.Oracle11Platform"
     * @see org.eclipse.persistence.internal.databaseaccess.DatabasePlatform
     */
    public JPAMetadataGenerator() {
        this(null, DEFAULT_PLATFORM);
    }

    /**
     * This constructor allows setting the default package name and database platform.
     *
     * @param defaultPackage package name to be prepended to generated class names for artifacts
     * not in a PL/SQL package such as an Entity (to avoid having classes in the default package)
     * @param platformClassName class name of the DatabasePlatform to be used to get class names
     * for database types, i.e. java.math.BigDecimal for DECIMAL.
     * @see org.eclipse.persistence.internal.databaseaccess.DatabasePlatform
     */
    public JPAMetadataGenerator(String defaultPackage, String platformClassName) {
        this(defaultPackage, loadDatabasePlatform(platformClassName));
    }

    /**
     * This constructor allows setting the default package name and database platform.
     *
     * @param defaultPackage package name to be prepended to generated class names for artifacts
     * not in a PL/SQL package such as an Entity (to avoid having classes in the default package)
     * @param dbPlatform DatabasePlatform to be used to get class names for database types, i.e.
     * java.math.BigDecimal for DECIMAL.
     * @see org.eclipse.persistence.internal.databaseaccess.DatabasePlatform
     */
    public JPAMetadataGenerator(String defaultPackage, DatabasePlatform dbPlatform) {
        this(defaultPackage, dbPlatform, false);
    }

    /**
     * This constructor allows setting the default package name and database platform.
     *
     * @param defaultPackage package name to be prepended to generated class names for artifacts
     * not in a PL/SQL package such as an Entity (to avoid having classes in the default package)
     * @param dbPlatform DatabasePlatform to be used to get class names for database types, i.e.
     * java.math.BigDecimal for DECIMAL.
     * @param generateCRUDOps if true, CRUD operations (NamedNativeQueryMetadata) will be
     * generated for each Entity
     * @see org.eclipse.persistence.internal.databaseaccess.DatabasePlatform
     */
    public JPAMetadataGenerator(String defaultPackage, DatabasePlatform dbPlatform, boolean generateCRUDOps) {
        this.defaultPackage = defaultPackage == null ? null : defaultPackage.toLowerCase();
        this.dbPlatform = dbPlatform;
        this.generateCRUDOps = generateCRUDOps;

        xmlEntityMappings = new XMLEntityMappings();

        // initialize the various lists - some used, some not
        initializeXMLEntityMappingLists();
    }

    /**
     * XMLEntityMappings processing at runtime (i.e. PersistenceUnitProcessor.processORMetadata)
     * assumes that all lists are initialized.  We need to init all lists to avoid runtime
     * exceptions.
     *
     * @see org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings
     */
    protected void initializeXMLEntityMappingLists() {
        // Entities and Embeddables
        xmlEntityMappings.setEntities(new ArrayList<EntityAccessor>());
        xmlEntityMappings.setEmbeddables(new ArrayList<EmbeddableAccessor>());

        // PL/SQL and advanced Oracle types
        xmlEntityMappings.setPLSQLRecords(new ArrayList<PLSQLRecordMetadata>());
        xmlEntityMappings.setPLSQLTables(new ArrayList<PLSQLTableMetadata>());
        xmlEntityMappings.setOracleObjectTypes(new ArrayList<OracleObjectTypeMetadata>());
        xmlEntityMappings.setOracleArrayTypes(new ArrayList<OracleArrayTypeMetadata>());

        // queries
        xmlEntityMappings.setNamedNativeQueries(new ArrayList<NamedNativeQueryMetadata>());
        xmlEntityMappings.setNamedPLSQLStoredFunctionQueries(new ArrayList<NamedPLSQLStoredFunctionQueryMetadata>());
        xmlEntityMappings.setNamedPLSQLStoredProcedureQueries(new ArrayList<NamedPLSQLStoredProcedureQueryMetadata>());
        xmlEntityMappings.setNamedStoredFunctionQueries(new ArrayList<NamedStoredFunctionQueryMetadata>());
        xmlEntityMappings.setNamedStoredProcedureQueries(new ArrayList<NamedStoredProcedureQueryMetadata>());

        // initialize other various lists (to avoid exceptions)
        xmlEntityMappings.setMixedConverters(new ArrayList<MixedConverterMetadata>());
        xmlEntityMappings.setMappedSuperclasses(new ArrayList<MappedSuperclassAccessor>());
        xmlEntityMappings.setTenantDiscriminatorColumns(new ArrayList<TenantDiscriminatorColumnMetadata>());
        xmlEntityMappings.setTypeConverters(new ArrayList<TypeConverterMetadata>());
        xmlEntityMappings.setObjectTypeConverters(new ArrayList<ObjectTypeConverterMetadata>());
        xmlEntityMappings.setSerializedConverters(new ArrayList<SerializedConverterMetadata>());
        xmlEntityMappings.setStructConverters(new ArrayList<StructConverterMetadata>());
        xmlEntityMappings.setTableGenerators(new ArrayList<TableGeneratorMetadata>());
        xmlEntityMappings.setSequenceGenerators(new ArrayList<SequenceGeneratorMetadata>());
        xmlEntityMappings.setPartitioning(new ArrayList<PartitioningMetadata>());
        xmlEntityMappings.setReplicationPartitioning(new ArrayList<ReplicationPartitioningMetadata>());
        xmlEntityMappings.setRoundRobinPartitioning(new ArrayList<RoundRobinPartitioningMetadata>());
        xmlEntityMappings.setPinnedPartitioning(new ArrayList<PinnedPartitioningMetadata>());
        xmlEntityMappings.setRangePartitioning(new ArrayList<RangePartitioningMetadata>());
        xmlEntityMappings.setValuePartitioning(new ArrayList<ValuePartitioningMetadata>());
        xmlEntityMappings.setHashPartitioning(new ArrayList<HashPartitioningMetadata>());
        xmlEntityMappings.setNamedQueries(new ArrayList<NamedQueryMetadata>());
        xmlEntityMappings.setSqlResultSetMappings(new ArrayList<SQLResultSetMappingMetadata>());
    }

    /**
     * XMLAttributes processing at runtime (i.e. PersistenceUnitProcessor.processORMetadata)
     * assumes that all lists are initialized.  We need to init all lists to avoid runtime
     * exceptions.
     *
     * @see org.eclipse.persistence.internal.jpa.metadata.accessors.classes.XMLAttributes
     */
    protected void initializeXMLAttributeLists(ClassAccessor accessor) {
        accessor.setAttributes(new XMLAttributes());
        accessor.getAttributes().setIds(new ArrayList<IdAccessor>());
        accessor.getAttributes().setBasics(new ArrayList<BasicAccessor>());
        accessor.getAttributes().setArrays(new ArrayList<ArrayAccessor>());
        accessor.getAttributes().setStructures(new ArrayList<StructureAccessor>());
        accessor.getAttributes().setEmbeddeds(new ArrayList<EmbeddedAccessor>());

        // initialize other various lists (to avoid exceptions)
        accessor.getAttributes().setBasicCollections(new ArrayList<BasicCollectionAccessor>());
        accessor.getAttributes().setBasicMaps(new ArrayList<BasicMapAccessor>());
        accessor.getAttributes().setElementCollections(new ArrayList<ElementCollectionAccessor>());
        accessor.getAttributes().setManyToManys(new ArrayList<ManyToManyAccessor>());
        accessor.getAttributes().setManyToOnes(new ArrayList<ManyToOneAccessor>());
        accessor.getAttributes().setOneToManys(new ArrayList<OneToManyAccessor>());
        accessor.getAttributes().setOneToOnes(new ArrayList<OneToOneAccessor>());
        accessor.getAttributes().setTransformations(new ArrayList<TransformationAccessor>());
        accessor.getAttributes().setTransients(new ArrayList<TransientAccessor>());
        accessor.getAttributes().setVariableOneToOnes(new ArrayList<VariableOneToOneAccessor>());
        accessor.getAttributes().setVersions(new ArrayList<VersionAccessor>());
    }

    /**
     * Generate an XMLEntityMappings instance based on a given list of meta-model database types.
     *
     * @param databaseTypes the list of meta-model database types to be used to generate an XMLEntityMappings
     * @see org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType
     */
    public XMLEntityMappings generateXmlEntityMappings(List<CompositeDatabaseType> databaseTypes) {
        List<ProcedureType> procedures = new ArrayList<ProcedureType>();
        List<TableType> tables = new ArrayList<TableType>();

        // populate lists of TableTypes and ProcedureTypes
        for (CompositeDatabaseType dbType : databaseTypes) {
            if (dbType.isTableType()) {
                tables.add((TableType) dbType);
            } else if (dbType.isProcedureType()) {
                procedures.add((ProcedureType) dbType);
            }
        }

        // handle stored procedure overloading
        handleOverloading(procedures);

        // process TableTypes
        for (TableType table : tables) {
            EntityAccessor entity = processTableType(table);
            xmlEntityMappings.getEntities().add(entity);
        }
        // process ProcedureTypes
        for (ProcedureType procedure : procedures) {
            // PL/SQL stored procedures and functions will have a PLSQLPackageType as its parent
            PLSQLPackageType pkgType = procedure.getParentType();
            if (pkgType != null) {
                // handle PL/SQL
                if (procedure.isFunctionType()) {
                    xmlEntityMappings.getNamedPLSQLStoredFunctionQueries().add(processPLSQLFunctionType((FunctionType) procedure, pkgType));
                } else {
                    xmlEntityMappings.getNamedPLSQLStoredProcedureQueries().add(processPLSQLProcedureType(procedure, pkgType));
                }
            } else {
                // handle top-level (non-PL/SQL) functions and procedures
                if (procedure.isFunctionType()) {
                    xmlEntityMappings.getNamedStoredFunctionQueries().add(processFunctionType((FunctionType) procedure));
                } else {
                    xmlEntityMappings.getNamedStoredProcedureQueries().add(processProcedureType(procedure));
                }
            }
        }
        return xmlEntityMappings;
    }

    /**
     * Generate an EntityAccessor based on the given TableType.
     */
    protected EntityAccessor processTableType(TableType tType) {
        EntityAccessor entity = new EntityAccessor();
        entity.setAccess(EL_ACCESS_VIRTUAL);
        entity.setClassName(getEntityName(tType.getTableName(), defaultPackage));

        // initialize the various lists - some used, some not
        initializeXMLAttributeLists(entity);

        // set the table name on the entity
        TableMetadata table = new TableMetadata();
        table.setName(tType.getTableName());
        entity.setTable(table);

        // process the table columns
        for (FieldType fType : tType.getColumns()) {
            BasicAccessor attribute;
            // handle primary key
            if (fType.pk()) {
                attribute = new IdAccessor();
                entity.getAttributes().getIds().add((IdAccessor) attribute);
            } else {
                attribute = new BasicAccessor();
                entity.getAttributes().getBasics().add(attribute);
            }
            attribute.setName(fType.getFieldName().toLowerCase());
            attribute.setAttributeType(getAttributeTypeNameForFieldType(fType, dbPlatform));
           // set the column name
            ColumnMetadata column = new ColumnMetadata();
            column.setName(fType.getFieldName());
            attribute.setColumn(column);
        }
        // may need to generated NamedNativeQueryMetadata for CRUD operations
        generateCRUDMetadata(entity);

        return entity;
    }

    /**
     * Generate a stored function query based on the given FunctionType.
     */
    protected NamedStoredFunctionQueryMetadata processFunctionType(FunctionType fType) {
        NamedStoredFunctionQueryMetadata storedFunc = new NamedStoredFunctionQueryMetadata();
        storedFunc.setName(getQueryNameForProcedureType(fType));
        storedFunc.setProcedureName(fType.getProcedureName());
        // set the return parameter
        storedFunc.setReturnParameter(processArgument(fType.getReturnArgument()));
        // process the function's arguments
        if (fType.getArguments().size() > 0) {
            List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
            for (ArgumentType arg : fType.getArguments()) {
                params.add(processArgument(arg));
            }
            storedFunc.setParameters(params);
        }
        return storedFunc;
    }

    /**
     * Generate a stored procedure query based on the given ProcedureType.
     */
    protected NamedStoredProcedureQueryMetadata processProcedureType(ProcedureType pType) {
        NamedStoredProcedureQueryMetadata storedProc = new NamedStoredProcedureQueryMetadata();
        storedProc.setName(getQueryNameForProcedureType(pType));
        storedProc.setProcedureName(pType.getProcedureName());
        storedProc.setReturnsResultSet(false);
        // process the procedure's arguments
        if (pType.getArguments().size() > 0) {
            List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
            for (ArgumentType arg : pType.getArguments()) {
                params.add(processArgument(arg));
            }
            storedProc.setParameters(params);
        }
        return storedProc;
    }

    /**
     * Generate a PL/SQL stored function query based on the given FunctionType.
     */
    protected NamedPLSQLStoredFunctionQueryMetadata processPLSQLFunctionType(FunctionType fType, PLSQLPackageType pkgType) {
        NamedPLSQLStoredFunctionQueryMetadata storedFunc = new NamedPLSQLStoredFunctionQueryMetadata();
        storedFunc.setName(getQueryNameForProcedureType(fType));
        storedFunc.setProcedureName(pkgType.getPackageName() + DOT + fType.getProcedureName());
        List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
        // set the return parameter
        storedFunc.setReturnParameter(processPLSQLArgument(fType.getReturnArgument()));
        // process the function's arguments
        if (fType.getArguments().size() > 0) {
            for (ArgumentType arg : fType.getArguments()) {
                params.add(processPLSQLArgument(arg));
            }
        }
        storedFunc.setParameters(params);
        return storedFunc;
    }

    /**
     * Generate a PL/SQL stored procedure query based on the given ProcedureType.
     */
    protected NamedPLSQLStoredProcedureQueryMetadata processPLSQLProcedureType(ProcedureType pType, PLSQLPackageType pkgType) {
        NamedPLSQLStoredProcedureQueryMetadata storedProc = new NamedPLSQLStoredProcedureQueryMetadata();
        storedProc.setName(getQueryNameForProcedureType(pType));
        storedProc.setProcedureName(pkgType.getPackageName() + DOT + pType.getProcedureName());
        // process the procedure's arguments
        if (pType.getArguments().size() > 0) {
            List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
            for (ArgumentType arg : pType.getArguments()) {
                params.add(processPLSQLArgument(arg));
            }
            storedProc.setParameters(params);
        }
        return storedProc;
    }

    /**
     * Convenience method that returns a query name  for a given ProcedureType.
     * The name will be the procedureName value of the ProcedureType with
     * "_" + overload value if the ProcedureType's overload value is &gt; 0.
     *
     * For example, if the procedureName value is "P1" and overload == 0, "P1"
     * is returned.  If the procedureName value is "P1" and overload == 4,
     * "P1_4" is returned.
     */
    protected String getQueryNameForProcedureType(ProcedureType pType) {
        return pType.getOverload() == 0 ? pType.getProcedureName() : pType.getProcedureName() + UNDERSCORE + pType.getOverload();
    }

    /**
     * Generate a stored procedure parameter based on the given ArgumentType.
     * For PL/SQL arguments the processPLSQLArgument method should be used.
     */
    protected StoredProcedureParameterMetadata processArgument(ArgumentType arg) {
        StoredProcedureParameterMetadata param = new StoredProcedureParameterMetadata();
        param.setName(arg.getArgumentName());
        // don't set mode for stored function return argument
        if (arg.getDirection() != ArgumentTypeDirection.RETURN) {
            param.setMode(arg.getDirection().name());
        }
        if (!arg.isComposite()) {
            param.setTypeName(getClassNameFromJDBCTypeName(arg.getTypeName(), dbPlatform));
            param.setJdbcType(getJDBCTypeFromTypeName(arg.getTypeName()));
            param.setJdbcTypeName(getJDBCTypeName(arg.getTypeName()));
        } else {  // handle composites, i.e. Object, Varray, PL/SQL, etc.
            param.setTypeName(getGeneratedJavaClassName(arg.getTypeName(), defaultPackage));
            param.setJdbcTypeName(arg.getTypeName());
            if (arg.isObjectType()) {  // ObjectType
                param.setJdbcType(Types.STRUCT);
            } else if (arg.isObjectTableType() || arg.isVArrayType()) {  // ObjectTable and Varray
                param.setJdbcType(Types.ARRAY);
            }
            processCompositeType(arg.getEnclosedType());
        }
        return param;
    }

    /**
     * Generate a PL/SQL parameter based on the given ArgumentType. For
     * non-PL/SQL arguments the processArgument method should be used.
     */
    protected PLSQLParameterMetadata processPLSQLArgument(ArgumentType arg) {
        // for %ROWTYPE, we need to create a PL/SQL record that mirrors the Table
        if (arg.getEnclosedType().isROWTYPEType()) {
            ROWTYPEType rType = (ROWTYPEType) arg.getEnclosedType();
            TableType tableType = (TableType) rType.getEnclosedType();
            PLSQLRecordType plsqlRec = new PLSQLRecordType(rType.getTypeName());
            plsqlRec.setParentType(new PLSQLPackageType());
            for (FieldType col : tableType.getColumns()) {
                FieldType ft = new FieldType(col.getFieldName());
                ft.setEnclosedType(col.getEnclosedType());
                plsqlRec.addField(ft);
            }
            arg.setEnclosedType(plsqlRec);
        }

        PLSQLParameterMetadata param = new PLSQLParameterMetadata();
        // handle cursor
        if (arg.isPLSQLCursorType()) {
            param.setDirection(OUT_CURSOR_STR);
        }
        // handle stored function return type
        if (arg.getDirection() == ArgumentTypeDirection.RETURN) {
            param.setName(arg.isPLSQLCursorType() ? CURSOR_STR : RESULT_STR);
        } else {
            // direction is already set for cursor type
            if (!arg.isPLSQLCursorType()) {
                param.setDirection(arg.getDirection().name());
            }
            param.setName(arg.getArgumentName());
        }

        String dbType = arg.getTypeName();
        // handle composites
        if (arg.isComposite()) {
            DatabaseType enclosedType = arg.getEnclosedType();
            // need to prepend the package name for most PL/SQL and Cursor types
            if (enclosedType.isPLSQLType() || enclosedType.isPLSQLCursorType()) {
                dbType = getQualifiedTypeName(enclosedType);
            }
            // process the composite enclosed type
            processCompositeType(enclosedType, dbType);
        }
        param.setDatabaseType(processTypeName(dbType));
        return param;
    }

    /**
     * Generate object type metadata based on the given ObjectType.
     */
    protected OracleObjectTypeMetadata processObjectType(ObjectType oType) {
        OracleObjectTypeMetadata objectType = new OracleObjectTypeMetadata();
        objectType.setName(oType.getTypeName());
        objectType.setJavaType(getGeneratedJavaClassName(oType.getTypeName(), defaultPackage));
        // process the object type's fields
        List<PLSQLParameterMetadata> fields = new ArrayList<PLSQLParameterMetadata>();
        for (FieldType ft : oType.getFields()) {
            PLSQLParameterMetadata fieldMetadata = new PLSQLParameterMetadata();
            fieldMetadata.setName(ft.getFieldName());
            fieldMetadata.setDatabaseType(processTypeName(ft.getTypeName()));
            fields.add(fieldMetadata);
            if (ft.isComposite()) {
                processCompositeType(ft.getEnclosedType());
            }
        }
        objectType.setFields(fields);

        // avoid double-processing
        getProcessedTypes().add(objectType.getName());

        // generate an EmbeddableAccessor for this type
        generateEmbeddable(objectType, oType);

        return objectType;
    }

    /**
     * Generate array type metadata based on the given VArray or ObjectTable type.
     */
    protected OracleArrayTypeMetadata processArrayType(DatabaseType dbType) {
        OracleArrayTypeMetadata arrayType = new OracleArrayTypeMetadata();
        arrayType.setName(dbType.getTypeName());
        arrayType.setJavaType(getGeneratedJavaClassName(dbType.getTypeName(), defaultPackage));
        if (dbType.isVArrayType()) {
            arrayType.setNestedType(processTypeName(((VArrayType) dbType).getEnclosedType().getTypeName()));
        } else {
            // assumes ObjectTable
            arrayType.setNestedType(((ObjectTableType) dbType).getEnclosedType().getTypeName());
        }
        // avoid double-processing
        getProcessedTypes().add(arrayType.getName());

        // generate an EmbeddableAccessor for this type
        generateEmbeddable(arrayType, (CompositeDatabaseTypeWithEnclosedType) dbType);

        return arrayType;
    }

    /**
     * Process the given PLSQLCollectionType and return a PLSQLTableMetadata instance.
     *
     */
    protected PLSQLTableMetadata processPLSQLCollectionType(PLSQLCollectionType plsqlCollectionType) {
        String typeName = getQualifiedTypeName(plsqlCollectionType);
        String compatiableName = getQualifiedCompatibleTypeName(plsqlCollectionType);
        String targetClassName = compatiableName;

        PLSQLTableMetadata plsqlTable = new PLSQLTableMetadata();
        plsqlTable.setName(typeName);
        plsqlTable.setCompatibleType(compatiableName);
        plsqlTable.setJavaType(getGeneratedJavaClassName(typeName));

        // handle Nested Table (i.e. non-Varray)
        plsqlTable.setNestedTable(!plsqlCollectionType.isIndexed());
        String dbType = plsqlCollectionType.getEnclosedType().getTypeName();
        if (!(getJDBCTypeFromTypeName(dbType) == Types.OTHER)) {
            // need special handling for nested PL/SQL scalar types
            if (isArgPLSQLScalar(dbType)) {
                plsqlTable.setNestedType(getOraclePLSQLTypeForName(dbType));
            } else {
                plsqlTable.setNestedType(processTypeName(dbType));
            }
        } else {
            if (plsqlCollectionType.isComposite()) {
                DatabaseType enclosedType = plsqlCollectionType.getEnclosedType();
                // may need to prepend package name
                if (enclosedType.isPLSQLType()) {
                    dbType = ((PLSQLType) enclosedType).getParentType().getPackageName() + DOT + dbType;
                    targetClassName = getGeneratedJavaClassName(dbType);
                } else {
                    // advanced JDBC
                    targetClassName = getGeneratedJavaClassName(dbType, defaultPackage);
                }
                processCompositeType(enclosedType, dbType);
            }
            plsqlTable.setNestedType(dbType);
        }
        // avoid double-processing
        getProcessedTypes().add(plsqlTable.getName());

        // generate an EmbeddableAccessor for this type
        generateEmbeddable(plsqlTable, targetClassName);

        return plsqlTable;
    }

    /**
     * Process the given PLSQLRecordType and return a PLSQLRecordMetadata instance.
     *
     */
    protected PLSQLRecordMetadata processPLSQLRecordType(PLSQLRecordType plsqlRecordType) {
        // for %ROWTYPE we create a 'place holder' PL/SQL Record - in this case there is no package name
        String typeName = getQualifiedTypeName(plsqlRecordType);
        String compatibleName = getQualifiedCompatibleTypeName(plsqlRecordType);
        if (compatibleName.contains(PERCENT)) {
            compatibleName = compatibleName.replace(PERCENT, UNDERSCORE);
        }

        PLSQLRecordMetadata plsqlRecord = new PLSQLRecordMetadata();
        plsqlRecord.setName(typeName);
        plsqlRecord.setCompatibleType(compatibleName);
        if (typeName.endsWith(ROWTYPE_STR)) {
            plsqlRecord.setJavaType(getGeneratedJavaClassName(compatibleName));
        } else {
            plsqlRecord.setJavaType(getGeneratedJavaClassName(typeName));
        }

        List<PLSQLParameterMetadata> fields = new ArrayList<PLSQLParameterMetadata>();
        PLSQLParameterMetadata field;
        for (FieldType fld : plsqlRecordType.getFields()) {
            field = new PLSQLParameterMetadata();
            field.setName(fld.getFieldName());
            String dbType = processTypeName(fld.getTypeName());
            if (fld.isComposite()) {
                DatabaseType enclosedType = fld.getEnclosedType();
                // may need to prepend package name
                if (enclosedType.isPLSQLType()) {
                    dbType = ((PLSQLType) fld.getEnclosedType()).getParentType().getPackageName() + DOT + dbType;
                }
                processCompositeType(enclosedType, dbType);
            }
            field.setDatabaseType(dbType);
            fields.add(field);
        }
        plsqlRecord.setFields(fields);

        // avoid double-processing
        getProcessedTypes().add(plsqlRecord.getName());

        // generate an EmbeddableAccessor for this type
        generateEmbeddable(plsqlRecord, plsqlRecordType);

        return plsqlRecord;
    }

    /**
     * Process the given composite database type.
     */
    protected void processCompositeType(DatabaseType compositeType) {
        processCompositeType(compositeType, compositeType.getTypeName());
    }
    /**
     * Process the given composite database type.  For PL/SQL types, typeName will be
     * the fully qualified type name (i.e. packagename.typename).  The type should
     * be one of:  PLSQLCollection, PLSQLRecord, Object, ObjectTable, or Varray.
     */
    protected void processCompositeType(DatabaseType compositeType, String typeName) {
        // avoid double-processing of records & collections, objects and arrays
        if (!alreadyProcessed(typeName)) {
            if (compositeType.isPLSQLCollectionType()) {
                xmlEntityMappings.getPLSQLTables().add(processPLSQLCollectionType((PLSQLCollectionType) compositeType));
            } else if (compositeType.isPLSQLRecordType()) {
                xmlEntityMappings.getPLSQLRecords().add(processPLSQLRecordType((PLSQLRecordType) compositeType));
            } else if (compositeType.isObjectType()) {
                xmlEntityMappings.getOracleObjectTypes().add(processObjectType((ObjectType) compositeType));
            } else if (compositeType.isObjectTableType() || compositeType.isVArrayType()) {
                xmlEntityMappings.getOracleArrayTypes().add(processArrayType(compositeType));
            }
        }
    }

    /**
     * Generate an Embeddable for the given PLSQLTableMetadata, and add
     * it to the list of Embeddables on the XMLEntityMappings instance.
     *
     * @param tableMetadata PLSQLTableMetadata used to build the Embeddable
     */
    protected void generateEmbeddable(PLSQLTableMetadata tableMetadata, String targetClassName) {
        // avoid double-processing
        if (!embeddableAlreadyProcessed(tableMetadata.getJavaType())) {
            EmbeddableAccessor embeddable = initEmbeddable(tableMetadata.getJavaType());

            ArrayAccessor array = generateArrayAccessor(ITEMS_FLD_STR, ITEMS_COL_STR, tableMetadata.getCompatibleType(), targetClassName);
            embeddable.getAttributes().getArrays().add(array);

            // set on the XMLEntityMappings instance
            xmlEntityMappings.getEmbeddables().add(embeddable);

            // track to avoid double processing
            getGeneratedEmbeddables().add(tableMetadata.getJavaType());
        }
    }

    /**
     * Generate an Embeddable for the given PLSQLRecordMetadata and PLSQLRecordType,
     * and add it to the list of Embeddables on the XMLEntityMappings instance.
     *
     * @param recordMetadata PLSQLRecordMetadata used to build the Embeddable
     * @param recordType PLSQLRecordType used to build the Embeddable
     */
    protected void generateEmbeddable(PLSQLRecordMetadata recordMetadata, PLSQLRecordType recordType) {
        // avoid double-processing
        if (!embeddableAlreadyProcessed(recordMetadata.getJavaType())) {
            EmbeddableAccessor embeddable = initEmbeddable(recordMetadata.getJavaType());

            // add a struct to satisfy field ordering
            StructMetadata struct = new StructMetadata();
            struct.setName(recordMetadata.getCompatibleType());
            List<String> fields = new ArrayList<String>();
            for (PLSQLParameterMetadata fld : recordMetadata.getFields()) {
                fields.add(fld.getName());
            }
            struct.setFields(fields);
            embeddable.setStruct(struct);

            // add an attribute to the embeddable for each of the record's fields
            addEmbeddableAttributes(embeddable, recordType.getFields());

            // set on the XMLEntityMappings instance
            xmlEntityMappings.getEmbeddables().add(embeddable);

            // track to avoid double processing
            getGeneratedEmbeddables().add(recordMetadata.getJavaType());
        }
    }

    /**
     * Generate an Embeddable for the given OracleArrayTypeMetadata, and add
     * it to the list of Embeddables on the XMLEntityMappings instance.
     */
    protected void generateEmbeddable(OracleArrayTypeMetadata arrayTypeMetadata, CompositeDatabaseTypeWithEnclosedType dbType) {
        // avoid double-processing
        if (!embeddableAlreadyProcessed(arrayTypeMetadata.getJavaType())) {
            EmbeddableAccessor embeddable = initEmbeddable(arrayTypeMetadata.getJavaType());

            ArrayAccessor array;
            if (dbType.getEnclosedType().isComposite()) {
                array = generateArrayAccessor(ITEMS_FLD_STR, ITEMS_COL_STR, arrayTypeMetadata.getNestedType(),
                        getGeneratedJavaClassName(arrayTypeMetadata.getNestedType(), defaultPackage));
            } else {
                array = generateArrayAccessor(ITEMS_FLD_STR, ITEMS_COL_STR, dbType.getEnclosedType().getTypeName());
            }

            embeddable.getAttributes().getArrays().add(array);

            // set on the XMLEntityMappings instance
            xmlEntityMappings.getEmbeddables().add(embeddable);

            // track to avoid double processing
            getGeneratedEmbeddables().add(arrayTypeMetadata.getJavaType());
        }
    }

    /**
     * Generate an Embeddable for the given OracleObjectTypeMetadata, and add
     * it to the list of Embeddables on the XMLEntityMappings instance.
     */
    protected void generateEmbeddable(OracleObjectTypeMetadata objectTypeMetadata, ObjectType objectType) {
        // avoid double-processing
        if (!embeddableAlreadyProcessed(objectTypeMetadata.getJavaType())) {
            EmbeddableAccessor embeddable = initEmbeddable(objectTypeMetadata.getJavaType());

            // add a struct to satisfy field ordering
            StructMetadata struct = new StructMetadata();
            struct.setName(objectTypeMetadata.getName());
            List<String> fields = new ArrayList<String>();
            for (PLSQLParameterMetadata fld : objectTypeMetadata.getFields()) {
                fields.add(fld.getName());
            }
            struct.setFields(fields);
            embeddable.setStruct(struct);

            // add an attribute to the embeddable for each of the object's fields
            addEmbeddableAttributes(embeddable, objectType.getFields());

            // set on the XMLEntityMappings instance
            xmlEntityMappings.getEmbeddables().add(embeddable);

            // track to avoid double processing
            getGeneratedEmbeddables().add(objectTypeMetadata.getJavaType());
        }
    }

    /**
     * Convenience method that creates and EmbeddableAccessor, setting the class name to the
     * provided embeddableClassName, initializes the various lists (Basics, Arrays, etc.),
     * and sets the access type to 'VIRTUAL'.
     */
    protected EmbeddableAccessor initEmbeddable(String embeddableClassName) {
        EmbeddableAccessor embeddable = new EmbeddableAccessor();
        embeddable.setClassName(embeddableClassName);
        embeddable.setAccess(EL_ACCESS_VIRTUAL);

        // initialize the various lists - some used, some not
        initializeXMLAttributeLists(embeddable);
        return embeddable;
    }

    /**
     * Process a list of FieldTypes, creating an attribute for each - the created
     * XMLAttributes are set on the given EmbeddableAccessor.
     *
     * @see org.eclipse.persistence.internal.jpa.metadata.accessors.classes.XMLAttributes
     */
    protected void addEmbeddableAttributes(EmbeddableAccessor embeddable, List<FieldType> fields) {
        for (FieldType fld : fields) {
            DatabaseType enclosedType = fld.getEnclosedType();
            if (!enclosedType.isComposite() || enclosedType.isTYPEType()) {  // basic
                String typeName = enclosedType.isTYPEType() ? enclosedType.getTypeName() : fld.getTypeName();
                BasicAccessor basic = generateBasicAccessor(fld.getFieldName().toLowerCase(), fld.getFieldName(), getClassNameFromJDBCTypeName(typeName, dbPlatform));
                embeddable.getAttributes().getBasics().add(basic);
            } else if (enclosedType.isPLSQLType()) {  // record or collection
                PLSQLType plsqlType = (PLSQLType) enclosedType;
                String typeName = getQualifiedTypeName(plsqlType);
                EmbeddedAccessor embedded = new EmbeddedAccessor();
                embedded.setName(fld.getFieldName().toLowerCase());
                embedded.setAttributeType(getGeneratedJavaClassName(typeName));
                embeddable.getAttributes().getEmbeddeds().add(embedded);
            } else if (enclosedType.isVArrayType() || enclosedType.isObjectTableType()) {  // array
                ArrayAccessor array = null;
                // target class is reference class name for Object Table, and structure name for Varray
                if (enclosedType.isVArrayType()) {
                    array = generateArrayAccessor(fld.getFieldName().toLowerCase(), fld.getFieldName(), enclosedType.getTypeName());
                } else {
                    ObjectTableType otType = (ObjectTableType) enclosedType;
                    array = generateArrayAccessor(fld.getFieldName().toLowerCase(), fld.getFieldName(), otType.getEnclosedType().getTypeName(),
                            getGeneratedJavaClassName(otType.getEnclosedType().getTypeName(), defaultPackage));
                }
                embeddable.getAttributes().getArrays().add(array);
            } else if (enclosedType.isObjectType()) {  // struct
                StructureAccessor structure = generateStructureAccessor(fld.getFieldName().toLowerCase(), fld.getFieldName(),
                        getGeneratedJavaClassName(enclosedType.getTypeName(), defaultPackage));
                embeddable.getAttributes().getStructures().add(structure);
            } else if (enclosedType.isTYPEType()) {
                TYPEType tType = (TYPEType) enclosedType;
                BasicAccessor basic = generateBasicAccessor(fld.getFieldName().toLowerCase(), fld.getFieldName(), getClassNameFromJDBCTypeName(tType.getTypeName(), dbPlatform));
                embeddable.getAttributes().getBasics().add(basic);
            }
        }
    }

    /**
     * Returns an ArrayAccessor instance, constructed based on the given String values.  This method
     * can be used when the database type and target class names are the same.
     *
     */
    protected ArrayAccessor generateArrayAccessor(String arrayName, String columnName, String databaseTypeName) {
        return generateArrayAccessor(arrayName, columnName, databaseTypeName, databaseTypeName);
    }

    /**
     * Returns an ArrayAccessor instance, constructed based on the given String values.
     */
    protected ArrayAccessor generateArrayAccessor(String arrayName, String columnName, String databaseTypeName, String targetClassName) {
        ArrayAccessor array = new ArrayAccessor();
        array.setName(arrayName);
        array.setAttributeType(ARRAYLIST_CLS_STR);
        array.setDatabaseType(databaseTypeName);
        array.setTargetClassName(targetClassName);
        ColumnMetadata column = new ColumnMetadata();
        column.setName(columnName);
        array.setColumn(column);
        return array;
    }

    /**
     * Returns a BasicAccessor instance, constructed based on the given String values.
     */
    protected BasicAccessor generateBasicAccessor(String basicName, String columnName, String attributeTypeName) {
        BasicAccessor basic = new BasicAccessor();
        basic.setName(basicName);
        basic.setAttributeType(attributeTypeName);

        ColumnMetadata column = new ColumnMetadata();
        column.setName(columnName);
        basic.setColumn(column);
        return basic;
    }

    /**
     * Returns a StructureAccessor instance, constructed based on the given String values.  This method can be used
     * when the attribute type and target class names are the same.
     */
    protected StructureAccessor generateStructureAccessor(String structureName, String columnName, String attributeTypeName) {
        return generateStructureAccessor(structureName, columnName, attributeTypeName, attributeTypeName);
    }

    /**
     * Returns a StructureAccessor instance, constructed based on the given String values.
     */
    protected StructureAccessor generateStructureAccessor(String structureName, String columnName, String attributeTypeName, String targetClassName) {
        StructureAccessor structure = new StructureAccessor();
        structure.setName(structureName);
        structure.setAttributeType(attributeTypeName);
        structure.setTargetClassName(targetClassName);
        ColumnMetadata column = new ColumnMetadata();
        column.setName(columnName);
        structure.setColumn(column);
        return structure;
    }

    /**
     * Generates NamedNativeQueryMetadata for CRUD operations (create,
     * findAll, findByPk, update and delete) for a given Entity if
     * required, i.e. generateCRUDOps is true.
     */
    protected void generateCRUDMetadata(EntityAccessor entity) {
        if (generateCRUDOps) {
            // don't blow away the Entity's query metadata
            if (entity.getNamedNativeQueries() == null) {
                entity.setNamedNativeQueries(new ArrayList<NamedNativeQueryMetadata>());
            }

            String tableName = entity.getTable().getName();
            String entityType = getUnqualifiedEntityName(tableName) + TYPE_STR;

            List<IdAccessor> ids = entity.getAttributes().getIds();
            List<BasicAccessor> basics = entity.getAttributes().getBasics();

            // list of all mappings (ids and basics)
            List<MappingAccessor> mappings = new ArrayList<MappingAccessor>();
            mappings.addAll(ids);
            mappings.addAll(basics);

            // process primary keys
            String pks = null;
            int pkCount = 0;
            for (IdAccessor pk : ids) {
                if (pkCount++ == 0) {
                    pks = OPEN_BRACKET + pk.getName().toUpperCase() + EQUALS_BINDING1_STR;
                } else {
                    pks = pks.concat(AND_STR + pk.getName().toUpperCase() + EQUALS_BINDING_STR + pkCount++);
                }
            }
            if (pks != null) {
                pks = pks.concat(CLOSE_BRACKET);
            }

            // find by PK
            NamedNativeQueryMetadata crudQuery = new NamedNativeQueryMetadata();
            crudQuery.setName(PK_QUERYNAME + UNDERSCORE + entityType);
            crudQuery.setQuery(SELECT_FROM_STR + tableName + WHERE_STR + pks);
            crudQuery.setResultClassName(entity.getClassName());
            entity.getNamedNativeQueries().add(crudQuery);

            // find all
            crudQuery = new NamedNativeQueryMetadata();
            crudQuery.setName(ALL_QUERYNAME + UNDERSCORE + entityType);
            crudQuery.setQuery(SELECT_FROM_STR + tableName);
            crudQuery.setResultClassName(entity.getClassName());
            entity.getNamedNativeQueries().add(crudQuery);
            // create
            StringBuilder sqlStmt = new StringBuilder(128);
            sqlStmt.append(INSERT_STR).append(tableName).append(SINGLE_SPACE).append(OPEN_BRACKET);
            MetadataHelper.buildColsFromMappings(sqlStmt, mappings, COMMA_SPACE_STR);
            sqlStmt.append(CLOSE_BRACKET).append(VALUES_STR).append(OPEN_BRACKET);
            MetadataHelper.buildValuesAsQMarksFromMappings(sqlStmt, mappings, COMMA_SPACE_STR);
            sqlStmt.append(CLOSE_BRACKET);

            crudQuery = new NamedNativeQueryMetadata();
            crudQuery.setName(CREATE_OPERATION_NAME + UNDERSCORE + entityType);
            crudQuery.setQuery(sqlStmt.toString());
            entity.getNamedNativeQueries().add(crudQuery);

            // update
            sqlStmt = new StringBuilder(128);
            sqlStmt.append(UPDATE_STR).append(tableName).append(SET_STR);
            MetadataHelper.buildColsAndValuesBindingsFromMappings(sqlStmt, basics,
                    pkCount, EQUALS_BINDING_STR, COMMA_SPACE_STR);
            sqlStmt.append(WHERE_STR).append(pks);

            crudQuery = new NamedNativeQueryMetadata();
            crudQuery.setName(UPDATE_OPERATION_NAME + UNDERSCORE + entityType);
            crudQuery.setQuery(sqlStmt.toString());
            entity.getNamedNativeQueries().add(crudQuery);

            // delete
            crudQuery = new NamedNativeQueryMetadata();
            crudQuery.setName(REMOVE_OPERATION_NAME + UNDERSCORE + entityType);
            crudQuery.setQuery(DELETE_STR + tableName + WHERE_STR + pks);
            entity.getNamedNativeQueries().add(crudQuery);
        }
    }

    /**
     * If set to true, NamedNativeQueryMetadata for CRUD operations (create, findAll, findByPk,
     * update and delete) will be generated for each Entity.  The default is false.
     *
     */
    protected void setGenerateCRUDOps(boolean generateCRUDOps) {
        this.generateCRUDOps = generateCRUDOps;
    }

    /**
     * Lazy-load the List of processed composite types.
     */
    protected List<String> getProcessedTypes() {
        if (processedTypes == null) {
            processedTypes = new ArrayList<String>();
        }
        return processedTypes;
    }
    /**
     * Lazy-load the List of embeddables.
     */
    protected List<String> getGeneratedEmbeddables() {
        if (generatedEmbeddables == null) {
            generatedEmbeddables = new ArrayList<String>();
        }
        return generatedEmbeddables;
    }

    /**
     * Indicates if an embeddable has already been processed - the list of
     * generated embeddable names will be checked for the given typeName.
     */
    protected boolean embeddableAlreadyProcessed(String embeddableName) {
        return generatedEmbeddables != null && generatedEmbeddables.size() > 0 && generatedEmbeddables.contains(embeddableName);
    }

    /**
     * Indicates if a type has already been processed - the list of
     * processed type names will be checked for the given typeName.
     */
    protected boolean alreadyProcessed(String typeName) {
        return processedTypes != null && processedTypes.size() > 0 && processedTypes.contains(typeName);
    }

    /**
     * Attempt to load the DatabasePlatform using the given platform class name.  If the
     * platform cannot be loaded Oracle11Platform will be returned - if available.
     *
     * @param platformClassName class name of the DatabasePlatform to be loaded
     * @return DatabasePlatform loaded for the given platformClassname, or Oracle11Platform if not found
     * @see "org.eclipse.persistence.platform.database.oracle.Oracle11Platform"
     */
    public static DatabasePlatform loadDatabasePlatform(String platformClassName) {
        DatabasePlatform dbPlatform = null;
        Class<?> platformClass = null;
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                platformClass = AccessController.doPrivileged(new PrivilegedClassForName<>(platformClassName));
            } else {
                platformClass = PrivilegedAccessHelper.getClassForName(platformClassName);
            }
            dbPlatform = (DatabasePlatform) Helper.getInstanceFromClass(platformClass);
        } catch (PrivilegedActionException | ClassNotFoundException | NullPointerException e) {
            try {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    platformClass = AccessController.doPrivileged(new PrivilegedClassForName<>(DEFAULT_PLATFORM));
                } else {
                    platformClass = PrivilegedAccessHelper.getClassForName(DEFAULT_PLATFORM);
                }
                dbPlatform = (DatabasePlatform) Helper.getInstanceFromClass(platformClass);
            } catch (PrivilegedActionException | ClassNotFoundException ex) {
                // at this point we can't load the default Oracle11Platform, so null will be returned
            }
        }
        return dbPlatform;
    }
}
