/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     David McCann - 2.5.0 - Sept.18, 2012 - Initial Implementation
 ******************************************************************************/
package org.eclipse.persistence.tools.dbws;

import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.config.HintValues;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.internal.helper.DatabaseField;
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.XMLAttributes;
import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor;
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.MappingAccessor;
import org.eclipse.persistence.internal.jpa.metadata.columns.ColumnMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.ComplexTypeMetadata;
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.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.OracleComplexTypeMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.OracleObjectTypeMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.PLSQLComplexTypeMetadata;
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.QueryHintMetadata;
import org.eclipse.persistence.internal.jpa.metadata.queries.StoredProcedureParameterMetadata;
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.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
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.platform.database.oracle.plsql.OraclePLSQLTypes;
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.queries.DatabaseQuery;
import org.eclipse.persistence.queries.StoredFunctionCall;
import org.eclipse.persistence.queries.StoredProcedureCall;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
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.PLSQLRecordType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType;

import static org.eclipse.persistence.internal.databaseaccess.DatasourceCall.IN;
import static org.eclipse.persistence.internal.databaseaccess.DatasourceCall.INOUT;
import static org.eclipse.persistence.internal.databaseaccess.DatasourceCall.OUT;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.EL_ACCESS_VIRTUAL;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_IN;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_INOUT;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_OUT;
import static org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_REF_CURSOR;
import static org.eclipse.persistence.internal.xr.XRDynamicClassLoader.COLLECTION_WRAPPER_SUFFIX;
import static org.eclipse.persistence.platform.database.oracle.plsql.OraclePLSQLTypes.PLSQLBoolean;
import static org.eclipse.persistence.platform.database.oracle.plsql.OraclePLSQLTypes.XMLType;
import static org.eclipse.persistence.tools.dbws.Util._TYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.BOOLEAN_STR;
import static org.eclipse.persistence.tools.dbws.Util.DOT;
import static org.eclipse.persistence.tools.dbws.Util.PERCENT;
import static org.eclipse.persistence.tools.dbws.Util.ROWTYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.UNDERSCORE;
import static org.eclipse.persistence.tools.dbws.Util.VARCHAR_STR;
import static org.eclipse.persistence.tools.dbws.Util.VARCHAR2_STR;
import static org.eclipse.persistence.tools.dbws.Util.XMLTYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.getGeneratedAlias;
import static org.eclipse.persistence.tools.dbws.Util.getJDBCTypeFromTypeName;
import static org.eclipse.persistence.tools.dbws.Util.getOraclePLSQLTypeForName;
import static org.eclipse.persistence.tools.dbws.Util.isArgPLSQLScalar;

/**
 * This class is responsible for generating an XMLEntityMappings instance based
 * on a given OR Project's Queries and Descriptors.
 * 
 */
public class XmlEntityMappingsGenerator {
    static final String IN_STR = "IN";
    static final String INOUT_STR = "IN_OUT";
    static final String OUT_STR = "OUT";
    static final String CURSOR_STR = "OUT_CURSOR";

    static final String ARRAYLIST_STR = "java.util.ArrayList";
    static final String STRING_STR = "java.lang.String";
    
    /**
     * Generate an XMLEntityMappings instance based on a given OR Project's Queries and Descriptors.
     * 
     * @param orProject the ORM Project instance containing Queries and Descriptors to be used to generate an XMLEntityMappings
     * @param complexTypes list of composite database types used to generate metadata for advanced Oracle and PL/SQL types
     * @param crudOperations map of maps keyed on table name - the second map are operation name to SQL string entries
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static XMLEntityMappings generateXmlEntityMappings(Project orProject, List<CompositeDatabaseType> complexTypes, Map<String, Map<String, String>> crudOperations) {
        List<ClassDescriptor> descriptors = orProject.getOrderedDescriptors();
        List<DatabaseQuery> queries = orProject.getQueries();
        
        XMLEntityMappings xmlEntityMappings = new XMLEntityMappings();
        xmlEntityMappings.setEmbeddables(new ArrayList<EmbeddableAccessor>());
        xmlEntityMappings.setEntities(new ArrayList<EntityAccessor>());

        xmlEntityMappings.setPLSQLRecords(new ArrayList<PLSQLRecordMetadata>());
        xmlEntityMappings.setPLSQLTables(new ArrayList<PLSQLTableMetadata>());
        xmlEntityMappings.setOracleObjectTypes(new ArrayList<OracleObjectTypeMetadata>());
        xmlEntityMappings.setOracleArrayTypes(new ArrayList<OracleArrayTypeMetadata>());

        // process PL/SQL records and collections, and Oracle advanced JDBC types
        List<PLSQLRecordMetadata> plsqlRecords = null;
        List<PLSQLTableMetadata>  plsqlTables  = null;
        List<OracleObjectTypeMetadata> objectTypes = null;
        List<OracleArrayTypeMetadata> arrayTypes = null;
        
        // generate metadata for each of the composite types
        List<ComplexTypeMetadata> complexTypeMetadata = processCompositeTypes(complexTypes, orProject);
        for (ComplexTypeMetadata cTypeMetadata : complexTypeMetadata) {
            if (cTypeMetadata.isOracleComplexTypeMetadata()) {
                OracleComplexTypeMetadata octMetadata = (OracleComplexTypeMetadata) cTypeMetadata;
                if (octMetadata.isOracleArrayTypeMetadata()) {
                    if (arrayTypes == null) {
                        arrayTypes = new ArrayList<OracleArrayTypeMetadata>();
                    }
                    arrayTypes.add((OracleArrayTypeMetadata) octMetadata);
                } else {
                    // assumes OracleObjectTypeMetadata
                    if (objectTypes == null) {
                        objectTypes = new ArrayList<OracleObjectTypeMetadata>();
                    }
                    objectTypes.add((OracleObjectTypeMetadata) octMetadata);
                }                
            } else {
                // assumes PL/SQL complex type metadata
                PLSQLComplexTypeMetadata plsqlctMetadata = (PLSQLComplexTypeMetadata) cTypeMetadata;
                if (plsqlctMetadata.isPLSQLRecordMetadata()) {
                    if (plsqlRecords == null) {
                        plsqlRecords = new ArrayList<PLSQLRecordMetadata>();
                    }
                    plsqlRecords.add((PLSQLRecordMetadata) plsqlctMetadata);
                } else {
                    // assumes PLSQLTableMetadata
                    if (plsqlTables == null) {
                        plsqlTables  = new ArrayList<PLSQLTableMetadata>();
                    }
                    plsqlTables.add((PLSQLTableMetadata) plsqlctMetadata);
                }
            }
        }
        // add generated metadata
        xmlEntityMappings.setPLSQLRecords(plsqlRecords);
        xmlEntityMappings.setPLSQLTables(plsqlTables);
        xmlEntityMappings.setOracleObjectTypes(objectTypes);
        xmlEntityMappings.setOracleArrayTypes(arrayTypes);
        
        // process stored procedures/functions
        List<NamedPLSQLStoredProcedureQueryMetadata> plsqlStoredProcs = null;
        List<NamedPLSQLStoredFunctionQueryMetadata> plsqlStoredFuncs = null;
        List<NamedStoredProcedureQueryMetadata> storedProcs = null;
        List<NamedStoredFunctionQueryMetadata> storedFuncs = null;
        List<NamedNativeQueryMetadata> namedNativeQueries = null;

        // process database queries set on the descriptor
        for (DatabaseQuery query : queries) {
            if (query.getCall().isStoredFunctionCall()) {
                if (query.getCall() instanceof PLSQLStoredFunctionCall) {
                    PLSQLStoredFunctionCall call = (PLSQLStoredFunctionCall)query.getCall();
                    NamedPLSQLStoredFunctionQueryMetadata metadata = new NamedPLSQLStoredFunctionQueryMetadata();
                    
                    metadata.setName(query.getName());
                    metadata.setProcedureName(call.getProcedureName());
                    
                    List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
                    if (plsqlStoredFuncs == null) {
                        plsqlStoredFuncs = new ArrayList<NamedPLSQLStoredFunctionQueryMetadata>();
                    }

                    PLSQLargument arg;
                    PLSQLParameterMetadata param;
                    List<PLSQLargument> types = call.getArguments();
                    for (int i=0; i < types.size(); i++) {
                        arg = types.get(i);
                        param = new PLSQLParameterMetadata();
                        param.setName(arg.name);
                        String dbType = arg.databaseType.getTypeName();

                        if (arg.databaseType == XMLType) {
                            dbType = XMLType.name();
                        } else if (arg.databaseType == PLSQLBoolean) {
                        	dbType = PLSQLBoolean.name();
                        } else {
                            if (!(getJDBCTypeFromTypeName(dbType) == Types.OTHER)) {
                                dbType = dbType.concat(_TYPE_STR);
                            }
                        }
                        param.setDatabaseType(dbType);
                        if (i == 0) {
                            // first arg is the return arg
                            metadata.setReturnParameter(param);
                            if (arg.cursorOutput) {
                                param.setDirection(CURSOR_STR);
                            }
                        } else {
                            param.setDirection(getDirectionAsString(arg.direction));
                            params.add(param);
                        }
                    }
                    if (params.size() > 0) {
                        metadata.setParameters(params);
                    }
                    plsqlStoredFuncs.add(metadata);
                } else {
                    StoredFunctionCall call = (StoredFunctionCall)query.getCall();
                    NamedStoredFunctionQueryMetadata metadata = new NamedStoredFunctionQueryMetadata();

                    metadata.setName(query.getName());
                    metadata.setProcedureName(call.getProcedureName());
                    
                    List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
                    if (storedFuncs == null) {
                        storedFuncs = new ArrayList<NamedStoredFunctionQueryMetadata>();
                    }
                    
                    DatabaseField arg;
                    StoredProcedureParameterMetadata param;
                    List<DatabaseField> paramFields = call.getParameters();
                    List<Integer> types = call.getParameterTypes();
                    for (int i=0; i < paramFields.size(); i++) {
                        arg = paramFields.get(i);
                        param = new StoredProcedureParameterMetadata();
                        param.setTypeName(arg.getTypeName());

                        if (arg.getSqlType() != DatabaseField.NULL_SQL_TYPE) {
                            param.setJdbcType(arg.getSqlType());
                        }
                        
                        if (arg.isObjectRelationalDatabaseField()) {
                            param.setJdbcTypeName(((ObjectRelationalDatabaseField)arg).getSqlTypeName());
                        }
                        
                        if (i == 0) {
                            // first arg is the return arg
                            metadata.setReturnParameter(param);
                            // handle CURSOR types - want name/value pairs returned
                            if ((Integer) types.get(i) == 8) {
                                addQueryHint(metadata);
                            }
                        } else {
                            param.setName(arg.getName());
                            param.setMode(getParameterModeAsString((Integer)types.get(i)));
                            params.add(param);
                        }
                    }
                    if (params.size() > 0) {
                        metadata.setParameters(params);
                    }
                    storedFuncs.add(metadata);
                }                    
            } else if (query.getCall().isStoredProcedureCall()) {
                if (query.getCall() instanceof PLSQLStoredProcedureCall) {
                    PLSQLStoredProcedureCall call = (PLSQLStoredProcedureCall)query.getCall();
                    if (plsqlStoredProcs == null) {
                        plsqlStoredProcs = new ArrayList<NamedPLSQLStoredProcedureQueryMetadata>();
                    }

                    NamedPLSQLStoredProcedureQueryMetadata metadata = new NamedPLSQLStoredProcedureQueryMetadata();
                    metadata.setName(query.getName());
                    metadata.setProcedureName(call.getProcedureName());

                    PLSQLParameterMetadata param;
                    List<PLSQLParameterMetadata> params = new ArrayList<PLSQLParameterMetadata>();
                    
                    List<PLSQLargument> types = call.getArguments();
                    for (PLSQLargument arg : types) {
                        param = new PLSQLParameterMetadata();
                        param.setName(arg.name);
                        String dbType = processTypeName(arg.databaseType.getTypeName());
                        
                        if (arg.cursorOutput) {
                            param.setDirection(CURSOR_STR);
                        } else {
                            param.setDirection(getDirectionAsString(arg.direction));
                        }
                        
                        if (arg.databaseType == XMLType) {
                            param.setDatabaseType(XMLType.name());
                        } else if (arg.databaseType == PLSQLBoolean) {
                        	param.setDatabaseType(PLSQLBoolean.name());
                        } else {
                            param.setDatabaseType(dbType);
                        }
                        params.add(param);
                    }
                    if (params.size() > 0) {
                        metadata.setParameters(params);
                    }
                    plsqlStoredProcs.add(metadata);
                } else {
                    StoredProcedureCall call = (StoredProcedureCall) query.getCall();
                    NamedStoredProcedureQueryMetadata metadata = new NamedStoredProcedureQueryMetadata();
                    metadata.setName(query.getName());
                    metadata.setProcedureName(call.getProcedureName());
                    metadata.setReturnsResultSet(false);
                    
                    List<StoredProcedureParameterMetadata> params = new ArrayList<StoredProcedureParameterMetadata>();
                    DatabaseField arg;
                    StoredProcedureParameterMetadata param;
                    List paramFields = call.getParameters();
                    List<Integer> types = call.getParameterTypes();
                    for (int i = 0; i < paramFields.size(); i++) {
                        if (types.get(i) == DatabaseCall.INOUT) {
                            // for INOUT we get Object[IN, OUT]
                            arg = (DatabaseField) ((Object[]) paramFields.get(i))[1];
                        } else {
                            arg = (DatabaseField) paramFields.get(i);
                        }

                        param = new StoredProcedureParameterMetadata();
                        param.setName(arg.getName());
                        param.setTypeName(arg.getTypeName());
                        if (arg.getSqlType() != DatabaseField.NULL_SQL_TYPE) {
                            param.setJdbcType(arg.getSqlType());
                        }
                        if (arg.isObjectRelationalDatabaseField()) {
                            param.setJdbcTypeName(((ObjectRelationalDatabaseField) arg).getSqlTypeName());
                        }
                        
                        param.setMode(getParameterModeAsString((Integer) types.get(i)));
                        
                        // handle CURSOR types - want name/value pairs returned
                        if ((Integer) types.get(i) == 8) {
                            addQueryHint(metadata);
                        }
                        
                        params.add(param);
                    }
                    if (params.size() > 0) {
                        metadata.setParameters(params);
                    }
                    if (storedProcs == null) {
                        storedProcs = new ArrayList<NamedStoredProcedureQueryMetadata>();
                    }
                    storedProcs.add(metadata);
                }
            } else {
                // named native query
                NamedNativeQueryMetadata namedQuery = new NamedNativeQueryMetadata();
                namedQuery.setName(query.getName());
                namedQuery.setQuery(query.getSQLString());
                namedQuery.setResultClassName(query.getReferenceClassName());
                if (namedNativeQueries == null) {
                    namedNativeQueries = new ArrayList<NamedNativeQueryMetadata>();
                }
                namedNativeQueries.add(namedQuery);
            }
        }
        // add generated metadata
        if (plsqlStoredProcs != null) {
            xmlEntityMappings.setNamedPLSQLStoredProcedureQueries(plsqlStoredProcs);
        }
        if (plsqlStoredFuncs != null) {
            xmlEntityMappings.setNamedPLSQLStoredFunctionQueries(plsqlStoredFuncs);
        }
        if (storedProcs != null) {
            xmlEntityMappings.setNamedStoredProcedureQueries(storedProcs);
        }
        if (storedFuncs != null) {
            xmlEntityMappings.setNamedStoredFunctionQueries(storedFuncs);
        }
        if (namedNativeQueries != null) {
            xmlEntityMappings.setNamedNativeQueries(namedNativeQueries);
        }

        // generate a ClassAccessor for each Descriptor, keeping track of Embeddables
        List<String> embeddables = new ArrayList<String>();
        Map<String, ClassAccessor> accessors = new HashMap<String, ClassAccessor>();
        for (ClassDescriptor cdesc : descriptors) {
            boolean embeddable = false;
            ClassAccessor classAccessor;
            if (cdesc.isAggregateDescriptor()) {
                embeddable = true;
                classAccessor = new EmbeddableAccessor();
                embeddables.add(cdesc.getJavaClassName());
            } else {
                classAccessor = new EntityAccessor();
            }
            classAccessor.setClassName(cdesc.getJavaClassName());
            classAccessor.setAccess(EL_ACCESS_VIRTUAL);
            
            // may need add STRUCT metadata to the classAccessor to ensure correct field ordering
            if (cdesc.isObjectRelationalDataTypeDescriptor()) {
                ObjectRelationalDataTypeDescriptor odesc = (ObjectRelationalDataTypeDescriptor) cdesc;
                if (odesc.getOrderedFields().size() > 0) {
                    StructMetadata struct = new StructMetadata();
                    struct.setName(odesc.getStructureName());
                    struct.setFields(odesc.getOrderedFields());
                    classAccessor.setStruct(struct);
                }
            }
            
            if (!embeddable && cdesc.getTableName() != null) {
                TableMetadata table = new TableMetadata();
                table.setName(cdesc.getTableName());
                ((EntityAccessor)classAccessor).setTable(table);
            }
            
            if (!embeddable) {
                List<NamedNativeQueryMetadata> namedNatQueries = new ArrayList<NamedNativeQueryMetadata>();
                NamedNativeQueryMetadata namedQuery;
                DatabaseQuery dbQuery;
                // process findAll and findByPk queries
                for (Iterator<DatabaseQuery> queryIt = cdesc.getQueryManager().getAllQueries().iterator(); queryIt.hasNext();) {
                    dbQuery = queryIt.next();
                    namedQuery = new NamedNativeQueryMetadata();
                    namedQuery.setName(dbQuery.getName());
                    namedQuery.setQuery(dbQuery.getSQLString());
                    namedQuery.setResultClassName(dbQuery.getReferenceClassName());
                    namedNatQueries.add(namedQuery);
                }
                // now create/update/delete operations
                Map<String, String> crudOps = crudOperations.get(cdesc.getTableName());
                if (!crudOps.isEmpty()) {
                    for (String opName : crudOps.keySet()) {
                        String crudSql = crudOps.get(opName);
                        NamedNativeQueryMetadata crudQuery = new NamedNativeQueryMetadata();
                        crudQuery.setName(opName);
                        crudQuery.setQuery(crudSql);
                        if (namedNatQueries == null) {
                            namedNatQueries = new ArrayList<NamedNativeQueryMetadata>();
                        }
                        namedNatQueries.add(crudQuery);
                    }
                }
                if (namedNatQueries.size() > 0) {
                    ((EntityAccessor)classAccessor).setNamedNativeQueries(namedNatQueries);
                }
            }
                        
            classAccessor.setAttributes(new XMLAttributes());
            classAccessor.getAttributes().setIds(new ArrayList<IdAccessor>());
            classAccessor.getAttributes().setBasics(new ArrayList<BasicAccessor>());
            classAccessor.getAttributes().setArrays(new ArrayList<ArrayAccessor>());
            classAccessor.getAttributes().setStructures(new ArrayList<StructureAccessor>());
            classAccessor.getAttributes().setEmbeddeds(new ArrayList<EmbeddedAccessor>());
            
            if (embeddable) {
                xmlEntityMappings.getEmbeddables().add((EmbeddableAccessor) classAccessor);
            } else {
                xmlEntityMappings.getEntities().add((EntityAccessor) classAccessor);
            }
            accessors.put(cdesc.getJavaClassName(), classAccessor);
        }
        // now the we know what the embeddables are, we can process mappings 
        for (ClassDescriptor cdesc : descriptors) {
            ClassAccessor classAccessor = accessors.get(cdesc.getJavaClassName());
            
            MappingAccessor mapAccessor;
            // generate a MappingAccessor for each mapping 
            for (DatabaseMapping dbMapping : cdesc.getMappings()) {
                mapAccessor = generateMappingAccessor(dbMapping, embeddables);
                if (mapAccessor == null) { 
                    continue; 
                }
                if (mapAccessor.isId()) {
                    classAccessor.getAttributes().getIds().add((IdAccessor) mapAccessor);
                } else if (mapAccessor.isBasic()) {
                    classAccessor.getAttributes().getBasics().add((BasicAccessor) mapAccessor);
                } else if (mapAccessor instanceof ArrayAccessor) {
                    classAccessor.getAttributes().getArrays().add((ArrayAccessor) mapAccessor);
                } else if (mapAccessor instanceof StructureAccessor) {
                    classAccessor.getAttributes().getStructures().add((StructureAccessor) mapAccessor);
                } else { // assumes EmbeddedAccessor
                    classAccessor.getAttributes().getEmbeddeds().add((EmbeddedAccessor) mapAccessor);
                }
            }
        }
        return xmlEntityMappings;
    }
    
    /**
     * Process a given DatabaseMapping and return a MappingAccessor.
     * 
     * Expected mappings are:
     * <ul>
     * <li>org.eclipse.persistence.mappings.DirectToFieldMapping
     * <li>org.eclipse.persistence.mappings.structures.ArrayMapping
     * <li>org.eclipse.persistence.mappings.structures.ObjectArrayMapping
     * <li>org.eclipse.persistence.mappings.structures.StructureMapping
     * </ul>
     */
    protected static MappingAccessor generateMappingAccessor(DatabaseMapping mapping, List<String> embeddables) {
        MappingAccessor mapAccessor = null;

        if (mapping.isDirectToFieldMapping()) {
            mapAccessor = processDirectMapping((DirectToFieldMapping) mapping);
        } else if (mapping instanceof ObjectArrayMapping) {
            mapAccessor = processObjectArrayMapping((ObjectArrayMapping) mapping);
        } else if (mapping instanceof ArrayMapping) {
            mapAccessor = processArrayMapping((ArrayMapping) mapping);
        } else if (mapping.isStructureMapping()) {
            mapAccessor = processStructureMapping((StructureMapping) mapping);
        } else if (embeddables.contains(((AggregateMapping) mapping).getReferenceClassName())) {
            mapAccessor = processEmbeddedMapping((AggregateMapping) mapping);
        }
        return mapAccessor;
    }

    /**
     * Generate a MappingAccessor for a given DirectToFieldMapping.
     * 
     */
    protected static BasicAccessor processDirectMapping(DirectToFieldMapping mapping) {
        BasicAccessor directMapping;
        if (mapping.getDescriptor().getPrimaryKeyFields().contains(mapping.getField())) {
            directMapping = new IdAccessor();
        } else {
            directMapping = new BasicAccessor();
        }
        directMapping.setName(mapping.getAttributeName());
        directMapping.setAttributeType(mapping.getAttributeClassificationName());
        
        ColumnMetadata column = new ColumnMetadata();
        column.setName(mapping.getField().getName());
        directMapping.setColumn(column);
        
        return directMapping;
    }
    
    /**
     * Generate a MappingAccessor for a given ArrayMapping.
     * 
     */
    protected static ArrayAccessor processArrayMapping(ArrayMapping mapping) {
        ArrayAccessor arrayAccessor = new ArrayAccessor();
        arrayAccessor.setName(mapping.getAttributeName());
        arrayAccessor.setDatabaseType(mapping.getStructureName());
        arrayAccessor.setAttributeType(ARRAYLIST_STR);
        arrayAccessor.setTargetClassName(mapping.getStructureName());
        
        ColumnMetadata column = new ColumnMetadata();
        column.setName(mapping.getField().getName());
        arrayAccessor.setColumn(column);
        
        return arrayAccessor;
    }
    
    /**
     * Generate a MappingAccessor for a given ObjectArrayMapping.
     * 
     */
    protected static ArrayAccessor processObjectArrayMapping(ObjectArrayMapping mapping) {
        ArrayAccessor arrayAccessor = new ArrayAccessor();
        arrayAccessor.setName(mapping.getAttributeName());
        arrayAccessor.setDatabaseType(mapping.getStructureName());
        arrayAccessor.setTargetClassName(mapping.getReferenceClassName());
        arrayAccessor.setAttributeType(ARRAYLIST_STR);

        ColumnMetadata column = new ColumnMetadata();
        column.setName(mapping.getField().getName());
        arrayAccessor.setColumn(column);
        
        return arrayAccessor;
    }

    /**
     * Generate a MappingAccessor for a given StructureMapping.
     * 
     */
    protected static StructureAccessor processStructureMapping(StructureMapping mapping) {
        StructureAccessor structAccessor = new StructureAccessor();
        structAccessor.setName(mapping.getAttributeName());
        structAccessor.setTargetClassName(mapping.getReferenceClassName());
        structAccessor.setAttributeType(mapping.getReferenceClassName());
        
        ColumnMetadata column = new ColumnMetadata();
        column.setName(mapping.getField().getName());
        structAccessor.setColumn(column);
        
        return structAccessor;
    }
    
    /**
     * Generate an EmbeddedAccessor for a given AggregateMapping.
     * 
     */
    protected static EmbeddedAccessor processEmbeddedMapping(AggregateMapping mapping) {
        EmbeddedAccessor embeddedAccessor = new EmbeddedAccessor();
        embeddedAccessor.setName(mapping.getAttributeName());
        embeddedAccessor.setAttributeType(mapping.getReferenceClassName());
        
        return embeddedAccessor;
    }
    
    /**
     * Return a parameter direction as a String based on a given in value.
     * 
     * Expected 'direction' value is one of:
     * <ul>
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.IN
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.INOUT
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.OUT
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.OUT_CURSOR
     * 
     */
    public static String getDirectionAsString(int direction) {
        if (direction == IN) {
            return IN_STR;
        }
        if (direction == OUT) {
            return OUT_STR;
        }
        if (direction == INOUT) {
            return INOUT_STR;
        }
        return CURSOR_STR;
    }
    
    /**
     * Return a parameter mode as a String based on a given in value.
     * 
     * Expected 'direction' value is one of:
     * <ul>
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.IN
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.INOUT
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.OUT
     * <li>org.eclipse.persistence.internal.databaseaccess.DatasourceCall.OUT_CURSOR
     * </ul>
     * 
     * Will return one of:
     * <ul>
     * <li>org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_IN
     * <li>org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_INOUT
     * <li>org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_OUT
     * <li>org.eclipse.persistence.internal.jpa.metadata.MetadataConstants.JPA_PARAMETER_REF_CURSOR
     * </ul>
     */
    public static String getParameterModeAsString(int direction) {
        if (direction == IN) {
            return JPA_PARAMETER_IN;
        }
        if (direction == OUT) {
            return JPA_PARAMETER_OUT;
        }
        if (direction == INOUT) {
            return JPA_PARAMETER_INOUT;
        }
        return JPA_PARAMETER_REF_CURSOR;
    }
    
    /**
     * Alter the given type name if required.
     */
    protected static String processTypeName(String typeName) {
        if (!(getJDBCTypeFromTypeName(typeName) == Types.OTHER)) {
            // OR Metadata doesn't handle VARCHAR2 
            if (typeName.equals(VARCHAR2_STR)) {
                typeName = VARCHAR_STR;
            }
            // for BOOLEAN we want to wrap the type in a PLSQLrecord (in ORMetadata.getDatabaseTypeEnum) to
            // force the appropriate conversion method in PLSQLStoredProcedureCall (declare block, etc)
            if (!typeName.equals(BOOLEAN_STR) && !typeName.equals(XMLTYPE_STR)) {
                typeName = typeName.concat(_TYPE_STR);
            }
        } else { 
            String oPLSQLTypeName = getOraclePLSQLTypeForName(typeName);
            if (oPLSQLTypeName != null) {
                typeName = oPLSQLTypeName;
            }
        }
        return typeName;
    }
    
    /**
     * Returns a list of ComplexTypeMetadata instances generated based on a list of 
     * CompositeDatabaseTypes.  The given non-empty list should contain one or
     * more of the following types:
     * <ul>
     * <li>PLSQLCollectionType
     * <li>PLSQLRecordType
     * <li>ObjectTableType
     * <li>ObjectType
     * <li>VArrayType
     * </ul>
     */
    protected static List<ComplexTypeMetadata> processCompositeTypes(List<CompositeDatabaseType> complexTypes, Project orProject) {
        List<String> processedTypeNames = new ArrayList<String>();
        List<ComplexTypeMetadata> processedTypes = new ArrayList<ComplexTypeMetadata>();
        // process composite types
        for (CompositeDatabaseType cdbType : complexTypes) {
            ComplexTypeMetadata complexTypeMetadata = processDatabaseType(cdbType, orProject);
            if (complexTypeMetadata != null) {
                processedTypeNames.add(complexTypeMetadata.getName());
                processedTypes.add(complexTypeMetadata);
            }
        }
        // now handle processing composite enclosed types
        for (CompositeDatabaseType cdbType : complexTypes) {
            if (cdbType.getEnclosedType() != null && cdbType.getEnclosedType().isComposite()) {
                CompositeDatabaseType enclosedType = (CompositeDatabaseType) cdbType.getEnclosedType();
                ComplexTypeMetadata complexTypeMetadata = processDatabaseType(enclosedType, orProject, processedTypeNames);
                if (complexTypeMetadata != null) {
                    processedTypeNames.add(complexTypeMetadata.getName());
                    processedTypes.add(complexTypeMetadata);
                    
                    if (enclosedType.isObjectType()) {                        
                        for (FieldType ft : ((ObjectType) enclosedType).getFields()) {
                            if (ft.isComposite()) {
                                complexTypeMetadata = processDatabaseType(ft, orProject, processedTypeNames);
                                if (complexTypeMetadata != null) {
                                    processedTypeNames.add(complexTypeMetadata.getName());
                                    processedTypes.add(complexTypeMetadata);
                                }
                            }
                        }
                    } else if (enclosedType.isVArrayType()) {
                        VArrayType vType = (VArrayType) enclosedType;
                        if (vType.getEnclosedType().isComposite()) {
                            complexTypeMetadata = processDatabaseType((CompositeDatabaseType) vType.getEnclosedType(), orProject, processedTypeNames);
                            if (complexTypeMetadata != null) {
                                processedTypeNames.add(complexTypeMetadata.getName());
                                processedTypes.add(complexTypeMetadata);
                            }
                        }
                    }
                }
            }
            
        }        
        return processedTypes;
    }
    
    /**
     * Process the given CompositeDatabaseType and return a ComplexTypeMetadata
     * instance. The given type is expected to be one of:
     * <ul>
     * <li>PLSQLCollectionType
     * <li>PLSQLRecordType
     * <li>ObjectTableType
     * <li>ObjectType
     * <li>VArrayType
     * </ul>
     * If the given type is not one of these, null is returned.
     */
    protected static ComplexTypeMetadata processDatabaseType(CompositeDatabaseType cdbType, Project orProject) {
        return processDatabaseType(cdbType, orProject, new ArrayList<String>());
    }
    
    /**
     * Process the given CompositeDatabaseType and return a ComplexTypeMetadata
     * instance. The given type is expected to be one of:
     * <ul>
     * <li>PLSQLCollectionType
     * <li>PLSQLRecordType
     * <li>ObjectTableType
     * <li>ObjectType
     * <li>VArrayType
     * </ul>
     * If the given type is not one of these, null is returned.  Previously processed types
     * are tracked to avoid unnecessary work.
     */
    protected static ComplexTypeMetadata processDatabaseType(CompositeDatabaseType cdbType, Project orProject, List<String> processedTypeNames) {
        if (!processedTypeNames.contains(cdbType.getTypeName())) {
            if (cdbType.isPLSQLCollectionType()) {
                return processPLSQLCollectionType((PLSQLCollectionType) cdbType);
            }
            if (cdbType.isPLSQLRecordType()) {
                return processPLSQLRecordType((PLSQLRecordType) cdbType);
            }
            if (cdbType.isObjectTableType()) {
                return processObjectTableType((ObjectTableType) cdbType, orProject);
            }
            if (cdbType.isObjectType()) {
                return processObjectType((ObjectType) cdbType, orProject);
            }
            if (cdbType.isVArrayType()) {
                return processVArrayType((VArrayType) cdbType, orProject);
            }
        }
        return null;
    }

    /**
     * Process the given PLSQLCollectionType and return a PLSQLTableMetadata instance.
     * 
     */
    protected static ComplexTypeMetadata processPLSQLCollectionType(PLSQLCollectionType plsqlCollectionType) {
        String typeName = plsqlCollectionType.getParentType().getPackageName() + DOT + plsqlCollectionType.getTypeName();
        String compatiableName = plsqlCollectionType.getParentType().getPackageName() + UNDERSCORE + plsqlCollectionType.getTypeName();
        
        PLSQLTableMetadata plsqlTable = new PLSQLTableMetadata();
        plsqlTable.setName(typeName);
        plsqlTable.setCompatibleType(compatiableName);
        // 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 {
                // OR Metadata doesn't handle VARCHAR2 
                if (dbType.equals(VARCHAR2_STR)) {
                    dbType = VARCHAR_STR;
                }
                plsqlTable.setNestedType(dbType + _TYPE_STR);
            }
        } else {
            // may need to prepend package name
            String pkg = null;
            if (plsqlCollectionType.getEnclosedType() != null && plsqlCollectionType.getEnclosedType().isPLSQLType()) {
                PLSQLType pType = (PLSQLType) plsqlCollectionType.getEnclosedType();
                pkg = pType.getParentType().getPackageName();
            }
            plsqlTable.setNestedType(pkg == null ? dbType : pkg + DOT + dbType);
        }
        
        plsqlTable.setJavaType(typeName.toLowerCase() + COLLECTION_WRAPPER_SUFFIX);
        return plsqlTable;
    }

    /**
     * Process the given PLSQLRecordType and return a PLSQLRecordMetadata instance.
     * 
     */
    protected static ComplexTypeMetadata processPLSQLRecordType(PLSQLRecordType plsqlRecordType) {
        // for %ROWTYPE we create a 'place holder' PL/SQL Record - in this case there is no package name
        String packageName = plsqlRecordType.getParentType().getPackageName();
        String typeName = packageName != null ? plsqlRecordType.getParentType().getPackageName() + DOT + plsqlRecordType.getTypeName() : plsqlRecordType.getTypeName();
        String compatiableName = packageName != null ? plsqlRecordType.getParentType().getPackageName() + UNDERSCORE + plsqlRecordType.getTypeName() : plsqlRecordType.getTypeName();
        if (compatiableName.contains(PERCENT)) {
            compatiableName = compatiableName.replace(PERCENT, UNDERSCORE);
        }
        
        PLSQLRecordMetadata plsqlRecordMetadata = new PLSQLRecordMetadata();
        plsqlRecordMetadata.setName(typeName);
        plsqlRecordMetadata.setCompatibleType(compatiableName);
        if (typeName.endsWith(ROWTYPE_STR)) {
            plsqlRecordMetadata.setJavaType(compatiableName.toLowerCase());
        } else {
            plsqlRecordMetadata.setJavaType(typeName.toLowerCase());
        }

        List<PLSQLParameterMetadata> fields = new ArrayList<PLSQLParameterMetadata>();
        PLSQLParameterMetadata field;
        for (FieldType fld : plsqlRecordType.getFields()) {
            field = new PLSQLParameterMetadata();
            field.setName(fld.getFieldName());
            String pkg = null;
            if (fld.getEnclosedType() != null && fld.getEnclosedType().isPLSQLType()) {
                PLSQLType pType = (PLSQLType) fld.getEnclosedType();
                pkg = pType.getParentType().getPackageName();
            }
            String dbType = fld.getTypeName();
            if (!(getJDBCTypeFromTypeName(dbType) == Types.OTHER)) {
                // OR Metadata doesn't handle VARCHAR2 
                if (dbType.equals(VARCHAR2_STR)) {
                    dbType = VARCHAR_STR;
                }
                if (!dbType.equals(BOOLEAN_STR)) {
                    dbType = dbType.concat(_TYPE_STR);
                }
            }
            dbType = pkg == null ? dbType : pkg + DOT + dbType;
            field.setDatabaseType(dbType);
            fields.add(field);
        }
        plsqlRecordMetadata.setFields(fields);
        return plsqlRecordMetadata;
    }

    /**
     * Process the given ObjectTableType and return an OracleArrayTypeMetadata instance.
     * 
     */
    protected static ComplexTypeMetadata processObjectTableType(ObjectTableType oTableType, Project orProject) {
        ClassDescriptor cDesc = orProject.getDescriptorForAlias(getGeneratedAlias(oTableType.getTypeName()));
        
        OracleArrayTypeMetadata oatMetadata = new OracleArrayTypeMetadata();
        oatMetadata.setName(oTableType.getTypeName());
        oatMetadata.setJavaType(cDesc.getJavaClassName());
        
        oatMetadata.setNestedType(oTableType.getEnclosedType().getTypeName());
        
        return oatMetadata;
    }

    /**
     * Process the given ObjectType and return an OracleObjectTypeMetadata instance.
     * 
     */
    protected static ComplexTypeMetadata processObjectType(ObjectType oType, Project orProject) {
        ClassDescriptor cDesc = orProject.getDescriptorForAlias(getGeneratedAlias(oType.getTypeName()));
        
        OracleObjectTypeMetadata ootMetadata = new OracleObjectTypeMetadata();
        ootMetadata.setName(oType.getTypeName());
        ootMetadata.setJavaType(cDesc.getJavaClassName());
    
        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);
        }
        ootMetadata.setFields(fields);
        return ootMetadata;
    }    
    
    /**
     * Process the given VArrayType and return an OracleArrayTypeMetadata instance.
     * 
     */
    protected static ComplexTypeMetadata processVArrayType(VArrayType vType, Project orProject) {
        ClassDescriptor cDesc = orProject.getDescriptorForAlias(getGeneratedAlias(vType.getTypeName()));
        
        OracleArrayTypeMetadata oatMetadata = new OracleArrayTypeMetadata();
        oatMetadata.setName(vType.getTypeName());
        oatMetadata.setJavaType(cDesc.getJavaClassName());
        oatMetadata.setNestedType(processTypeName(vType.getEnclosedType().getTypeName()));

        return oatMetadata;
    }
    
    /**
     * Adds a ReturnNameValuePairsHint to the given query metadata instance.
     */
    protected static void addQueryHint(NamedNativeQueryMetadata metadata) {
        List<QueryHintMetadata> hints = metadata.getHints();
        if (hints == null) {
            hints = new ArrayList<QueryHintMetadata>();
        }
        QueryHintMetadata hint = new QueryHintMetadata();
        hint.setName(QueryHints.RETURN_NAME_VALUE_PAIRS);
        hint.setValue(HintValues.TRUE);
        hints.add(hint);
        metadata.setHints(hints);
    }
}