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

// Contributors:
//     Mike Norman - from Proof-of-concept, become production code
package dbws.testing.shadowddlgeneration.oldjpub;

import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_ARGUMENTS;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_COLL_TYPES;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_OBJECTS;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_TYPES;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ALL_TYPE_ATTRS;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ATTR_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ATTR_TYPE_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.DEFAULT_VARCHAR_LEN;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.ELEM_TYPE_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.IS_COLLECTION;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.IS_PACKAGE;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.IS_TOPLEVEL;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.IS_TYPE;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.MAX_IDENTIFIER_LENGTH;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.OBJECT_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.OVERLOAD;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.OWNER;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.PACKAGE_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.TOPLEVEL;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.TYPE_NAME;
import static dbws.testing.shadowddlgeneration.oldjpub.Util.getDefaultTypeLen;

//javase imports
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/*
 * SQL Type Reflection Facility
 */
public class SqlReflector {

    public static final String CHAR_CS = "CHAR_CS";
    public static final String NCHAR_CS = "NCHAR_CS";
    public static final String ROWTYPE = "ROWTYPE";
    public static final String ROWTYPE_PL = ROWTYPE + "_PL";
    public static final String ROWTYPE_SQL = ROWTYPE + "_SQL";
    private static final int MAGIC_NUMBER = 0;

    public static final SqlType BFILE_TYPE = new SqlType("BFILE", OracleTypes.BFILE);
    public static final SqlType BINARY_INTEGER_TYPE =
    // new SqlType("BINARY_INTEGER", OracleTypes.INTEGER);
    new SqlType(new SqlName("BINARY_INTEGER", "INTEGER"), OracleTypes.INTEGER);
    public static final SqlType BLOB_TYPE = new SqlType("BLOB", OracleTypes.BLOB);
    // public static final SqlType BOOLEAN_TYPE =
    // new SqlType("BOOLEAN", SqlType.OracleTypes_BOOLEAN);
    public static final SqlType CHAR_TYPE = new SqlType("CHAR", OracleTypes.CHAR);
    public static final SqlType CLOB_TYPE = new SqlType("CLOB", OracleTypes.CLOB);
    public static final SqlType DATE_TYPE = new SqlType("DATE", OracleTypes.DATE);
    public static final SqlType NCHAR_TYPE = new SqlType("NCHAR", SqlType.ORACLE_TYPES_NCHAR);
    public static final SqlType NCLOB_TYPE = new SqlType("NCLOB", SqlType.ORACLE_TYPES_NCLOB);
    /*
     * public static final SqlType TIME_TYPE = new SqlType("TIME", OracleTypes.TIME); public static
     * final SqlType TIME_WTZ_TYPE = new SqlType("TIME WITH TIME ZONE", OracleTypes.TIME); public
     * static final SqlType TIMETZ_TYPE = // alternate spelling new SqlType("TIME WITH TZ",
     * OracleTypes.TIME);
     */
    public static final SqlType TIMESTAMP_TYPE = new SqlType("TIMESTAMP", OracleTypes.TIMESTAMP);
    public static final SqlType TIMESTAMP_WTZ_TYPE =
        new SqlType("TIMESTAMP WITH TZ", -101 ); // ==OracleTypes.TIMESTAMPTZ
    public static final SqlType TIMESTAMPTZ_TYPE = // alternate spelling
        new SqlType("TIMESTAMP WITH TIME ZONE", -101 ); // ==OracleTypes.TIMESTAMPTZ
    public static final SqlType TIMESTAMPTZ_TYPE0 = // alternate spelling
        new SqlType("TIMESTAMPTZ", -101 ); // ==OracleTypes.TIMESTAMPTZ
    public static final SqlType TIMESTAMP_WLTZ_TYPE =
        new SqlType("TIMESTAMP WITH LOCAL TZ", -102 ); // ==OracleTypes.TIMESTAMPLTZ
    public static final SqlType TIMESTAMPLTZ_TYPE = // alternate spelling
    new SqlType("TIMESTAMP WITH LOCAL TIME ZONE", -102 ); // ==OracleTypes.TIMESTAMPLTZ
    public static final SqlType TIMESTAMPLTZ_TYPE0 = // alternate spelling
    new SqlType("TIMESTAMPLTZ", -102 ); // ==OracleTypes.TIMESTAMPLTZ
    public static final SqlType DECIMAL_TYPE = new SqlType("DECIMAL", OracleTypes.DECIMAL);
    public static final SqlType DOUBLE_PRECISION_TYPE = new SqlType("DOUBLE PRECISION",
        OracleTypes.DOUBLE);
    public static final SqlType FLOAT_TYPE = new SqlType("FLOAT", OracleTypes.FLOAT);
    public static final SqlType FLOAT38TYPE = new SqlType("FLOAT38", OracleTypes.NUMBER);
    // TBD: Using the two types, 101 (OracleTypes.BDOUBLE),
    // 100 (OracleType.BFLOAT), results in <unsupported type>,
    // e.g., for the command
    // jpub -u scott/tiger -sql=sys.xmltype:XMLType
    public static final SqlType BINARY_DOUBLE_TYPE = new SqlType("BINARY_DOUBLE", 101); // OracleTypes.BDOUBLE
    public static final SqlType BINARY_FLOAT_TYPE = new SqlType("BINARY_FLOAT", 100); // OracleTypes.BFLOAT
    // Note: not referencing OracleTypes.BDOULBE and BFLOAT is
    // to avoid incompatible with pre-10i JDBC drivers
    public static final SqlType INTEGER_TYPE = new SqlType("INTEGER", OracleTypes.INTEGER);
    public static final SqlType INT_TYPE = new SqlType("INT", OracleTypes.INTEGER);
    public static final SqlType LONG_TYPE =
    // new SqlType("LONG", OracleTypes.LONGVARBINARY);
    new SqlType(new SqlName("LONG", "VARCHAR2"), OracleTypes.VARCHAR);
    public static final SqlType LONG_RAW_TYPE =
    // new SqlType("LONG RAW", OracleTypes.RAW);
    new SqlType(new SqlName("LONG RAW", "RAW"), OracleTypes.RAW);
    public static final SqlType NUMBER_TYPE = new SqlType("NUMBER", OracleTypes.NUMBER);
    public static final SqlType NUMERIC_TYPE = new SqlType("NUMERIC", OracleTypes.NUMERIC);
    public static final SqlType NVARCHAR2_TYPE = new SqlType("NVARCHAR2",
        SqlType.ORACLE_TYPES_NCHAR);
    public static final SqlType PLS_INTEGER_TYPE =
    // new SqlType("PLS_INTEGER", OracleTypes.INTEGER);
    new SqlType(new SqlName("PLS_INTEGER", "INTEGER"), OracleTypes.INTEGER);
    // public static final SqlType PLSQL_RECORD_TYPE =
    // new SqlType("PL/SQL RECORD", OracleTypes.UNSUPPORTED);
    public static final SqlType RAW_TYPE = new SqlType("RAW", OracleTypes.RAW);
    public static final SqlType REAL_TYPE = new SqlType("REAL", OracleTypes.REAL);
    public static final SqlType REF_CURSOR_TYPE = new SqlType("REF CURSOR", OracleTypes.CURSOR);
    public static final SqlType PLSQL_REF_CURSOR_TYPE = new SqlType("PL/SQL REF CURSOR",
        OracleTypes.CURSOR);
    public static final SqlType ROWID_TYPE =
    // new SqlType("ROWID", OracleTypes.ROWID);
    new SqlType(new SqlName("ROWID", "VARCHAR2"), OracleTypes.VARCHAR);
    public static final SqlType SMALLINT_TYPE = new SqlType("SMALLINT", OracleTypes.SMALLINT);
    public static final SqlType STRING_TYPE = new SqlType("STRING", OracleTypes.VARCHAR);
    public static final SqlType UROWID_TYPE =
    // new SqlType("UROWID", OracleTypes.ROWID);
    new SqlType(new SqlName("UROWID", "VARCHAR2"), OracleTypes.VARCHAR);
    public static final SqlType VARCHAR_TYPE = new SqlType("VARCHAR", OracleTypes.VARCHAR);
    public static final SqlType VARCHAR2_TYPE = new SqlType("VARCHAR2", OracleTypes.VARCHAR);
    public static SqlType plsqlTableDouble = null;
    public static SqlType plsqlTableFloat = null;
    public static SqlType plsqlTableInt = null;
    public static SqlType plsqlTableShort = null;
    public static SqlType plsqlTableJldouble = null;
    public static SqlType plsqlTableJlfloat = null;
    public static SqlType plsqlTableJlinteger = null;
    public static SqlType plsqlTableJlshort = null;
    public static SqlType plsqlTableJmbigdecimal = null;
    public static SqlType plsqlTableString = null;
    public static final SqlType UNKNOWN_TYPE = new SqlType("<unknown type or type not found>",
        OracleTypes.UNSUPPORTED);

    protected ViewCacheManager m_viewCacheManager;
    protected ViewCache m_viewCache;
    protected Connection m_conn;
    protected Boolean m_isPre920 = null;
    protected boolean m_geq9i;
    protected boolean m_transitive = true;
    protected String m_user;
    // A hashtable holding both predefined types and user types
    // for quick looking up.
    protected Map<Name, TypeClass> m_allTypes;
    protected Map<Name, TypeClass> m_predefTypes;
    /*
     * User types to be published can be added into m_userTypes in difference phases of publishing:
     * (1) First the types specified by the -sql option in the jpub command line are added (2)
     * JavaPublisher starts to publish the types in m_userTypes (3) When publishing a type, the
     * types on which that types depend on are reflected and added to the m_userTypes (4) On
     * finishing a type, JavaPublisher publishes the next type in the m_userTypes list. The
     * publishing order seems to be breadth-first.
     */
    protected List<TypeClass> m_userTypes;
    // -overwritedbtypes=false
    protected HashSet<String> m_allTypeNames;
    protected HashSet<String> m_allGeneratedTypeNames;
    protected int m_allGeneratedTypeNamesMagicNumber;
    protected Map<String, String> m_allDefaultArgsHolderTypeNames;
    protected HashSet<String>m_isReused;
    protected boolean m_getTypeCodeWarning = false;
    protected SqlStmtType m_sqlStmtType;
    protected int m_rowtypeDistinguisher = 0;
    protected WrapperPackageMetadata m_wrapperPackageMetadata;
    protected Map<String, SqlType> m_typeMap = new HashMap<String, SqlType>();

    public SqlReflector(Connection conn, String user) {
        m_viewCacheManager = new ViewCacheManager(conn);
        m_user = user;
        reset(conn);
    }

    public void reset(Connection conn) {
        if (m_conn != null) {
            try {
                m_conn.close();
            }
            catch (SQLException e) {
                // Closing resources. OK to ignore exception.
            }
        }
        m_conn = conn;

        m_viewCache = m_viewCacheManager.get(m_user);
        if (m_viewCache == null) {
            m_viewCache = new ViewCache(m_conn, m_user);
            m_viewCacheManager.add(m_viewCache);
        }
        else {
            m_viewCache.reset(m_conn);
        }

        m_allTypes = new HashMap<Name, TypeClass>();
        m_predefTypes = new HashMap<Name, TypeClass>();
        m_userTypes = new ArrayList<TypeClass>();
        sqlTypeInit();

        m_allTypeNames = new HashSet<String>();
        m_allGeneratedTypeNames = new HashSet<String>();
        m_allGeneratedTypeNamesMagicNumber = MAGIC_NUMBER;
        m_allDefaultArgsHolderTypeNames = new HashMap<String, String>();
        m_sqlStmtType = null;

        m_isReused = new HashSet<String>();
        m_wrapperPackageMetadata = null;

        if (conn != null) {
            m_geq9i = SqlReflector.geqOracle9(conn);
        }
    }

    public void loadAllTypeNames() {
        try {
            Iterator<ViewRow> iter = m_viewCache.getRows(ALL_TYPES, new String[]{TYPE_NAME},
                new String[0], new Object[0], new String[0]);
            while (iter.hasNext()) {
                SingleColumnViewRow row = (SingleColumnViewRow)iter.next();
                m_allTypeNames.add(row.getValue());
            }
        }
        catch (Exception e) { /* Cannot access ALL_TYPES table */
            e.printStackTrace();;
        }
    }

    // Determine the SQL type name for a PL/SQL type
    public String determineSqlName(String packageName, String[] sourceName, TypeClass parentType,
        boolean[] isRowType, List<AttributeField> fields, SqlType elemType, SqlType valueType)
        throws SQLException {
        String parentName = null; // Java name for the PL/SQL package
        if (parentType != null) {
            SqlName parentSqlName = (SqlName)parentType.getNameObject();
            if (parentSqlName != null) {
                parentName = parentSqlName.getTypeName().toUpperCase();
            }
        }
        String name = sourceName[0];
        m_allGeneratedTypeNames.add(name);
        if (name.indexOf('.') >= 0 && parentName != null) {
            // Replace the package name with the correpsonding Java name
            name = parentName + "_" + name.substring(name.indexOf('.') + 1);
            m_allGeneratedTypeNames.add(parentName);
        }
        name = name.replace('.', '_').replace(' ', '_');

        boolean toBeDistinguished = false;
        if (sourceName[0].equals("PL/SQL RECORD")) { // %ROWTYPE
            isRowType[0] = true;
            sourceName[0] = ROWTYPE_PL + (m_rowtypeDistinguisher++);
            name = ROWTYPE_SQL;
            if (packageName != null && !packageName.equals("")) {
                if (parentName != null) {
                    name = parentName + "_" + name;
                }
                else {
                    name = packageName + "_" + name;
                }
            }
            toBeDistinguished = true;
        }
        return determineSqlName(name, toBeDistinguished, fields, elemType, valueType);
    }

    private String determineSqlName(String name, boolean toBeDistinguished,
        List<AttributeField> fields, SqlType elemType, SqlType valueType) throws SQLException {

        String origName = name;
        if (valueType != null) {
            String uniqueName = m_allDefaultArgsHolderTypeNames.get(origName);
            if (uniqueName != null) {
                return uniqueName;
            }
        }

        if (m_allTypeNames.contains(name)) {
            boolean match = true;
            Iterator<ViewRow> iter;
            if (fields != null) {
                HashSet<String> hs = new HashSet<String>();
                for (int i = 0; i < fields.size(); i++) {
                    AttributeField af = fields.get(i);
                    String fieldType = ((SqlName)af.getType().getNameObject())
                        .getTargetTypeName();
                    hs.add(fieldType + af.getName());
                }
                iter = m_viewCache.getRows(ALL_TYPE_ATTRS, new String[]{"CONCAT("
                    + ATTR_TYPE_NAME + "," + ATTR_NAME + ")"},
                    new String[]{TYPE_NAME}, new Object[]{name}, new String[0]);
                int count = 0;
                while (iter.hasNext()) {
                    String attr = ((SingleColumnViewRow)iter.next()).getValue();
                    if (!hs.contains(attr)) {
                        match = false;
                    }
                    count++;
                }
                match = match && (count == hs.size());
            }
            else if (elemType != null) {
                iter = m_viewCache.getRows(ALL_COLL_TYPES, new String[]{ELEM_TYPE_NAME},
                    new String[]{TYPE_NAME}, new Object[]{name}, new String[0]);
                if (iter.hasNext()) {
                    String elemTypeNameInDb = ((SingleColumnViewRow)iter.next()).getValue();
                    String elemTypeName = elemType.getSqlName().getTargetTypeName();
                    match = elemTypeNameInDb.equalsIgnoreCase(elemTypeName);
                }
                else {
                    match = false;
                }
            }
            else if (valueType != null) {
                iter = m_viewCache.getRows(ALL_TYPE_ATTRS, new String[]{ATTR_TYPE_NAME},
                    new String[]{TYPE_NAME}, new Object[]{name}, new String[0]);
                if (iter.hasNext()) {
                    String valueTypeNameInDb = ((SingleColumnViewRow)iter.next()).getValue();
                    String valueTypeName = valueType.getSqlName().getTargetTypeName();
                    match = valueTypeNameInDb.equalsIgnoreCase(valueTypeName);
                }
                else {
                    match = false;
                }
            }
            if (match) {
                m_isReused.add(name);
                return name;
            }
        }
        String uniqueName = name.toUpperCase();
        if (m_allTypeNames.contains(uniqueName)
            || (toBeDistinguished && m_allGeneratedTypeNames.contains(uniqueName))) {
            do {
                int len1 = name.length();
                int len2 = Integer.toString(m_allGeneratedTypeNamesMagicNumber++).length();
                if ((len1 + len2) > MAX_IDENTIFIER_LENGTH) {
                    name = name.substring(0, MAX_IDENTIFIER_LENGTH - len2);
                }
                uniqueName = name.toUpperCase() + m_allGeneratedTypeNamesMagicNumber;
            }
            while (m_allTypeNames.contains(uniqueName)
                || (toBeDistinguished && m_allGeneratedTypeNames.contains(uniqueName)));
        }
        m_allGeneratedTypeNames.add(uniqueName);
        if (valueType != null) {
            m_allDefaultArgsHolderTypeNames.put(origName, uniqueName);
        }

        return uniqueName;
    }

    void addAllGeneratedTypeNames(String name) {
        m_allGeneratedTypeNames.add(name.toUpperCase());
    }

    public boolean isReused(String name) {
        return m_isReused.contains(name);
    }

    /*
     * public String determineDefaultArgsHolderSqlName(String name) throws SQLException { String
     * unique = (String) m_allDefaultArgsHolderTypeNames.get(name); if (unique == null) { unique =
     * determineSqlName( name, true, null , null , name); m_allDefaultArgsHolderTypeNames.put(name,
     * unique); } return unique; }
     */
    public void setViewCachePoolCapacity(int size) {
        m_viewCacheManager.setViewCachePoolCapacity(size);
    }

    private void sqlTypeInit() {
        if (!m_allTypes.isEmpty()) {
            m_allTypes = new HashMap<Name, TypeClass>();
        }
        m_allTypes.put(BFILE_TYPE.m_name, BFILE_TYPE);
        m_allTypes.put(BINARY_INTEGER_TYPE.m_name, BINARY_INTEGER_TYPE);
        m_allTypes.put(BLOB_TYPE.m_name, BLOB_TYPE);
        // m_allTypes.put(BOOLEAN_TYPE.m_name, BOOLEAN_TYPE);
        m_allTypes.put(CHAR_TYPE.m_name, CHAR_TYPE);
        m_allTypes.put(CLOB_TYPE.m_name, CLOB_TYPE);
        m_allTypes.put(DATE_TYPE.m_name, DATE_TYPE);
        m_allTypes.put(NCHAR_TYPE.m_name, NCHAR_TYPE);
        m_allTypes.put(NCLOB_TYPE.m_name, NCLOB_TYPE);
        /*
         * m_allTypes.put(TIME_TYPE.m_name, TIME_TYPE);
         * m_allTypes.put(TIME_WTZ_TYPE.m_name,TIME_WTZ_TYPE);
         * m_allTypes.put(TIMETZ_TYPE.m_name, TIMETZ_TYPE);
         */
        m_allTypes.put(TIMESTAMP_TYPE.m_name, TIMESTAMP_TYPE);
        m_allTypes.put(TIMESTAMP_WTZ_TYPE.m_name, TIMESTAMP_WTZ_TYPE);
        m_allTypes.put(TIMESTAMPTZ_TYPE.m_name, TIMESTAMPTZ_TYPE);
        m_allTypes.put(TIMESTAMPTZ_TYPE0.m_name, TIMESTAMPTZ_TYPE0);
        m_allTypes.put(TIMESTAMP_WLTZ_TYPE.m_name, TIMESTAMP_WLTZ_TYPE);
        m_allTypes.put(TIMESTAMPLTZ_TYPE.m_name, TIMESTAMPLTZ_TYPE);
        m_allTypes.put(TIMESTAMPLTZ_TYPE0.m_name, TIMESTAMPLTZ_TYPE0);
        /*
         * m_allTypes.put(INTERVAL_YM_TYPE.m_name, INTERVAL_YM_TYPE);
         * m_allTypes.put(INTERVAL_YM_TYPE.m_name, INTERVAL_YM_TYPE);
         */
        m_allTypes.put(DECIMAL_TYPE.m_name, DECIMAL_TYPE);
        m_allTypes.put(BINARY_DOUBLE_TYPE.m_name, BINARY_DOUBLE_TYPE);
        m_allTypes.put(DOUBLE_PRECISION_TYPE.m_name, DOUBLE_PRECISION_TYPE);
        m_allTypes.put(FLOAT_TYPE.m_name, FLOAT_TYPE);
        m_allTypes.put(FLOAT38TYPE.m_name, FLOAT38TYPE);
        m_allTypes.put(BINARY_FLOAT_TYPE.m_name, BINARY_FLOAT_TYPE);
        m_allTypes.put(INTEGER_TYPE.m_name, INTEGER_TYPE);
        m_allTypes.put(INT_TYPE.m_name, INT_TYPE);
        m_allTypes.put(LONG_TYPE.m_name, LONG_TYPE);
        m_allTypes.put(LONG_RAW_TYPE.m_name, LONG_RAW_TYPE);
        m_allTypes.put(NUMBER_TYPE.m_name, NUMBER_TYPE);
        m_allTypes.put(NUMERIC_TYPE.m_name, NUMERIC_TYPE);
        m_allTypes.put(NVARCHAR2_TYPE.m_name, NVARCHAR2_TYPE);
        m_allTypes.put(PLS_INTEGER_TYPE.m_name, PLS_INTEGER_TYPE);
        m_allTypes.put(RAW_TYPE.m_name, RAW_TYPE);
        m_allTypes.put(REAL_TYPE.m_name, REAL_TYPE);
        m_allTypes.put(REF_CURSOR_TYPE.m_name, REF_CURSOR_TYPE);
        m_allTypes.put(PLSQL_REF_CURSOR_TYPE.m_name, PLSQL_REF_CURSOR_TYPE);
        m_allTypes.put(ROWID_TYPE.m_name, ROWID_TYPE);
        m_allTypes.put(SMALLINT_TYPE.m_name, SMALLINT_TYPE);
        m_allTypes.put(STRING_TYPE.m_name, STRING_TYPE);
        m_allTypes.put(UROWID_TYPE.m_name, UROWID_TYPE);
        m_allTypes.put(VARCHAR_TYPE.m_name, VARCHAR_TYPE);
        m_allTypes.put(VARCHAR2_TYPE.m_name, VARCHAR2_TYPE);

        String name;
        SqlName sqlName;

        name = "PLSQL_TABLE_DOUBLE";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "double[]", null, "double[]", null));
        plsqlTableDouble = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_FLOAT";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "float[]", null, "float[]", null));
        plsqlTableFloat = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_INT";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "int[]", null, "int[]", null));
        plsqlTableInt = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_SHORT";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "short[]", null, "short[]", null));
        plsqlTableShort = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JLDOUBLE";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "Double[]", null, "Double[]", null));
        plsqlTableJldouble = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JLFLOAT";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "Float[]", null, "Float[]", null));
        plsqlTableJlfloat = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JLINTEGER";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "Integer[]", null, "Integer[]", null));
        plsqlTableJlinteger = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JLSHORT";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "Short[]", null, "Short[]", null));
        plsqlTableJlshort = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JLINTEGER";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "Integer[]", null, "Integer[]", null));
        plsqlTableJlinteger = new PlsqlIndexTableType(sqlName, true);

        name = "PLSQL_TABLE_JMBIGDECIMAL";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "java.math.BigDecimal[]", null,
            "java.math.BigDecimal[]", null));
        plsqlTableJmbigdecimal = new PlsqlIndexTableType(sqlName, true);
        name = "PLSQL_TABLE_STRING";
        sqlName = new SqlName(name, name);
        sqlName.setAnnotation(new JavaName("", "String[]", null, "String[]", null));
        plsqlTableString = new PlsqlIndexTableType(sqlName, false);

        m_allTypes.put(plsqlTableDouble.m_name, plsqlTableDouble);
        m_allTypes.put(plsqlTableFloat.m_name, plsqlTableFloat);
        m_allTypes.put(plsqlTableInt.m_name, plsqlTableInt);
        m_allTypes.put(plsqlTableShort.m_name, plsqlTableShort);
        m_allTypes.put(plsqlTableJldouble.m_name, plsqlTableJldouble);
        m_allTypes.put(plsqlTableJlfloat.m_name, plsqlTableJlfloat);
        m_allTypes.put(plsqlTableJlshort.m_name, plsqlTableJlshort);
        m_allTypes.put(plsqlTableJlinteger.m_name, plsqlTableJlinteger);
        m_allTypes.put(plsqlTableJmbigdecimal.m_name, plsqlTableJmbigdecimal);
        m_allTypes.put(plsqlTableString.m_name, plsqlTableString);
        String hint = "/*[32767]*/";
        plsqlTableDouble.setHint(hint);
        plsqlTableFloat.setHint(hint);
        plsqlTableInt.setHint(hint);
        plsqlTableShort.setHint(hint);
        plsqlTableJldouble.setHint(hint);
        plsqlTableJlfloat.setHint(hint);
        plsqlTableJlinteger.setHint(hint);
        plsqlTableJlshort.setHint(hint);
        plsqlTableString.setHint(hint);
        plsqlTableJmbigdecimal.setHint(hint);

        m_allTypes.put(UNKNOWN_TYPE.m_name, UNKNOWN_TYPE);
    }

    public Connection getConnection() {
        return m_conn;
    }

    public SqlType addSqlType(SqlName sqlName, int whatIsIt, boolean mustBeNew, boolean generateMe,
        SqlType parentType, String modifier) throws SQLException, PublisherException {
        return addSqlType(sqlName, whatIsIt, mustBeNew, generateMe, parentType, modifier, false,
            null);
    }

    public SqlType addSqlType(SqlName sqlName, int whatIsIt, boolean mustBeNew, boolean generateMe,
        SqlType parentType, String modifier, boolean ncharFormOfUse, MethodFilter signatureFilter)
        throws SQLException, PublisherException {
        SqlType result = null;
        try {
            if (ncharFormOfUse) {
                if (sqlName.getTypeName().equals("CHAR")) {
                    sqlName = NCHAR_TYPE.getSqlName();
                }
                else if (sqlName.getTypeName().equals("VARCHAR2")) {
                    sqlName = NVARCHAR2_TYPE.getSqlName();
                }
                else if (sqlName.getTypeName().equals("CLOB")) {
                    sqlName = NCLOB_TYPE.getSqlName();
                }
            }

            SqlType t = findType(sqlName);
            boolean predefined = false;
            if (t == null) {
                t = findPredefType(sqlName);
                predefined = true;
            }

            if (t != null) {
                result = t;
                if (mustBeNew && predefined) {
                    throw new PublisherException("duplicate type " + result.toString());
                }
                else if (mustBeNew) {
                    t.setNameObject(sqlName);
                }
                return result;
            }

            String schema = sqlName.getSchemaName();
            String type = sqlName.getTypeName();
            if (whatIsIt == IS_TOPLEVEL) {
                return new SqlToplevelType(sqlName, parentType, signatureFilter, this);
            }
            else if ((whatIsIt & IS_PACKAGE) != 0) {
                Iterator<ViewRow> rowIter = m_viewCache.getRows(ALL_OBJECTS,
                    new String[]{"'PACKAGE' AS TYPECODE"}, new String[]{OWNER, OBJECT_NAME,
                        "OBJECT_TYPE", "STATUS"}, new Object[]{schema, type, "PACKAGE", "VALID"},
                    new String[0]);

                if (rowIter.hasNext()) {
                    m_viewCache.fetch(type, signatureFilter);
                    result = new SqlPackageType(sqlName, parentType, signatureFilter, this);
                }
                if (result != null) {
                    return result;
                }
                if (whatIsIt == IS_PACKAGE) {
                    throw new PublisherException("package not found " + sqlName.toString());
                }
            }

            /* determine whether this is an opaque type */
            Iterator<ViewRow> iter = m_viewCache.getRows(ALL_TYPES, new String[0], new String[]{
                OWNER, TYPE_NAME, "PREDEFINED"}, new Object[]{schema, type, "NO"},
                new String[0]);
            if (iter.hasNext()) {
                AllTypes allTypes = (AllTypes)iter.next();
                String typeCode = allTypes.typeCode;
                byte[] typeOID = allTypes.typeOid;
                int dbTypeCode = 0;
                int kind = 0;
                if (!m_getTypeCodeWarning) {
                    try {
                        Object[] outParams = m_viewCache.getOutParameters(
                            "BEGIN sys.sqljutl.get_typecode(:1, :2, :3, :4); END;",
                            new Object[]{typeOID}, new int[]{OracleTypes.INTEGER,
                                OracleTypes.VARCHAR, OracleTypes.INTEGER});
                        if (outParams == null) {
                            throw new SQLException("no data from sqljutl.get_typecode call");
                        }
                        dbTypeCode = (Integer) outParams[0];
                        kind = (Integer) outParams[2];
                    }
                    catch (SQLException exn) {
                        String msg = exn.getMessage();
                        if (isPre920()) {
                            // an older database version will not have GET_TYPECODE
                            msg = null;
                            m_getTypeCodeWarning = true;
                        }
                        else if (msg.indexOf("PLS-00201") > 0) {
                            msg = "cannot determine type " + type;
                            m_getTypeCodeWarning = true;
                        }
                        else {
                            msg = "error determining type " + type;
                        }
                        if (msg != null) {
                            throw new PublisherException(msg);
                        }
                    }
                }

                if (dbTypeCode == SqlType.CODE_OPAQUE) {
                    result = new SqlObjectType(sqlName, OracleTypes.OPAQUE, generateMe, parentType,
                        this);
                }
                else if (dbTypeCode == SqlType.CODE_SQLJTYPE && kind != 0) {
                    result = new SqlSqljType(sqlName, kind, parentType, this);
                }
                else if (typeCode.equals("OBJECT")) {
                    result = new SqlObjectType(sqlName, generateMe, parentType, this);
                    if (SqlName.langIsOtt()) {
                        /*
                         * For C only. Maura - I'm not sure about this, but
                         * it seems that a ref typedef has to be generated
                         * for every struct. That's the purpose of the
                         * following SqlRefType
                         */
                        new SqlRefType(sqlName, result, parentType, generateMe, this);
                    }
                    if (PublisherModifier.isIncomplete(result.getModifiers())) {
                        /*
                         * give warning
                         * about incomplete
                         * type and
                         * continue
                         */
                        int line = sqlName.getLine();
                        int column = sqlName.getColumn();
                        String mesg = "incomplete type " + sqlName.toString();

                        if (line > 0 || column > 0) {
                            mesg = "" + line + "." + column + ": " + mesg;
                        }
                        System.err.println(mesg);
                    }
                }
                else if (typeCode.equals("COLLECTION")) {
                    if ((whatIsIt & IS_COLLECTION) == 0) {
                        throw new PublisherException("collection found " + sqlName.toString());
                    }
                    Iterator<ViewRow> iter3 = m_viewCache.getRows(ALL_COLL_TYPES, new String[0],
                        new String[]{OWNER, TYPE_NAME}, new Object[]{schema, type},
                        new String[0]);
                    if (iter3.hasNext()) {
                        AllCollTypes act = (AllCollTypes)iter3.next();
                        String collTypeCode = act.collType;
                        if (collTypeCode.equals("TABLE")) {
                            result = new SqlTableType(sqlName, generateMe, parentType, this);
                        }
                        else {
                            // "VARYING ARRAY"
                            result = new SqlArrayType(sqlName, generateMe, parentType, this);
                        }
                    }
                }
            }
            if (result != null) {
                return result;
            }
            else {
                // Note that this type is not supported, so we will not look
                // it up again.
                result = addPredefType(sqlName, OracleTypes.UNSUPPORTED);
                // Now add an error message
                if ((whatIsIt & IS_PACKAGE) != 0) {
                    throw new PublisherException("type not found " + sqlName.toString());
                }
            }
        }
        catch (SQLException e) {
            System.err.println(e.getMessage());
        }
        catch (PublisherException ex) {
            System.err.println(ex.getMessage());
        }
        return result;
    }

    public SqlType addSqlUserType(String schema, String type, int whatIsIt, boolean mustBeNew,
        int line, int col, MethodFilter signatureFilter) throws SQLException, PublisherException {
        SqlName sn = new SqlName(schema, type, false, line, col, this);
        return addSqlType(sn, whatIsIt, mustBeNew, true, null, null, false, signatureFilter);
    }

    private SqlType addSqlDBType(SqlName sqlName, String modifier, boolean ncharFormOfUse,
        SqlType parentType) throws SQLException, PublisherException {

        /* constructed types are not hashed */
        if (modifier != null && modifier.equals("REF")) {
            SqlType t = addSqlType(sqlName, IS_TYPE, false, m_transitive, parentType, modifier);
            SqlType rt = new SqlRefType(sqlName, t, parentType, m_transitive, this);
            return rt;
        }
        else {
            return addSqlType(sqlName, IS_TYPE, false, m_transitive, parentType, modifier,
                ncharFormOfUse, null);
        }
    }

    // Used for adding types other than PL/SQL types
    public SqlType addSqlDBType(String schema, String type, String subtype, String modifier,
        boolean ncharFormOfUse, SqlType parentType) throws SQLException, PublisherException {
        int line = 0;
        int col = 0;

        if (parentType != null) {
            SqlName psqlname = (SqlName)parentType.getNameObject();
            line = psqlname.getLine();
            col = psqlname.getColumn();
        }
        if (subtype != null) {
            if (type != null) {
                type = type + "." + subtype;
            }
            else {
                type = subtype;
            }
            if (schema != null) {
                type = schema + "." + type;
                schema = null;
            }
        }
        SqlName sn = new SqlName(schema, type, true, line, col, this);
        sn.setAnnotation(genPattern((LangName)sn.getAnnotation(), sn.getSimpleName(), true));

        return addSqlDBType(sn, modifier, ncharFormOfUse, parentType);
    }

    /*
     * Add SQL or PL/SQL types from PL/SQL packages (1) For SQL types, delegate to addSqlDBType (2)
     * For PL/SQL, create PlsqlRecorType or PlsqlTableType
     */
    public SqlType addPlsqlDBType(String schema, String type, String subtype, String modifier,
        boolean ncharFormOfUse, String packageName, String methodName, String methodNo,
        int sequence, SqlType parentType) throws SQLException, PublisherException {
        return addPlsqlDBType(schema, type, subtype, modifier, ncharFormOfUse, packageName,
            methodName, methodNo, sequence, parentType, false);
    }

    public SqlType addPlsqlDBType(String schema, String type, String subtype, String modifier,
        boolean ncharFormOfUse, String packageName, String methodName, String methodNo,
        int sequence, SqlType parentType, boolean isGrandparent) throws SQLException,
        PublisherException {
        int line = 0;
        int col = 0;

        if (parentType != null) {
            SqlName psqlname = (SqlName)parentType.getNameObject();
            line = psqlname.getLine();
            col = psqlname.getColumn();
        }
        if (subtype != null) {
            if (type != null) {
                type = type + "." + subtype;
            }
            else {
                type = subtype;
            }
            if (schema != null) {
                type = schema + "." + type;
                schema = null;
            }
        }
        // For SQL types, delegate to addSqlDBType
        if (modifier == null
            || (!modifier.equals("PL/SQL RECORD") && !modifier.equals("PL/SQL TABLE")
                && (!modifier.equals("TABLE") || (subtype == null && type.indexOf(".") == -1)) && (!modifier
                .equals("VARRAY") || (subtype == null && type.indexOf(".") == -1)))) {
            SqlName sn = new SqlName(schema, type, true, line, col, this);
            sn.setAnnotation(genPattern((LangName)sn.getAnnotation(), sn.getSimpleName(), true));
            return addSqlDBType(sn, modifier, ncharFormOfUse, parentType);
        }

        // Start processing PL/SQL types
        // Check wether the ROWTYPE has bee published
        List<RowtypeInfo> rowtypeInfoA = null;
        if (modifier != null && type != null && modifier.equals("PL/SQL RECORD")
            && type.equals("PL/SQL RECORD")) {
            rowtypeInfoA = reflectRowtypeInfo(packageName, methodName, methodNo, sequence);
            for (int i = 0; i < m_userTypes.size(); i++) {
                boolean found = true;
                TypeClass p = m_userTypes.get(i);
                if (!(p instanceof PlsqlRecordType)) {
                    continue;
                }
                List<RowtypeInfo> rowtypeInfoB = ((PlsqlRecordType)p).getRowtypeInfo();
                if (rowtypeInfoB == null || rowtypeInfoA == null
                    || rowtypeInfoA.size() != rowtypeInfoB.size()) {
                    found = false;
                    continue;
                }
                for (int ja = 0; ja < rowtypeInfoA.size(); ja++) {
                    boolean microFound = false;
                    for (int jb = 0; jb < rowtypeInfoB.size(); jb++) {
                        if (rowtypeInfoA.get(ja).equals(rowtypeInfoB.get(jb))) {
                            microFound = true;
                            break;
                        }
                    }
                    if (!microFound) {
                        found = false;
                        break;
                    }
                }
                if (found) {
                    return (SqlType)p;
                }
            }
        }

        // Create the PL/SQL type
        SqlType result = findPredefType(schema, type);
        boolean predefined = (result != null);
        if (!predefined) {
            result = findType(schema, type);
        }
        if (result != null) {
            if (result.getTypecode() != SqlType.ORACLE_TYPES_TBD) {
                return result;
            }
            else if (!predefined) {
                // Deals with PL/SQL types: Augument the predefined type
                // by -typemap with more specific PL/SQL type information.
                if (modifier != null && modifier.equals("PL/SQL RECORD")) {
                    result.setTypecode(OracleTypes.PLSQL_RECORD);
                }
                else if (modifier != null && modifier.equals("PL/SQL TABLE")) {
                    result.setTypecode(OracleTypes.PLSQL_INDEX_TABLE);
                }
                else if (modifier != null && modifier.equals("TABLE")) {
                    result.setTypecode(OracleTypes.PLSQL_NESTED_TABLE);
                }
                else if (modifier != null && modifier.equals("VARRAY")) {
                    result.setTypecode(OracleTypes.PLSQL_VARRAY_TABLE);
                }
                return result;
            }
        }

        // Case 1: result is null
        // Case 2: result not null, predefined, OracleTypes_TBD
        if (modifier != null && modifier.equals("PL/SQL RECORD")) {
            List<FieldInfo> fieldInfo = PlsqlRecordType.getFieldInfo(Util.getSchema(schema, type), packageName, methodName, methodNo,
                sequence, this);
            List<AttributeField> fields = SqlTypeWithFields.reflectFields(false, fieldInfo, this,
                parentType, true /* isGrandparent */);
            // if predefined, overwrite entry already in m_predefiendTypes
            if (predefined) {
                String hint = result.getHint();
                result = new PlsqlRecordType(result.getSqlName(), fieldInfo, fields, rowtypeInfoA,
                    false /* generateMe */, parentType, this);
                result.setHint(hint);
            }
            else {
                // Prepare SqlName for the PL/SQL type
                SqlName sqlName = new PlsqlRecordName(schema, type, true, line, col, packageName,
                    parentType, fields, this);
                sqlName.setAnnotation(genPattern((LangName)sqlName.getAnnotation(), sqlName
                    .getSimpleName(), true));

                result = new PlsqlRecordType(sqlName, fieldInfo, fields, rowtypeInfoA,
                    true /* generateMe */, parentType, this);
            }
        }
        else {
            int oracleType = OracleTypes.UNSUPPORTED;
            if (modifier != null && modifier.equals("PL/SQL TABLE")) {
                oracleType = OracleTypes.PLSQL_INDEX_TABLE;
            }
            else if (modifier != null && modifier.equals("TABLE") && type.indexOf(".") > -1) {
                oracleType = OracleTypes.PLSQL_NESTED_TABLE;
            }
            else if (modifier != null && modifier.equals("VARRAY") && type.indexOf(".") > -1) {
                oracleType = OracleTypes.PLSQL_VARRAY_TABLE;
            }
            if (oracleType != OracleTypes.UNSUPPORTED) {
                ElemInfo elemInfo = PlsqlTableType.getElemInfo(schema, type, packageName,
                    methodName, methodNo, m_viewCache);
                int[] details = new int[PlsqlTableType.NUMBER_OF_DETAILS];

                SqlType elemType = (SqlType)PlsqlTableType.getComponentType(elemInfo, this,
                    parentType, details);

                if (predefined) {
                    String hint = result.getHint();
                    result = PlsqlTableType.newInstance(result.getSqlName(), oracleType, elemInfo,
                        elemType, details, false, parentType, isGrandparent, this);
                    result.setHint(hint);
                }
                else {
                    // Prepare SqlName for the PL/SQL type
                    SqlName sqlName = new PlsqlTableName(schema, type, true, line, col,
                        packageName, parentType, elemType, this);
                    sqlName.setAnnotation(genPattern((LangName)sqlName.getAnnotation(), sqlName
                        .getSimpleName(), true));

                    result = PlsqlTableType.newInstance(sqlName, oracleType, elemInfo, elemType,
                        details, true, parentType, isGrandparent, this);
                }
            }
        }
        if (result != null) {
            return result;
        }
        throw new PublisherException("unsupported Type " + schema + "." + type);
    }

    /*
     * look up rowtype columns
     */
    List<RowtypeInfo> reflectRowtypeInfo(String packageName, String methodName, String methodNo,
        int sequence) throws SQLException {
        // Although package_name and type_name derived from getPlsqlTypeName()
        // can be used for the queries, we use method and sequence
        // to be more general. If this type is defined via CURSOR%ROWTYPE,
        // method, method_no and sequence has to be used to
        // identify this type in ALL_ARGUMENTS.
        Iterator<ViewRow> iter = m_viewCache.getRows(ALL_ARGUMENTS, new String[0], new String[]{
           PACKAGE_NAME, OBJECT_NAME, OVERLOAD}, new Object[]{packageName, methodName,
            methodNo}, new String[0]);
        ArrayList<ViewRow> viewRows = new ArrayList<ViewRow>();
        while (iter.hasNext()) { // DISTINCT not enforced
            UserArguments item = (UserArguments)iter.next();
            viewRows.add(item);
        }
        List<RowtypeInfo> rowtypeInfoA = RowtypeInfo.getRowtypeInfo(viewRows);
        int data_level = 0;
        for (int i = 0; i < rowtypeInfoA.size(); i++) {
            RowtypeInfo rti = rowtypeInfoA.get(i);
            if (sequence == -1 || sequence == rti.sequence()) {
                data_level = rti.data_level();
                break;
            }
        }
        int next_rec_sequence = -1;
        for (int i = 0; i < rowtypeInfoA.size(); i++) {
            RowtypeInfo rti = rowtypeInfoA.get(i);
            if (data_level == rti.data_level() && (sequence == -1 || sequence < rti.sequence())) {
                next_rec_sequence = rti.sequence();
                break;
            }
        }
        data_level++;
        ArrayList<RowtypeInfo> rowtypeInfoW = new ArrayList<RowtypeInfo>();
        for (int i = 0; i < rowtypeInfoA.size(); i++) {
            RowtypeInfo rti = rowtypeInfoA.get(i);
            if ((sequence == -1 || sequence < rti.sequence()) && data_level == rti.data_level()
            // && data_level <= rti.data_level()
                && (next_rec_sequence == -1 || next_rec_sequence > rti.sequence())) {
                rowtypeInfoW.add(rti);
            }
        }
        return rowtypeInfoW;
    }

    public SqlType addPredefType(String schema, String type, int typecode, String javaName,
        String convertInto, String convertOutOf, String conversionTarget) throws PublisherException {
        SqlName sn = new SqlName(schema, type, false, false, true, convertInto, convertOutOf,
            conversionTarget, this);

        // Does the Java type contain a type annotation?
        int pos;
        String annotation;
        boolean isPlsqlIndexTable = false;
        int maxLen = Integer.parseInt(DEFAULT_VARCHAR_LEN);
        int maxElemLen = -1;
        boolean isNumeric = true;
        if ((pos = javaName.indexOf("[")) >= 0) {
            annotation = "/*" + javaName.substring(pos).trim() + "*/";
            isPlsqlIndexTable = true;
            int pos1 = pos;
            int pos2 = javaName.indexOf("]");
            if (pos2 > -1) {
                try {
                    maxLen = Integer.parseInt(javaName.substring(pos1 + 1, pos2));
                }
                catch (NumberFormatException e) {
                    System.err.println("ERROR: number format error: " + javaName);
                }
            }
            pos1 = javaName.indexOf("(");
            pos2 = javaName.indexOf(")");
            if (pos1 > -1 && pos2 > -1) {
                try {
                    maxElemLen = Integer.parseInt(javaName.substring(pos1 + 1, pos2));
                }
                catch (NumberFormatException e) {
                    System.err.println("ERROR: number format error: " + javaName);
                }
            }
            javaName = javaName.substring(0, pos);
            if ("String".equals(javaName) || "java.lang.String".equals(javaName)) {
                isNumeric = false;
            }
            javaName = javaName + "[]";
            if (maxElemLen == -1) {
                maxElemLen = Integer.parseInt(getDefaultTypeLen("VARCHAR2"));
            }
        }
        else {
            annotation = "";
        }

        sn.setLangName(null, javaName, null, null, null, null, null, null, true);

        SqlType st = null;
        if (isPlsqlIndexTable) {
            st = new PlsqlIndexTableType(sn, isNumeric, maxLen, maxElemLen);
            m_predefTypes.put(sn, st);
        }
        else {
            st = addPredefType(sn, typecode);
        }
        st.setHint(annotation);
        return st;
    }

    public SqlType addPredefType(SqlName name, int typecode) throws PublisherException {
        // To determine whether the Java type implements ORAData or CustomData
        boolean isPrimitive = true;
        String declClassName = ((name.getDeclPackage() != null && name.getDeclPackage().length() > 0) ? (name
            .getDeclPackage() + ".")
            : "")
            + name.getDeclClass();
        Class<?> declClass = null;
        try {
            declClass = Class.forName(declClassName);
        }
        catch (Throwable t) {
            try {
                declClass = Class.forName("java.lang." + declClassName);
            }
            catch (Throwable t2) {
                // class did not check out as a primitive class
            }
        }
        if (declClass == null) {
            // Cannot load that class. Assume it is not primitive.
            isPrimitive = false;
        }
        else if (declClass != null) {
            try {
                declClass.getField("_SQL_TYPENAME");
                isPrimitive = false;
            }
            catch (Throwable t) {
                try {
                    declClass.getField("_SQL_NAME");
                    isPrimitive = false;
                }
                catch (Throwable t2) {
                    // class has neither _SQL_TYPENAME nor _SQL_NAME
                }
            }
        }
        if (declClassName.equals("boolean") || declClassName.equals("int")
            || declClassName.equals("short") || declClassName.equals("double")
            || declClassName.equals("float") || declClassName.equals("long")
            || declClassName.equals("byte") || declClassName.equals("char")
            || declClassName.endsWith("[]")) {
            isPrimitive = true;
        }

        if (typecode == OracleTypes.UNSUPPORTED || typecode == SqlType.ORACLE_TYPES_TBD) {
            if ("INTEGER".equals(name.getTargetTypeName())) {
                typecode = OracleTypes.INTEGER;
            }
            if ("CHAR".equals(name.getTargetTypeName())) {
                typecode = OracleTypes.CHAR;
            }
        }

        SqlType st = null;
        if (!isPrimitive) { // for sure this is a SQL Object Type
            try {
                st = new SqlObjectType(name, typecode, false, null, this);
            }
            catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
        else {
            st = new SqlType(name, typecode, false, isPrimitive, null, this);
        }
        if (st != null) {
            m_predefTypes.put(name, st);
        }
        else {
            throw new PublisherException("Cannot find Type " + name);
        }
        return st;
    }

    public void addType(Name name, TypeClass type, boolean generateMe) {
        if (generateMe) {
            m_userTypes.add(type);
        }
        if (name instanceof SqlName && type instanceof SqlType) {
            m_allTypes.put(name, type);
        }
    }

    /*
     * Add default parameter holder types for PL/SQL methods
     */
    public SqlType addDefaultArgsHolderType(SqlType valueType, String packageName,
        SqlType parentType, boolean ncharFormOfUse) throws SQLException, PublisherException {
        String typeName = "";
        if (valueType.getSqlName().getTypeName().indexOf(".") > -1) {
            typeName += valueType.getSqlName().getSimpleName();
        }
        else {
            typeName += valueType.getSqlName().getTypeName();
        }
        SqlName sqlName = new DefaultArgsHolderName(null, typeName, true, 0, 0, packageName,
            parentType, valueType, this);
        SqlType result = findType(sqlName);
        if (result == null) {
            sqlName.setAnnotation(genPattern((LangName)sqlName.getAnnotation(), sqlName
                .getSimpleName(), true));
            result = new DefaultArgsHolderType(sqlName, valueType, ncharFormOfUse, this);
        }
        return result;
    }

    public boolean isUserType(TypeClass t) {
        if (t instanceof SqlType) {
            for (int i = 0; i < m_userTypes.size(); i++) {
                if (m_userTypes.get(i).equals(t)) {
                    return true;
                }
            }
        }
        return false;
    }

    private SqlType findType(SqlName sqlName) {
        return _findType(m_allTypes, sqlName);
    }

    private SqlType findType(String schema, String type) {
        SqlName sqlName = new SqlName(Util.getSchema(schema, type), Util.getType(schema, type),
            false, this);
        return _findType(m_allTypes, sqlName);
    }

    private SqlType findPredefType(SqlName sqlName) {
        return _findType(m_predefTypes, sqlName);
    }

    private SqlType findPredefType(String schema, String type) {
        SqlName sqlName = new SqlName(schema, type, false, this);
        return _findType(m_predefTypes, sqlName);
    }

    private SqlType _findType(Map<Name, TypeClass> ht, SqlName sqlName) {
        return (SqlType)ht.get(sqlName);
        /*
         * Enumeration keys = ht.keys(); while (keys.hasMoreElements()) { Object key =
         * keys.nextElement(); if (sqlName.equals(key)) { return (SqlType) ht.get(key); } } return
         * null;
         */
    }

    public SqlType findType(String name) {
        String schema = Util.getSchema(null, name);
        name = Util.getType(null, name);
        SqlName sqlName = new SqlName(schema, name, false, this);
        SqlType sqlType = findType(sqlName);
        if (sqlType == null) {
            sqlType = findPredefType(sqlName);
        }
        return sqlType;
    }

    /**
     * Add all types declared in the given schema to the set of types to be translated.
     */
    public void addAllTypes(String schema) throws SQLException, PublisherException {
        if (m_conn != null) {
            Iterator<ViewRow> iter = m_viewCache
                .getRows(ALL_TYPES, new String[0], new String[]{OWNER, "PREDEFINED"},
                    new Object[]{schema, "NO"}, new String[]{TYPE_NAME});
            while (iter.hasNext()) {
                AllTypes allTypes = (AllTypes)iter.next();
                addSqlDBType(schema, allTypes.typeName, null, "", false, null);
            }
        }
    }

    public void addAllPackages(String schema) throws SQLException, PublisherException {
        if (m_conn != null) {
            PreparedStatement stmt = m_conn.prepareStatement("SELECT OBJECT_NAME AS TYPE_NAME FROM " +
                    "ALL_OBJECTS WHERE OWNER = :1 AND OBJECT_TYPE = 'PACKAGE' AND STATUS='VALID'");
            stmt.setString(1, schema);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                SqlName sn = new SqlName(schema, rs.getString(1), true, this);
                // determine generated Java names using -genPattern setting.
                sn
                    .setAnnotation(genPattern((LangName)sn.getAnnotation(), sn.getSimpleName(),
                        true));
                addSqlType(sn, Util.IS_PACKAGE, false, true, null, null);
            }
            rs.close();
            stmt.close();

            stmt = m_conn
                .prepareStatement("SELECT COUNT(OBJECT_NAME) AS ARG_COUNT FROM ALL_ARGUMENTS WHERE OWNER = :1 AND PACKAGE_NAME IS NULL AND DATA_LEVEL = 0");
            stmt.setString(1, schema);
            rs = stmt.executeQuery();
            if (rs.next()) {
                int count = rs.getInt(1);
                if (count > 0) {
                    SqlType t = addSqlUserType(schema, "", Util.IS_TOPLEVEL, true, 0, 0, null);
                    String userName = SqlName.sqlIdToJavaId(TOPLEVEL, true);
                    t.getSqlName().setLangName("", userName, null, null, null, null, null, null,
                        true);
                }
            }
            rs.close();
            stmt.close();
        }
    }

    /* Add Java non-array types for publishing */
    public JavaType addJavaType(String typeName, List<AttributeField> fields,
        List<ProcedureMethod> methods, boolean genPattern, TypeClass sqlType) throws SQLException {
        if (typeName == null) {
            return null;
        }
        JavaType jt = null;
        for (int i = 0; i < m_userTypes.size(); i++) {
            if (m_userTypes.get(i) instanceof JavaType) {
                JavaType jTypeTmp = (JavaType)m_userTypes.get(i);
                JavaName jNameTmp = new JavaName(null, typeName, null, null, null);
                if (jTypeTmp.getJavaName().equals(jNameTmp)) {
                    jt = jTypeTmp;
                }
            }
        }
        if (jt != null) {
            return jt;
        }
        JavaName javaName = new JavaName(null, typeName, null, null, null);
        if (genPattern) {
            javaName = (JavaName)genPattern(javaName, typeName, false);
        }
        jt = new JavaBaseType(javaName, fields, methods, sqlType);
        m_userTypes.add(jt);
        return jt;
    }

    /**
     * Search among userTypes, and return a boolean indicating whether a subclass of the receiver
     * type has methods
     */
    public boolean hasMethodsInSubclasses(TypeClass who) throws SQLException, PublisherException {
        Iterator<TypeClass> iter = m_userTypes.iterator();
        while (iter.hasNext()) {
            TypeClass t = iter.next();
            if (!(t instanceof SqlType)) {
                continue;
            }
            SqlType st = (SqlType)t;
            boolean stHasMethods = st.hasMethods();
            while ((st = (SqlType)st.getSupertype()) != null) {
                if (who.getName() != null && who.getName().equals(st.getName())) {
                    if (stHasMethods) {
                        return true;
                    }
                    break;
                }
            }
        }
        return false;
    }

    public void createSqlStmtType(SqlName sqlName) throws SQLException {
        if (m_sqlStmtType == null) {
            m_sqlStmtType = new SqlStmtType(sqlName, this);
        }
    }

    public boolean isPre920() {
        if (m_isPre920 == null) {
            try {
                String v = m_conn.getMetaData().getDatabaseProductVersion().toUpperCase();
                if (v.startsWith("ORACLE DATABASE 10G") || v.startsWith("ORACLE DATABASE 11G")) {
                    m_isPre920 = Boolean.FALSE;
                    return false;
                }
                int pos = v.indexOf("ORACLE");
                if (0 < pos) {
                    v = v.substring(pos);
                }
                String vp = v.substring(0, "ORACLExx".length()).toUpperCase();
                if (vp.equals("ORACLE12")
                    || vp.equals("ORACLE11")
                    || vp.equals("ORACLE10")
                    || (vp.equals("ORACLE9I") && (v.indexOf("9.2.") > 0 || v.indexOf("9.3.") > 0 || v
                        .indexOf("9.4.") > 0))) {
                    m_isPre920 = Boolean.FALSE;
                }
            }
            catch (Exception e) {
                // Connection is pre 9.2.0
            }
            if (m_isPre920 == null) {
                m_isPre920 = Boolean.TRUE;
            }
        }
        return m_isPre920;
    }

    public boolean geqOracle9() {
        return m_geq9i;
    }

    public static boolean geqOracle9(Connection conn) {
        boolean geq9i = false;
        try {
            String dv = conn.getMetaData().getDatabaseProductVersion().toUpperCase();

            int pos = dv.indexOf("ORACLE");
            if (0 < pos) {
                dv = dv.substring(pos);
            }
            geq9i = dv.startsWith("ORACLE9") || dv.startsWith("ORACLE DATABASE 10G")
                || dv.startsWith("ORACLE DATABASE 11G") || dv.startsWith("ORACLE1")
                || dv.startsWith("ORACLE2") || dv.startsWith("ORACLE3");
        }
        catch (SQLException se) {
            /* assume the database is old */
        }
        return geq9i;
    }

    public void setTransitive(boolean transitive) {
        m_transitive = transitive;
    }

    // Return true if a column is null
    public static boolean isNull(String col) {
        return (col == null || col.length() == 0);
    }

    public boolean noUserTypes() {
        return m_userTypes.isEmpty();
    }

    public Map<String, SqlType> getTypeMap() {
        return m_typeMap;
    }

    /**
     * Used for implicitly publishing SQL types Based on the -genPattern setting, sets the LangName
     * associated with this SqlName.
     */
    private LangName genPattern(LangName langName, String simpleName, boolean sql2Java) {
        String genPattern = null;
        if (genPattern == null) {
            return langName;
        }
        @SuppressWarnings("unused") String useName = simpleName;
        if (sql2Java) {
            useName = SqlName.sqlIdToJavaId(simpleName, true);
        }
        // return sqlstring entry (e.g., a:b:c#d) according to m_genPattern.
        // Entries in itemTokens are used to replace %?
        // in m_genPattern. For instance, itemTokens can be
        // - {sqlTypeName, JavaTypeName, JavaSubclassName, JavaItf}
        // - {sqlTypeName}
        String sql = genPattern;
        for (int i = genPattern.length() - 1; i >= 0; i--) {
            if (genPattern.charAt(i) == '%' && i != genPattern.length() - 1) {
                int j = genPattern.charAt(i + 1) - '0';
                sql = sql.substring(0, i) + ((j == 1) ? simpleName : useName)
                    + sql.substring(i + 2);
                // System.out.println("SqlName: sql = "+sql); //D+
            }
        }
        // Derive useName, subclassName, interface name
        String useItf = null;
        String generatedName = null;
        String generatedItf = null;
        StringTokenizer st = new StringTokenizer(sql, "#");
        String[] tokens = new String[st.countTokens()];
        for (int i = 0; 0 < st.countTokens(); i++) {
            tokens[i] = st.nextToken();
            if (i == 1) {
                generatedItf = tokens[1];
                useItf = tokens[1];
            }
        }
        st = new StringTokenizer(tokens[0], ":");
        tokens = new String[st.countTokens()];
        for (int i = 0; 0 < st.countTokens(); i++) {
            tokens[i] = st.nextToken();
            if (i == 0) {
                useName = tokens[0];
            }
            else if (i == 1) {
                useName = tokens[1];
                generatedName = tokens[0];
            }
        }
        if (useName == null) {
            useItf = null;
        }
        if (generatedName == null) {
            generatedItf = null;
        }
        if (useItf != null) {
            generatedItf = null;
        }
        JavaName retJavaName = new JavaName("", useName, useItf, generatedName, generatedItf);
        return retJavaName;
    }

    public String determineSqlName(String name, boolean toBeDistinguished) {
        // toBeDistinguished is a marker indicating that the name is chopped
        // or post-fixed due to length over-limit or name conflicts. If true,
        // the new name needs to go through another round of conflicts checking.
        if (name.length() > MAX_IDENTIFIER_LENGTH) {
            name = name.substring(0, MAX_IDENTIFIER_LENGTH);
            toBeDistinguished = true;
        }
        String uniqueName = name.toUpperCase();
        if (m_allTypeNames.contains(uniqueName)
            || (toBeDistinguished && m_allGeneratedTypeNames.contains(uniqueName))) {
            do {
                int len1 = name.length();
                int len2 = Integer.toString(m_allGeneratedTypeNamesMagicNumber++).length();
                if ((len1 + len2) > MAX_IDENTIFIER_LENGTH) {
                    name = name.substring(0, MAX_IDENTIFIER_LENGTH - len2);
                }
                uniqueName = name.toUpperCase() + m_allGeneratedTypeNamesMagicNumber;
            }
            while (m_allTypeNames.contains(uniqueName)
                || (toBeDistinguished && m_allGeneratedTypeNames.contains(uniqueName)));
        }
        m_allGeneratedTypeNames.add(uniqueName);
        return uniqueName;
    }


    public ViewCache getViewCache() {
        return m_viewCache;
    }

    public void getViewCache(ViewCache vc) {
        m_viewCache = vc;
    }

    public void close() {
        try {
            if (m_conn != null) {
                m_conn.close();
            }
            if (m_viewCache != null) {
                m_viewCache.close();
            }
        }
        catch (Exception e) {
            // Closing resources. OK to ignore exception.
        }
    }

    /**
     * Returns all the user-defined SqlTypes. New types may be appended to the end of the
     * enumeration as the existing types are published or navigated.
     */
    public Iterator<TypeClass> getUserTypes() {
        return m_userTypes.iterator();
    }

    /**
     * @return metadata for generated PL/SQL wrapper package
     */

    public WrapperPackageMetadata getWrapperPackageMetadata() {
        return m_wrapperPackageMetadata;
    }

    public void addWrapperMethodMetadata(String name, String[] paramTypes, String[] paramNames,
        String returnType) {
        if (m_wrapperPackageMetadata == null) {
            m_wrapperPackageMetadata = new WrapperPackageMetadata("");
        }
        m_wrapperPackageMetadata.addMethod(new WrapperMethodMetadata(name, paramTypes, paramNames,
            returnType));
    }

}
