/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink

package org.eclipse.persistence.tools.dbws.jdbc;

//javase imports
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static java.sql.DatabaseMetaData.columnNullable;
import static java.sql.DatabaseMetaData.procedureReturnsResult;
import static java.sql.DatabaseMetaData.tableIndexStatistic;
import static java.sql.DatabaseMetaData.procedureColumnInOut;
import static java.sql.DatabaseMetaData.procedureColumnOut;
import static java.sql.DatabaseMetaData.procedureColumnReturn;
import static java.sql.Types.ARRAY;
import static java.sql.Types.OTHER;
import static java.sql.Types.STRUCT;
import static java.util.logging.Level.FINEST;

//java eXtension imports
import javax.xml.namespace.QName;

// EclipseLink imports
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.xr.Attachment;
import org.eclipse.persistence.internal.xr.CollectionResult;
import org.eclipse.persistence.internal.xr.NamedQueryHandler;
import org.eclipse.persistence.internal.xr.Parameter;
import org.eclipse.persistence.internal.xr.ProcedureArgument;
import org.eclipse.persistence.internal.xr.ProcedureOutputArgument;
import org.eclipse.persistence.internal.xr.QueryHandler;
import org.eclipse.persistence.internal.xr.QueryOperation;
import org.eclipse.persistence.internal.xr.Result;
import org.eclipse.persistence.internal.xr.StoredFunctionQueryHandler;
import org.eclipse.persistence.internal.xr.StoredProcedureQueryHandler;
import org.eclipse.persistence.platform.database.DerbyPlatform;
import org.eclipse.persistence.platform.database.MySQLPlatform;
import org.eclipse.persistence.platform.database.PostgreSQLPlatform;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.tools.dbws.BaseDBWSBuilderHelper;
import org.eclipse.persistence.tools.dbws.DBWSBuilder;
import org.eclipse.persistence.tools.dbws.DBWSBuilderHelper;
import org.eclipse.persistence.tools.dbws.ProcedureOperationModel;
import org.eclipse.persistence.tools.dbws.Util;

import static org.eclipse.persistence.internal.xr.Util.SXF_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.ANY_QNAME;
import static org.eclipse.persistence.tools.dbws.Util.SXF_QNAME_CURSOR;
import static org.eclipse.persistence.tools.dbws.Util.buildCustomQName;
import static org.eclipse.persistence.tools.dbws.Util.escapePunctuation;
import static org.eclipse.persistence.tools.dbws.Util.buildTypeForJDBCType;
import static org.eclipse.persistence.tools.dbws.Util.getXMLTypeFromJDBCType;
import static org.eclipse.persistence.tools.dbws.Util.qNameFromString;

//DDL parser imports
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType;
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FunctionType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.IN;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.INOUT;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.OUT;
import static org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection.RETURN;

/*
 * Known Problems/Limitations: Oracle
 *
 * 1) Oracle driver returns wrong value of column size
 * Driver versions:
 * - 10.0.1.4
 * - 9.2.0.6
 * When tables are created with NLS_LENGTH_SEMANTICS='CHAR'
 * As per JavaDOC for the method ResultSet DatabaseMetaData.getColumns(....) :
 *            7. COLUMN_SIZE int => column size. For char or date types this is the maximum
 *               number of characters, for numeric or decimal types this is precision.
 * Suppose you create a table :
 *     create table test (col_char varchar2(8));
 * Now Retrieve the MetaData for the column "col_char" :
 *     ...
 *     ResultSet columnsInfo = databaseMetaData.getColumns(null, null, "test", "%");
 *     if (columnsInfo != null) {
 *        while (columnsInfo.next()) {
 *           dbColumn.setName(columnsInfo.getString(4)); // 4 COLUMN_NAME String => column name
 *           dbColumn.setPrecision(columnsInfo.getInt(7)); // 7 COLUMN_SIZE int => column size.
 *                                                         // For char or date types this is the
 *                                                         // maximum number of characters, for
 *                                                         // numeric or decimal types this is
 *                                                         // precision.
 *        }
 *     }
 * the return value is 24 which is number of bytes and not char_length
 * as per the JavaDoc for the column col_char the return value should be 8.
 * But it returns the value 24 which is the number of bytes and not the char_length.
 * solved by 4485954 - updated version of oracle.jdbc.driver.OracleDatabaseMetaData
 *                     in 10.2.0.2.0
 *
 * 3) DatabaseMetaData.getColumns:
 * The driver doesn't return INTEGER data type, instead it returns 3 ("NUMBER")
 * with column precision of 22 and scale 0.
 *
 * 4) databaseMetaData.getTables() does not work for SYNONYMS
 *
 * 5) databaseMetaData.getProcedureColumns will not return the 'null' column for Stored Procedures
 *    that have no arguments, while USER_PROCEDURES (since 9.x) will
 *
 * 6) When making a call java method to a pl/sql stored procedure, register an out parameter of
 * type java.sql.Types.VARCHAR (statement.registerOutParameter(i, Types.VARCHAR). The procedure
 * has an OUT parameter of type VARCHAR2 with a NOCOPY hint (parameter1 OUT NOCOPY  VARCHAR2).
 * The pl/sql procedure throws an exception as soon as the size of 'parameter1' exceeds ~2000
 * characters (~4000 bytes).
 *
 * workaround : use oracle.jdbc.OracleTypes.VARCHAR
 *
 * 7) databaseMetaData.getIndexInfo() does not work for VIEWS, a SQLException with the following
 * "ORA-01702: a view is not appropriate here: can't retrieve indexInfo" is thrown
 * (other platforms just ignore).
 *
 * For IBM AS/400 via JTOpen
 * 1) In the result set returned by DatabaseMetaData.getColumns(), the CHAR_OCTET_LENGTH and
 *    ORDINAL_POSITION columns are not supported in Toolbox versions prior to V5R1 (JTOpen 2.x).
 *    The following workarounds are available:
 *     For CHAR_OCTET_LENGTH, which is supposed to indicate the maximum number of bytes in the column,
 *     use the value in the COLUMN_SIZE. Multiply this value by 2 if the column holds DBCS characters.
 *     For ORDINAL_POSITION, which is supposed to indicate the index of the column in a table,
 *     run a query for all columns in the table ("SELECT * FROM table"), and then issue
 *     ResultSet.findColumn() on the result set to determine the column index from the column name.
 *     In the ResultSetMetaData object, the getTableName() and getSchema() name methods are not
 *     supported in Toolbox versions prior to V5R2 (JTOpen 3.x). In supported Toolbox versions,
 *     these methods work only if the "extended metadata" connection property has been set to True
 *     and only when the target server is at the V5R2 operating system or later. Because retrieving
 *     the additional information may incur a performance penalty, this property is set to False by
 *     default.
 *
 * ODBC-JDBC Bridge
 * 1) for MS-ACCESS getPrimaryKeys not supported
 *
 * Apache Derby (a.k.a. JavaDB)
 * 1) metadata for storedFunctions not available until JDK 6/JDBC 4
 *    (Oracle returns metadata for storedFunctions via databaseMetaData.getProcedures())
 *
 */
public class JDBCHelper extends BaseDBWSBuilderHelper implements DBWSBuilderHelper {

    // useful fields in databaseMetaData.getTables() ResultSet
    public static final int TABLESINFO_CATALOG = 1; // String ==> table catalog (may be null)
    public static final int TABLESINFO_SCHEMA = 2; // String => table schema (may be null)
    public static final int TABLESINFO_NAME = 3; // String => table name
    public static final int TABLESINFO_TYPE = 4; // String => table type. Typical types are:
                                                 // "TABLE", "VIEW", "SYSTEM TABLE",
                                                 // "GLOBAL TEMPORARY", "LOCAL TEMPORARY",
                                                 // "ALIAS", "SYNONYM".
    // useful fields in databaseMetaData.getColumns() ResultSet
    public static final int COLUMNSINFO_COLUMN_NAME = 4; // String => table name
    public static final int COLUMNSINFO_DATA_TYPE = 5; // int => SQL type from java.sql.Types
    public static final int COLUMNSINFO_TYPE_NAME = 6; // String => Data source dependent type name,
                                                       // for a UDT the type name is fully qualified
    public static final int COLUMNSINFO_COLUMN_SIZE = 7; // int => column size. For char or date
                                                         // types, this is the maximum number of
                                                         // characters, for numeric or decimal types
                                                         // this is precision.
    public static final int COLUMNSINFO_DECIMAL_DIGITS = 9; // int => the number of fractional digits
    public static final int COLUMNSINFO_NULLABLE = 11; // int => is NULL allowed?
                                                       //  columnNoNulls - might not allow
                                                       //  columnNullable - definitely allows
                                                       //  columnNullableUnknown - unknown
    public static final int COLUMNSINFO_ORDINAL_POSITION = 17; // int => index of column in table
                                                               // (1-based)
    // useful fields in databaseMetaData.getPrimaryKeys() ResultSet
    public static final int PKSINFO_KEY_SEQ = 5; // KEY_SEQ short => sequence number within primary
                                                 // key
    public static final int PKSINFO_PK_NAME = 6; // PK_NAME String => primary key name (may be null)
    // useful fields in databaseMetaData.getIndexInfo() ResultSet
    public static final int INDEXINFO_NON_UNIQUE = 4; // boolean => Can index values be non-unique.
                                                      // false when TYPE is tableIndexStatistic
    public static final int INDEXINFO_TYPE = 7; // short => index type:
                                                //  tableIndexStatistic - this identifies
                                                //    table statistics that are returned in
                                                //    conjuction with a table's index
                                                //    descriptions
                                                //  tableIndexClustered - this is a
                                                //    clustered index
                                                //  tableIndexHashed - this is a hashed
                                                //    index
                                                //  tableIndexOther - this is some other
                                                //    style of index
    public static final int INDEXINFO_ORDINAL_POSITION = 8; // short => column sequence number
                                                            // within index; zero when TYPE is
                                                            // tableIndexStatistic
    // useful fields in databaseMetaData.getProcedures() ResultSet
    public static final int PROCS_INFO_CATALOG = 1; // String => procedure catalog (may be null)
    public static final int PROCS_INFO_SCHEMA = 2; // String => procedure schema (may be null)
    public static final int PROCS_INFO_NAME   = 3; // String ==> procedure name
    public static final int PROCS_INFO_TYPE = 8; // short => kind of procedure:
                                                 //  procedureResultUnknown - May return a result
                                                 //  procedureNoResult - Does not return a result
                                                 //  procedureReturnsResult - Returns a result
    // useful fields in databaseMetaData.getProcedureColumns() ResultSet
    public static final int PROC_COLS_INFO_CATALOG = 1; // String ==> procedure catalog (may be null)
    public static final int PROC_COLS_INFO_SCHEMA = 2; // String ==> procedure schema (may be null)
    public static final int PROC_COLS_INFO_NAME = 3; // String ==> procedure name
    public static final int PROC_COLS_INFO_COLNAME = 4; // String => column/parameter name
    public static final int PROC_COLS_INFO_TYPE = 5; // Short => kind of column/parameter:
                                                     //  procedureColumnUnknown - nobody knows
                                                     //  procedureColumnIn - IN parameter
                                                     //  procedureColumnInOut - INOUT parameter
                                                     //  procedureColumnOut - OUT parameter
                                                     //  procedureColumnReturn - procedure return value
                                                     //  procedureColumnResult - result column in ResultSet
    public static final int PROC_COLS_INFO_DATA_TYPE = 6; // int => SQL type from java.sql.Types
    public static final int PROC_COLS_INFO_TYPE_NAME = 7; // String => SQL type name, for a UDT type
                                                          // the type name is fully qualified
    public static final int PROC_COLS_INFO_PRECISION = 8; // int => precision
    public static final int PROC_COLS_INFO_LENGTH = 9; // int => length in bytes of data
    public static final int PROC_COLS_INFO_SCALE = 10; // short => scale
    public static final int PROC_COLS_INFO_RADIX = 11; // short => radix
    public static final int PROC_COLS_INFO_NULLABLE = 12; // short => can it contain NULL.
                                                          //  procedureNoNulls - does not allow NULL values
                                                          //  procedureNullable - allows NULL values
                                                          //  procedureNullableUnknown - nullability unknown
    public static final int PROC_COLS_INFO_ORA_SEQUENCE = 14; // Oracle-specific
                                                              //  for package-qualified procedures,
                                                              //  Oracle allows overloading of the
                                                              //  procedure name. This field indicates
                                                              //  the position of the argument (as
                                                              //  argument names may be reused
    public static final int PROC_COLS_INFO_ORA_OVERLOAD = 15; // Oracle-specific
                                                              //  for package-qualified procedures,
                                                              //  Oracle allows overloading of the
                                                              //  procedure name. This field indicates
                                                              //  the 'overload level' - i.e. which
                                                              //  procedure we are dealing with

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

    /**
     * Indicates if one or more database tables were discovered.
     *
     */
    @Override
    public boolean hasTables() {
        return dbTables.size() != 0;
    }

    @Override
    public void buildProcedureOperation(ProcedureOperationModel procedureOperationModel) {
        String name = procedureOperationModel.getName();
        boolean isMySQL = dbwsBuilder.getDatabasePlatform().getClass().getName().contains("MySQL");
        for (ProcedureType storedProcedure : procedureOperationModel.getDbStoredProcedures()) {
            StringBuilder sb = new StringBuilder();
            if (name == null || name.length() == 0) {
                if (storedProcedure.getOverload() > 0) {
                    sb.append(storedProcedure.getOverload());
                    sb.append('_');
                }
                if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
                    sb.append(storedProcedure.getCatalogName());
                    sb.append('_');
                }
                if (storedProcedure.getSchema() != null && storedProcedure.getSchema().length() > 0) {
                    sb.append(storedProcedure.getSchema());
                    sb.append('_');
                }
                sb.append(storedProcedure.getProcedureName());
            }
            else {
                sb.append(name);
            }
            QueryOperation qo = new QueryOperation();
            qo.setName(sb.toString());
            QueryHandler qh;
            if (storedProcedure.isFunctionType()) {
                qh = new StoredFunctionQueryHandler();
            }
            else {
              qh = new StoredProcedureQueryHandler();
            }
            sb = new StringBuilder();
            if (!isMySQL) {
                if (storedProcedure.getCatalogName() != null && storedProcedure.getCatalogName().length() > 0) {
                    sb.append(storedProcedure.getCatalogName());
                    sb.append('.');
                }
            }
            if (storedProcedure.getSchema() != null && storedProcedure.getSchema().length() > 0) {
                sb.append(storedProcedure.getSchema());
                sb.append('.');
            }
            sb.append(storedProcedure.getProcedureName());
            ((StoredProcedureQueryHandler)qh).setName(sb.toString());
            dbwsBuilder.logMessage(FINEST, "Building QueryOperation for " + sb.toString());
            // before assigning queryHandler, check for named query in OR project
            List<DatabaseQuery> queries = dbwsBuilder.getOrProject().getQueries();
            if (queries.size() > 0) {
                for (DatabaseQuery q : queries) {
                    if (q.getName().equals(qo.getName())) {
                        qh = new NamedQueryHandler();
                        ((NamedQueryHandler)qh).setName(qo.getName());
                    }
                }
            }
            qo.setQueryHandler(qh);
            String returnType = procedureOperationModel.getReturnType();
            boolean isCollection = procedureOperationModel.isCollection();
            boolean isSimpleXMLFormat = procedureOperationModel.isSimpleXMLFormat();
            Result result = null;
            if (storedProcedure.isFunctionType()) {
                FunctionType storedFunction = (FunctionType) storedProcedure;
                DatabaseType rarg = storedFunction.getReturnArgument();
                if (rarg.getTypeName().contains("CURSOR")) {
                    result = new CollectionResult();
                    result.setType(SXF_QNAME_CURSOR);
                }
                else {
                    result = new Result();
                    int rargJdbcType = Util.getJDBCTypeFromTypeName(rarg.getTypeName());
                    switch (rargJdbcType) {
                        case STRUCT:
                        case ARRAY:
                        case OTHER:
                            if (returnType != null) {
                                result.setType(buildCustomQName(returnType, dbwsBuilder));
                            }
                            else {
                                result.setType(ANY_QNAME);
                            }
                            break;
                        default :
                            result.setType(getXMLTypeFromJDBCType(rargJdbcType));
                            break;
                    }
                }
            }
            else {
                // if user overrides returnType, assume they're right
                if (returnType != null) {
                    result = new Result();
                    result.setType(buildCustomQName(returnType, dbwsBuilder));
                }
                else {
                    if (isCollection) {
                        result = new CollectionResult();
                        if (isSimpleXMLFormat) {
                            result.setType(SXF_QNAME_CURSOR);
                        }
                    }
                    else {
                        result = new Result();
                        result.setType(SXF_QNAME);
                    }
                }
            }
            if (procedureOperationModel.getBinaryAttachment()) {
                Attachment attachment = new Attachment();
                attachment.setMimeType("application/octet-stream");
                result.setAttachment(attachment);
            }
            for (ArgumentType arg : storedProcedure.getArguments()) {
                String argName = arg.getArgumentName();
                if (argName != null) {
                    ProcedureArgument pa = null;
                    Parameter parm = null;
                    ArgumentTypeDirection direction = arg.getDirection();
                    QName xmlType = null;
                    switch (Util.getJDBCTypeFromTypeName(arg.getTypeName())) {
                        case STRUCT:
                        case ARRAY:
                        case OTHER:
                            String typeString = nct.generateSchemaAlias(arg.getTypeName());
                            xmlType = buildCustomQName(typeString, dbwsBuilder);
                            break;
                        default :
                            xmlType = getXMLTypeFromJDBCType(Util.getJDBCTypeFromTypeName(arg.getTypeName()));
                            break;
                    }
                    if (direction == IN) {
                        parm = new Parameter();
                        parm.setName(argName);
                        parm.setType(xmlType);
                        pa = new ProcedureArgument();
                        pa.setName(argName);
                        pa.setParameterName(argName);
                        if (qh instanceof StoredProcedureQueryHandler) {
                            ((StoredProcedureQueryHandler)qh).getInArguments().add(pa);
                        }
                    }
                    else {
                        // the first OUT/INOUT arg determines singleResult vs. collectionResult
                        pa = new ProcedureOutputArgument();
                        ProcedureOutputArgument pao = (ProcedureOutputArgument)pa;
                        pao.setName(argName);
                        pao.setParameterName(argName);
                        if (arg.getTypeName().contains("CURSOR") &&
                            returnType == null) { // if user overrides returnType, assume they're right
                            pao.setResultType(SXF_QNAME_CURSOR);
                            if (result == null) {
                                result = new CollectionResult();
                                result.setType(SXF_QNAME_CURSOR);
                            }
                        }
                        else {
                            // if user overrides returnType, assume they're right
                            // Hmm, multiple OUT's gonna be a problem - later!
                            if (returnType != null && !isSimpleXMLFormat) {
                                xmlType = qNameFromString("{" + dbwsBuilder.getTargetNamespace() + "}" +
                                    returnType, dbwsBuilder.getSchema());
                            }
                            pao.setResultType(xmlType);
                            if (result == null) {
                                if (isCollection) {
                                    result = new CollectionResult();
                                }
                                else {
                                    result = new Result();
                                }
                                result.setType(xmlType);
                            }
                        }
                        if (direction == INOUT) {
                            parm = new Parameter();
                            parm.setName(argName);
                            parm.setType(xmlType);
                            result.setType(xmlType);
                            // use of INOUT precludes SimpleXMLFormat
                            isSimpleXMLFormat = false;

                            if (qh instanceof StoredProcedureQueryHandler) {
                                ((StoredProcedureQueryHandler)qh).getInOutArguments().add(pao);
                            }
                        }
                        else {
                            if (qh instanceof StoredProcedureQueryHandler) {
                                ((StoredProcedureQueryHandler)qh).getOutArguments().add(pao);
                            }
                        }
                    }
                    if (parm != null) {
                        qo.getParameters().add(parm);
                    }
                }
            }

            handleSimpleXMLFormat(isSimpleXMLFormat, result, procedureOperationModel);
            qo.setResult(result);
            dbwsBuilder.getXrServiceModel().getOperations().put(qo.getName(), qo);
        }
        finishProcedureOperation();
    }

    @Override
    protected List<TableType> loadTables(List<String> catalogPatterns, List<String> schemaPatterns,
        List<String> tableNamePatterns) {
        List<TableType> tables = new ArrayList<TableType>();
        for (int i = 0, len = catalogPatterns.size(); i < len; i++) {
            String catalogPattern = catalogPatterns.get(i);
            String schemaPattern = schemaPatterns.get(i);
            String tablePattern = tableNamePatterns.get(i);
            tables.addAll(loadTables(catalogPattern, schemaPattern, tablePattern));
        }
        return tables;
    }
    protected List<TableType> loadTables(String originalCatalogPattern, String originalSchemaPattern,
        String originalTablePattern) {
        List<TableType> dbTables = null;
        String schemaPattern = escapePunctuation(originalSchemaPattern);
        String tablePattern = escapePunctuation(originalTablePattern);
        DatabaseMetaData databaseMetaData = getDatabaseMetaData(dbwsBuilder.getConnection());
        boolean supportsCatalogsInTableDefinitions = true;
        try {
            supportsCatalogsInTableDefinitions =
                databaseMetaData.supportsCatalogsInTableDefinitions();
        }
        catch (SQLException sqlException) { /* ignore*/ }
        String catalogPattern = escapePunctuation(
            supportsCatalogsInTableDefinitions ? originalCatalogPattern : "");
        // Make sure table(s) is/are available
        ResultSet tablesInfo = null;
        try {
            tablesInfo = databaseMetaData.getTables(catalogPattern, schemaPattern, tablePattern, null);
        }
        catch (SQLException sqlException) {
            throw new IllegalStateException("failure retrieving JDBC table metadata", sqlException);
        }
        // did we get a hit?
        if (tablesInfo != null) {
            dbTables = new ArrayList<TableType>();
            try {
                while (tablesInfo.next()) {
                    String actualTableCatalog = null;
                    try {
                        actualTableCatalog = tablesInfo.getString(TABLESINFO_CATALOG);
                    }
                    catch (SQLException sqlException) {
                        // we can live without catalog info
                    }
                    String actualTableSchema = null;
                    try {
                        actualTableSchema = tablesInfo.getString(TABLESINFO_SCHEMA);
                    }
                    catch (SQLException sqlException) {
                        // we can live without schema info
                    }
                    String actualTableName = tablesInfo.getString(TABLESINFO_NAME);
                    String tableType = null;
                    try {
                        tableType = tablesInfo.getString(TABLESINFO_TYPE);
                    }
                    catch (SQLException sqlException) {
                        // we can live without table type - assume TABLE
                    }
                    DbTable dbTable = new DbTable();
                    dbTable.setCatalog(actualTableCatalog);
                    dbTable.setSchema(actualTableSchema);
                    dbTable.setTableName(actualTableName);
                    if (tableType != null) {
                        dbTable.setType(tableType);
                    }
                    dbTables.add(dbTable);
                    ResultSet columnInfo = databaseMetaData.getColumns(actualTableCatalog,
                        actualTableSchema, actualTableName, "%");
                    while (columnInfo.next()) {
                        String columnName = columnInfo.getString(COLUMNSINFO_COLUMN_NAME);
                        DbColumn dbColumn = new DbColumn(columnName);
                        int dbPrecision = -1;
                        try {
                            dbPrecision = columnInfo.getInt(COLUMNSINFO_COLUMN_SIZE);
                        }
                        catch (NumberFormatException nfe) {
                            // ignore
                        }
                        int dbScale = columnInfo.getInt(COLUMNSINFO_DECIMAL_DIGITS);
                        if (columnInfo.getInt(COLUMNSINFO_NULLABLE) == columnNullable) {
                            dbColumn.unSetNotNull();
                        }
                        else {
                            dbColumn.setNotNull();
                        }
                        dbColumn.setJDBCType(columnInfo.getInt(COLUMNSINFO_DATA_TYPE));
                        dbColumn.setJDBCTypeName(columnInfo.getString(COLUMNSINFO_TYPE_NAME));
                        dbColumn.setEnclosedType(buildTypeForJDBCType(dbColumn.getJDBCType(),
                            dbPrecision, dbScale));
                        dbTable.getColumns().add(dbColumn);
                    }
                    columnInfo.close();
                    ResultSet pksInfo = databaseMetaData.getPrimaryKeys(actualTableCatalog,
                        actualTableSchema, actualTableName);
                    if (pksInfo != null) {
                        while (pksInfo.next()) {
                            short keySeq = pksInfo.getShort(PKSINFO_KEY_SEQ);
                            String pkConstraintName = pksInfo.getString(PKSINFO_PK_NAME);
                            DbColumn dbColumn = (DbColumn)dbTable.getColumns().get(keySeq - 1);
                            dbColumn.setPk();
                            dbColumn.setPkConstraintName(pkConstraintName);
                        }
                    }
                    pksInfo.close();
                    try {
                        ResultSet indexInfo = databaseMetaData.getIndexInfo(actualTableCatalog,
                            actualTableSchema, actualTableName, true, false);
                        if (indexInfo != null) {
                            while (indexInfo.next()) {
                                boolean nonUnique = indexInfo.getBoolean(INDEXINFO_NON_UNIQUE);
                                if (!nonUnique) { // reverse logic!
                                    short type = indexInfo.getShort(INDEXINFO_TYPE);
                                    if (type != tableIndexStatistic) {
                                        short pos = indexInfo.getShort(INDEXINFO_ORDINAL_POSITION);
                                        DbColumn dbColumn = (DbColumn)dbTable.getColumns().get(pos - 1);
                                        if (!dbColumn.pk()) {
                                            dbColumn.setUnique(true);
                                        }
                                    }
                                }
                            }
                        }
                        indexInfo.close();
                    }
                    catch (SQLException sqlException) {
                        // ignore
                    }
                }
                tablesInfo.close();
            }
            catch (SQLException sqlException) {
                throw new IllegalStateException("failure retrieving JDBC table metadata",
                    sqlException);
            }
        }
        return dbTables;
    }

    @Override
    protected List<ProcedureType> loadProcedures(List<String> catalogPatterns,
        List<String> schemaPatterns, List<String> procedureNamePatterns) {
        List<ProcedureType> procedures = new ArrayList<ProcedureType>();
        for (int i = 0, len = catalogPatterns.size(); i < len; i++) {
            String catalogPattern = catalogPatterns.get(i);
            String schemaPattern = schemaPatterns.get(i);
            String tablePattern = procedureNamePatterns.get(i);
            List<ProcedureType> procs = loadProcedures(catalogPattern, schemaPattern, tablePattern);
            if (procs != null) {
                procedures.addAll(loadProcedures(catalogPattern, schemaPattern, tablePattern));
            }
        }
        return procedures;
    }
    protected List<ProcedureType> loadProcedures(String originalCatalogPattern,
        String originalSchemaPattern, String originalProcedurePattern) {
        List<ProcedureType> dbStoredProcedures = null;
        boolean catalogMatchDontCare = false;
        DatabasePlatform platform = dbwsBuilder.getDatabasePlatform();
        if (platform instanceof MySQLPlatform ||
            platform instanceof DerbyPlatform ||
            platform instanceof PostgreSQLPlatform ) {
            // note that get info on other platforms that also require catalogMatchDontCare = true
            catalogMatchDontCare = true;
        }
        String catalogPattern = escapePunctuation(originalCatalogPattern);
        String schemaPattern = escapePunctuation(originalSchemaPattern);
        String procedurePattern = escapePunctuation(originalProcedurePattern);
        // Make sure procedure(s) is/are available
        ResultSet procsInfo = null;
        try {
            DatabaseMetaData databaseMetaData = getDatabaseMetaData(dbwsBuilder.getConnection());
            procsInfo = databaseMetaData.getProcedures(catalogPattern, schemaPattern, procedurePattern);
            // did we get a hit?
            if (procsInfo != null) {
                List<ProcedureType> tmpProcs = new ArrayList<ProcedureType>();
                while (procsInfo.next()) {
                    String actualCatalogName = procsInfo.getString(PROCS_INFO_CATALOG);
                    String actualSchemaName = procsInfo.getString(PROCS_INFO_SCHEMA);
                    String actualProcedureName = procsInfo.getString(PROCS_INFO_NAME);
                    short procedureType = procsInfo.getShort(PROCS_INFO_TYPE);
                    ProcedureType dbStoredProcedure;
                    if (procedureType == procedureReturnsResult) {
                        dbStoredProcedure = new FunctionType(actualProcedureName);
                    }
                    else {
                        dbStoredProcedure = new ProcedureType(actualProcedureName);
                    }
                    if (actualCatalogName != null && actualCatalogName.length() > 0) {
                        dbStoredProcedure.setCatalogName(actualCatalogName);
                    }
                    if (actualSchemaName != null && actualSchemaName.length() > 0) {
                        dbStoredProcedure.setSchema(actualSchemaName);
                    }
                    tmpProcs.add(dbStoredProcedure);
                }
                procsInfo.close();
                /* new a temp bucket to hold DbStoredArgs until they can be sorted out with respect
                 * to which DbStoredProcedure owns which args; this has to be done because Oracle can
                 * return multiple hits across multiple packages for the same procedureName.
                 */
                int numProcs = tmpProcs.size();
                if (numProcs > 0) {
                    dbStoredProcedures = new ArrayList<ProcedureType>(numProcs);
                    ResultSet procedureColumnsInfo = null;
                    procedureColumnsInfo = databaseMetaData.getProcedureColumns(catalogPattern,
                        schemaPattern, procedurePattern, "%");
                    while (procedureColumnsInfo.next()) {
                        String actualCatalogName = procedureColumnsInfo.getString(PROC_COLS_INFO_CATALOG);
                        String actualSchemaName = procedureColumnsInfo.getString(PROC_COLS_INFO_SCHEMA);
                        String actualProcedureName = procedureColumnsInfo.getString(PROC_COLS_INFO_NAME);
                        String argName = procedureColumnsInfo.getString(PROC_COLS_INFO_COLNAME);
                        // some MySql drivers return empty string, some return null: set to emptyString regardless
                        if (argName == null) {
                            argName = "";
                        }
                        ArgumentType dbStoredArgument = new ArgumentType(argName);
                        short inOut = procedureColumnsInfo.getShort(PROC_COLS_INFO_TYPE);
                        if (inOut == procedureColumnInOut) {
                            dbStoredArgument.setDirection(INOUT);
                        }
                        else if (inOut == procedureColumnOut) {
                            dbStoredArgument.setDirection(OUT);
                        }
                        else if (inOut == procedureColumnReturn) {
                            dbStoredArgument.setDirection(RETURN);
                        } else {
                            // default to ArgumentTypeDirection.IN
                            dbStoredArgument.setDirection(IN);
                        }

                        int jdbcType = procedureColumnsInfo.getInt(PROC_COLS_INFO_DATA_TYPE);
                        int precision = procedureColumnsInfo.getInt(PROC_COLS_INFO_PRECISION);
                        int scale = procedureColumnsInfo.getInt(PROC_COLS_INFO_SCALE);

                        dbStoredArgument.setEnclosedType(buildTypeForJDBCType(jdbcType, precision, scale));

                        // find matching DbStoredProcedure
                        // this dbStoredArgument belongs to a 'regular' procedure
                        ProcedureType matchingProc = null;
                        for (int i = 0; i < tmpProcs.size();) {
                            ProcedureType tmpProc = tmpProcs.get(i);
                            if (matches(tmpProc, actualCatalogName, actualSchemaName,
                                actualProcedureName, false, catalogMatchDontCare)) {
                                matchingProc = tmpProc;
                                dbStoredProcedures.add(matchingProc);
                                break;
                            }
                            i++;
                        }
                        if (matchingProc == null) {
                            // look in dbStoredProcedures - matching proc already moved over ?
                            for (ProcedureType dbStoredProcedure: dbStoredProcedures) {
                                if (matches(dbStoredProcedure, actualCatalogName, actualSchemaName,
                                    actualProcedureName, false, catalogMatchDontCare)) {
                                    matchingProc = dbStoredProcedure;
                                    break;
                                }
                            }
                        }
                        if (matchingProc != null) {
                            if (matchingProc.isFunctionType() && dbStoredArgument.getArgumentName().equalsIgnoreCase("")) {
                                ((FunctionType)matchingProc).setReturnArgument(dbStoredArgument);
                            }
                            else {
                                matchingProc.getArguments().add(dbStoredArgument);
                            }
                            tmpProcs.remove(matchingProc);
                        }
                        // else some argument that doesn't have a matching proc? ignore for now
                    }
                    procedureColumnsInfo.close();
                    if (!tmpProcs.isEmpty()) {
                        // leftovers are the no-arg procedures
                        dbStoredProcedures.addAll(tmpProcs);
                    }
                }
            }
        }
        catch (SQLException sqlException) {
            throw new IllegalStateException("failure retrieving Stored Procedure metadata",
                sqlException);
        }
        if (dbStoredProcedures != null && !dbStoredProcedures.isEmpty()) {
            Collections.sort(dbStoredProcedures, new Comparator<ProcedureType>() {
                @Override
                public int compare(ProcedureType o1, ProcedureType o2) {
                    String name1 = o1.getProcedureName();
                    String name2 = o2.getProcedureName();
                    if (!name1.equals(name2)) {
                        return name1.compareTo(name2);
                    }
                    else {
                        return o1.getOverload() - o2.getOverload();
                    }
                }
            });
        }
        return dbStoredProcedures;
    }

    static DatabaseMetaData getDatabaseMetaData(Connection connection) {
        if (connection == null) {
            // without a connection we cannot retrieve the metadata
            throw new IllegalStateException("Connection is null - cannot retrieve JDBC metadata");
        }
        DatabaseMetaData databaseMetaData = null;
        try {
            databaseMetaData = connection.getMetaData();
        } catch (SQLException sqlException) {
            // without metadata, there is nothing to do here
            throw new IllegalStateException("failure retrieving JDBC metadata", sqlException);
        }
        return databaseMetaData;
    }

    public static boolean matches(ProcedureType proc, String catalog, String schema, String name, boolean isOracle,
            boolean catalogMatchDontCare) {

        // return true if all 3 match, sorta

        boolean catalogMatch =
                proc.getCatalogName() == null ?
                // for Oracle, catalog matching is 'dont-care' only if null
                (isOracle ? true :
                // other platforms: null has to match null
               (catalog == null))
                : proc.getCatalogName().equals(catalog);
        // but catalogDontCare trumps!
        if (catalogMatchDontCare) {
            catalogMatch = true;
        }
        boolean schemaMatch =
            // either they are both null or they match
            proc.getSchema() == null ? (schema == null)
                : proc.getSchema().equals(schema);
        boolean nameMatch =
            // either they are both null or they match
            proc.getProcedureName() == null ? (name == null)
                : proc.getProcedureName().equals(name);
        return catalogMatch && schemaMatch && nameMatch;
    }

    @Override
    public void addToOROXProjectsForComplexTypes(List<CompositeDatabaseType> types, Project orProject, Project oxProject) {
    }
    @Override
    protected void buildQueryForProcedureType(ProcedureType procType, Project orProject, Project oxProject, ProcedureOperationModel opModel, boolean hasComplexArgs) {
    }
}
