/*
 * 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;

//javase imports
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * A SqlName encapsulates the name of a database entity, that is, anything declared directly within
 * a schema. A SqlName identifies the schema in which the entity is declared, and the name of the
 * entity within the schema. Schema and entity names are converted to a canonical form so that they
 * may be compared accurately. Quotes are stripped, and names that are not quoted are shifted to
 * upper case. This class implements 'equals' and 'hash', so that SqlNames may be stored in
 * Hashtables. This class is currently used only for type names. An attribute of a type is not
 * considered to be a SqlName, because it is nested within the type, not directly within the schema.
 * A SqlName instance can describe a PL/SQL type. Both the PL/SQL type name and the corresponding
 * SQL name are captured in the SqlName instance. The two names are accessed via getTypeName(), and
 * getTargetTypeName().
 */
public class SqlName extends Name {

    public final static String ROWTYPE = "ROWTYPE";
    public final static String ROWTYPE_PL = ROWTYPE + "_PL";
    public final static String ROWTYPE_SQL = ROWTYPE + "_SQL";
    private static int m_rowtypeDistinguisher = 0;
    private final static String PUBLIC = "PUBLIC.";
    static String m_defaultSchema;
    static int m_case;
    static int m_targetLang;
    protected static int m_sql2PLCounter = 0;
    protected static int m_pl2SQLCounter = 0;

    protected boolean m_fromDB;
    protected boolean m_contextFromIntype;
    protected int m_line = 0;
    protected int m_column = 0;
    protected boolean m_quoted;
    protected boolean m_printAsIs;
    /**
     * The original database type for the type represented. - If (m_sourceName==m_name), this type
     * does not need conversion and can be published into Java classes directly. - If
     * (m_sourceName!=m_name), this type is typically a PL/SQL type, which needs to be converted
     * into and out of a SQL type in the published code. In this case, m_name represents that SQL
     * type
     */
    protected String m_sourceName;
    // If the record type is defined via CURSOR%ROWTYPE
    protected boolean m_isRowType = false;
    protected boolean m_isReused = false;
    // If the type is built-in or predefined by -defaulttypemap, -addtypemap
    protected boolean m_predefined = false;
    protected Boolean m_hasConversion;
    protected String m_convertOutOf;
    protected String m_convertInto;
    protected String m_convertOutOfQualified;
    protected String m_convertIntoQualified;

    /**
     * Initializes a SqlName with the schema and name of a declared entity. If "schema" is null, the
     * default schema will be used.
     *
     * @param schema
     *            the schema in which the entity is declared
     * @param type
     *            the declared name of the entity in the schema
     */
    public SqlName(String schema, String type, boolean fromDB, int line, int col,
        SqlReflector reflector) {
        this(schema, type, fromDB, line, col, false, false, null, null, null, reflector);
    }

    public SqlName(String schema, String type, boolean fromDB, SqlReflector reflector) {
        this(schema, type, fromDB, 0, 0, false, false, null, null, null, reflector);
    }

    // Used by SqlType to add predefined identity
    // mapping between PL/SQL and SQL
    // convertInto and converOutof being null means identity mapping
    SqlName(String plsql, String sql) {
        this(null, plsql, true, true, true, null, null, sql, null/* reflect */);
    }

    // A type needs conversion if convertOutOf/convertInto/conversionTarget
    // are not null
    public SqlName(String schema, String type, boolean fromDB, boolean printAsIs,
        boolean predefined, String convertInto, String convertOutOf, String conversionTarget,
        SqlReflector reflector) {
        this(schema, type, fromDB, 0, 0, printAsIs, predefined, convertInto, convertOutOf,
            conversionTarget, reflector);
    }

    protected SqlName(String schema, String type, boolean fromDB, int line, int col,
        boolean printAsIs, boolean predefined, String convertInto, String convertOutOf,
        String conversionTarget, SqlReflector reflector) {
        super(massageSchema(schema, fromDB, predefined, reflector), fromDB ? type : reflector
            .getViewCache().dbifyName(type));
        if (m_context == null) {
            m_context = NO_CONTEXT;
        }
        m_fromDB = fromDB;
        m_contextFromIntype = (schema != null && !fromDB) ? true : false;
        m_line = line;
        m_column = col;
        m_quoted = isQuoted(type) ? true : false;
        m_printAsIs = printAsIs;
        m_predefined = predefined;
        m_convertOutOf = convertOutOf;
        m_convertInto = convertInto;
        if (conversionTarget != null) {
            m_sourceName = m_name;
            m_name = conversionTarget;
        }
        else {
            m_sourceName = m_name;
        }
        m_convertOutOfQualified = convertOutOf;
        m_convertIntoQualified = convertInto;
    }

    /**
     * Create a SqlName instance for a PL/SQL type, which requires extra identifying information,
     * such the names for the package and method that mentions this PL/SQL type.
     *
     * @param parentType
     *            The PL/SQL package type that references to the SqlType for which the SqlName is
     *            created for
     */
    public SqlName(String schema, String type, boolean fromDB, int line, int col,
        String packageName, SqlType parentType, SqlReflector reflector) {
        this(schema, null, fromDB, line, col, false, false, null, null, null, reflector);

        // Figure out an identifying name for the SQL type
        // correpsonding to the PL/SQL type
        m_sourceName = type;
        if (m_context == null || m_context.equals("")) {
            if (type.indexOf('.') >= 0) {
                m_context = type.substring(0, type.indexOf('.'));
                m_sourceName = type.substring(type.indexOf('.') + 1);
            }
        }
        // Determine the SQL type name for a PL/SQL type
        String[] mSourceName = new String[]{m_sourceName};
        boolean[] mIsRowType = new boolean[]{m_isRowType};
        m_name = determineSqlName(packageName, mSourceName, parentType, mIsRowType, reflector);
        m_sourceName = mSourceName[0];
        m_isRowType = mIsRowType[0];
        m_name = m_fromDB ? m_name : dbifyName(m_name, reflector);
    }

    public static String interfaceIfPossible(SqlName sqlName, boolean itfIfPossible) {
        if (itfIfPossible && sqlName.hasUseItf()) {
            return sqlName.getUseItf();
        }
        else if (sqlName.hasUseClass()) {
            return sqlName.getUseClass();
        }
        else if (itfIfPossible && sqlName.hasDeclItf()) {
            return sqlName.getDeclItf();
        }
        else {
            return sqlName.getDeclClass();
        }
    }

    /**
     * Determine the SQL type name for a PL/SQL type. Generate a name in the form of
     * {@code <prefix>_<name>}. The {@code <prefix>} term is determined as follows in precedency - java user
     * interface name of the associated PL/SQL package - java base interface name of the associated
     * PL/SQL package - the associated PL/SQL package name Generated names are subject to length and
     * conflict check. If length excceeds PL/SQL identifier limit, the name will be chopped. If
     * conflicts occurs, the name will be pos-fixed with numeric values,
     *
     **/
    public static String determineSqlName(String packageName, String[] sourceName,
        TypeClass parentType, boolean[] isRowType, SqlReflector reflector) {
        String parentName = null; // Java name for the PL/SQL package
        if (parentType != null) {
            SqlName parentSqlName = (SqlName)parentType.getNameObject();
            if (parentSqlName != null) {
                parentName = interfaceIfPossible(parentSqlName, true /* itfIfPossible */)
                    .toUpperCase();
            }
        }
        String name = sourceName[0];
        reflector.addAllGeneratedTypeNames(name);
        // replace package name with parentName
        if (name.indexOf('.') >= 0 && parentName != null) {
            name = parentName + "_" + name.substring(name.indexOf('.') + 1);
            reflector.addAllGeneratedTypeNames(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 reflector.determineSqlName(name, toBeDistinguished);
    }

    public static void initStaticVariables() {
        setDefaultSchema(SqlName.NO_CONTEXT);
        // m_convFuns = new Hashtable();
        // m_convNameCounter = 0;
        m_rowtypeDistinguisher = 0;
        // added as well
        m_sql2PLCounter = 0;
        m_pl2SQLCounter = 0;
    }

    /**
     * Returns the schema name of the declared entity.
     */
    public String getSchemaName() {
        return m_context;
    }

    /**
     * Returns the name of the original database type. For a PL/SQL type, returns the name of the
     * declared PL/SQL type within the schema. not uppercased The name is prefixed by the package
     * name and ".", except for CURSOR%ROWTYPE
     */
    public String getTypeName() {
        return m_sourceName;
    }

    /**
     * Return the SQL type name. If this SqlName instance represents a PL/SQL type, or a type
     * requring conversions into and out of a SQL type, the method returns the SQL type name.
     * Otherwise, this method returns the same name as getTypeName().
     */

    public String getTargetTypeName() {
        // Deal with SQL synonymous
        if (m_name.equals("TIMESTAMP WITH LOCAL TZ")) {
            return "TIMESTAMP WITH LOCAL TIME ZONE";
        }
        if (m_name.equals("TIMESTAMP WITH TZ")) {
            return "TIMESTAMP WITH TIME ZONE";
        }
        // "BOOLEAN" is really "PL/SQL BOOLEAN" which doesn't have a JDBC equivalent
        // use INTEGER and SYS.SQLJUTL.INT2BOOL/SYS.SQLJUTL.BOOL2INT conversion
        if (m_name.equals("BOOLEAN")) {
            return "INTEGER";
        }
        return m_name;
    }

    public String getFullTargetTypeName(int schemaName) {
        return getFullTypeName(getTargetTypeName(), schemaName);
    }

    /**
     * Returns the use class name of a SqlName. This includes the package name if the Java class is
     * not in the current package. If the Java name has not been created yet, it is constructed
     * using the CASE and PACKAGE options.
     *
     * * @param SqlName the SQL name of the type
     *
     * @param currPackage
     *            the package from which the class is referenced
     * @return the name of an SQL type.
     */
    @Override
    public String getUseClass(String currPackage) {
        return getLangName().getUseClass(currPackage);
    }

    @Override
    public String getUseClass() {
        return getLangName().getUseClass();
    }

    @Override
    public String getUseClass(boolean full) {
        return getLangName().getUseClass(full);
    }

    /**
     * Returns the Java use package name of an SqlName.
     */
    @Override
    public String getUsePackage() {
        return getLangName().getUsePackage();
    }

    /**
     * return ture, if this type has user subclass
     */
    @Override
    public boolean hasUseClass() {
        return getLangName().hasUseClass();
    }

    /**
     * Returns the use interface name of a SqlName.
     */
    @Override
    public String getUseItf() {
        return getLangName().getUseItf();
    }

    /**
     * Returns the use interface name of a SqlName.
     */
    public String getUseItf(String currPackage) {
        return ((JavaName)getLangName()).getUseItf(currPackage);
    }

    /**
     * Returns the Java use interface
     */
    @Override
    public String getUseItfPackage() {
        return getLangName().getUseItfPackage();
    }

    /**
     * If both decl interface and use interface are defined, we use the latter
     */
    @Override
    public boolean hasUseItf() {
        return getUseItf() != null;
    }

    @Override
    public boolean hasDeclItf() {
        return getDeclItf() != null;
    }

    /**
     * Returns the boolean whether SqlName is from the DB.
     */
    public boolean getFromDB() {
        return m_fromDB;
    }

    /**
     * Returns the line number where the sqlname was found by the parser.
     */
    public int getLine() {
        return m_line;
    }

    /**
     * Returns the column number where the sqlname was found by the parser.
     */
    public int getColumn() {
        return m_column;
    }

    /**
     * Returns the boolean whether SqlName was quoted or not
     */
    public boolean isQuoted() {
        return m_quoted;
    }

    /**
     * Returns the boolean whether SqlName was quoted or not
     */
    public static boolean isQuoted(String str) {
        if (str != null && str.startsWith("\"") && str.endsWith("\"")) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
     * Returns the declaration class name of an SqlName. The declaration class name is the name of
     * the class that JPub generates. It is different from the use class name, the name of the class
     * name generated when the class is used, rather than declared, if the use class is
     * user-written. The user tells JPub that this is the case by putting the clause
     * "{@code GENERATE <decl name> AS <use name>}" in the input file.
     *
     * * @return the decl class name of a type.
     */
    @Override
    public String getDeclClass() {
        return getLangName().getDeclClass();
    }

    /**
     * Returns the declaration package name of an SqlName. The declaration package name is the name
     * of the package that JPub generates. It is different from the use package name, the name of
     * the package name generated when the package is used, rather than declared, if the use package
     * is user-written. The user tells JPub that this is the case by putting the clause "{@code GENERATE
     * <decl name> AS <use name>}" in the input file.
     *
     * * @return the decl package name of a type.
     */
    @Override
    public String getDeclPackage() {
        return getLangName().getDeclPackage();
    }

    public String getDeclClass(String currPackage) {
        return ((JavaName)getLangName()).getDeclClass(currPackage);
    }

    /**
     * Returns the declaration interface name of a SqlName.
     */
    @Override
    public String getDeclItf() {
        return getLangName().getDeclItf();
    }

    /**
     * Returns the declaration interface name of a SqlName.
     */
    public String getDeclItf(String currPackage) {
        return ((JavaName)getLangName()).getDeclItf(currPackage);
    }

    /**
     * Returns the Java declaration interface of an SqlName.
     */
    @Override
    public String getDeclItfPackage() {
        return getLangName().getDeclItfPackage();
    }

    /**
     * Returns the LangName of this SqlName.
     */
    public LangName getLangName() {
        LangName j = (LangName)getAnnotation();

        if (j == null) {
            j = setLangName("", null, null, null, null, null, null, null, true);
        }

        return j;
    }

    /**
     * Sets the LangName associated with this SqlName. Create a new C or Java name, and associate it
     * with this SqlName.
     */
    public LangName setLangName(String packageName, String useName, String useItf,
        String generatedName, String generatedItf, String hfile, SqlType firstParent,
        String cppfile, boolean userNameGiven) {
        LangName langName = (LangName)getAnnotation();

        if (langName == null) {
            if (useName == null) {
                useName = sqlIdToJavaId(m_name, true);
            }
            langName = new JavaName(packageName, useName, useItf, generatedName,
                generatedItf);

            setAnnotation(langName);
        }

        /*
         * For JPub only: If there is a previous entry for this SqlName, this is an error. The root
         * cause of this error, multiple requests to unparse this SqlName, has already been
         * reported, so we won't report a separate error here.
         */
        return langName;
    }

    /**
     * Returns the complete name of the declared entity. The returned name includes the schema name
     * and the name of the entity within the schema.
     */
    @Override
    public String toString() {
        String fullName = (m_sourceName.equals("")) ? "<top-level scope>"
            : ((m_printAsIs || m_sourceName.indexOf(".") < 0) ? m_sourceName : "\"" + m_sourceName
                + "\"");

        if (m_context != NO_CONTEXT) {
            String schemaName = (m_printAsIs || m_context.indexOf(".") < 0) ? m_context : "\""
                + m_context + "\"";

            fullName = schemaName + "." + fullName;
        }

        return stripPublic(fullName);
    }

    /**
     * Returns the name of the declared entity as a quoted string. If a non-null schema name was
     * supplied when this SqlName was constructed, the omitSchemaName flag is ignored, and the
     * returned name includes the schema name. If a null schema name was supplied when this SqlName
     * was declared, the returned name includes the schema name only if omitSchemaName == false.
     *
     * * @param omitSchemaName suggestion not to include the schema name
     *
     * @return the name of the declared entity as a quoted string
     */
    public String toQuotedString(boolean omitSchemaName) {
        return "\"" + toString(omitSchemaName) + "\"";
    }

    private String toString(boolean omitSchemaName) {
        if (!m_context.equals(m_defaultSchema)) {
            omitSchemaName = false;
        }

        /* This is correct, but SQLJ and JDBC don't support it yet. */
        /*
         * return "\"\\\"" + ((omitSchemaName) ? "" : m_context + "\\\".\\\"") + m_type + "\\\"\"";
         */

        /*
         * This doesn't handle embedded dots in schema and type names, but it's what JDBC and SQLJ
         * expect.
         */
        String name = null;
        if (omitSchemaName == true || m_context == null || m_context.equals("")) {
            name = getTargetTypeName();
        }
        else {
            name = m_context + "." + getTargetTypeName();
        }
        return stripPublic(name);
    }

    public String getQuotedSimpleName() {
        return (m_quoted ? "\"" : "") + getSimpleName() + (m_quoted ? "\"" : "");
    }

    /**
     * Initialize the SqlName class with the default schema name, used when a SqlName is created
     * without an explciit schema name.
     *
     * * @param defaultSchema the name of the default schema
     */
    public static void setDefaultSchema(String defaultSchema) {
        m_defaultSchema = defaultSchema;
    }

    /**
     * Set the default style of case conversion used to generate the Java equivalent of an unknown
     * SQL name. A name is unknown if its Java name was not specified via addType() or
     * addAttribute().
     */
    public static void setCase(int caseOption) {
        m_case = caseOption;
    }

    public static int getCase() {
        return m_case;
    }

    public static void setTargetLang(int targetLang) {
        m_targetLang = targetLang;
    }

    public static int getTargetLang() {
        return m_targetLang;
    }

    public static boolean langIsOtt() {
        return false;
    }

    public static boolean langIsC() {
        return false;
    }

    public static boolean langIsCpp() {
        return false;
    }

    public static boolean containsLowerChar(String s) {
        char carr[] = s.toCharArray();
        int len = carr.length;
        char ch;
        for (int i = 0; i < len; i++) {
            ch = carr[i];
            if (Character.isLetterOrDigit(ch) && Character.isLowerCase(ch)) {
                return true;
            }
        }
        return false;
    }

    public static String sqlIdToJavaId(String s, boolean wordBoundary) {
        return sqlIdToJavaId(s, wordBoundary, false);
    }

    public static String sqlIdToJavaId(String s, boolean wordBoundary, boolean avoidJavaPrimitives) {
        if (s.equals("__return"))
            return "_return";

        boolean needToWarn = false;
        char carr[] = s.toCharArray();
        int len = carr.length;
        char ch;
        int destPos = 0;
        if (m_case == Util.CASE_MIXED) {
            for (int sourcePos = 0; sourcePos < len; sourcePos++) {
                ch = carr[sourcePos];
                if (Character.isLetterOrDigit(ch)) {
                    carr[destPos++] = wordBoundary ? Character.toTitleCase(ch) : Character
                        .toLowerCase(ch);
                    wordBoundary = false;
                }
                else {
                    /* silently remove character */
                    wordBoundary = true;
                }
            }
        }
        else {
            for (int sourcePos = 0; sourcePos < len; sourcePos++) {
                ch = carr[sourcePos];
                if (Character.isJavaIdentifierPart(ch)) {
                    switch (m_case) {
                        case Util.CASE_UPPER:
                            carr[destPos] = Character.toUpperCase(ch);
                            break;
                        case Util.CASE_LOWER:
                            carr[destPos] = Character.toLowerCase(ch);
                            break;
                        case Util.CASE_OPPOSITE:
                            if (Character.isUpperCase(ch)) {
                                carr[destPos] = Character.toLowerCase(ch);
                            }
                            else if (Character.isLowerCase(ch)) {
                                carr[destPos] = Character.toUpperCase(ch);
                            }
                            break;
                        default:
                            carr[destPos] = ch;
                            break;
                    }
                    destPos++;
                }
                else {
                    /* remove character */
                    needToWarn = true;
                }
            }
        }
        if (destPos == 0) {
            // TODO -- error message
        }
        else if (needToWarn) {
            // TODO -- warn
        }
        return new String(carr, 0, destPos);
    }

    public static boolean isAlpha(char ch) {
        String lettersStr = new String("abcdefghijklmnopqrstuvwxyz");
        char[] chars = lettersStr.toCharArray();

        ch = Character.toLowerCase(ch);
        int len = chars.length;
        for (int i = 0; i < len; i++) {
            if (chars[i] == ch) {
                return true;
            }
        }
        return false;
    }

    private static String massageSchema(String schema, boolean fromDB, boolean predefined,
        SqlReflector reflector) {
        if (schema == null) {
            schema = NO_CONTEXT;
        }

        if (predefined) {
            schema = schema.length() > 0 ? reflector.getViewCache().dbifyName(schema) : schema;
        }
        else if (!fromDB) {
            schema = schema.length() > 0 ? reflector.getViewCache().dbifyName(schema)
                : m_defaultSchema;
        }

        return schema;
    }

    /**
     * Returns true if and only if two Names are equal.
     */
    // Used for mapping SqlName to SqlType in
    // SqlType.m_predefinedTypes and SqlType.m_namedTypes
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof SqlName)) {
            return false;
        }
        SqlName n = (SqlName)obj;
        boolean eq = (m_context == null || n.m_context == null || m_context.equals("") || n.m_context
            .equals("")) ? m_sourceName.equalsIgnoreCase(n.m_sourceName) : (m_context
            .equalsIgnoreCase(n.m_context) && m_sourceName.equalsIgnoreCase(n.m_sourceName));
        return eq;
    }

    /**
     * Returns a hash code for the Name. Implemented so that Names may be put in Hashtables.
     */
    @Override
    public int hashCode() {
        return m_sourceName.hashCode();
    }

    // Is this a PL/SQL record type defined
    // via CURSOR%ROWTYPE
    public boolean isRowType() {
        return m_isRowType;
    }

    // Is this type built-in or predefined
    public boolean isPredefined() {
        return m_predefined;
    }

    public boolean hasConversion() {
        if (m_hasConversion == null) {
            m_hasConversion = getIntoConversion() != null
                    || getOutOfConversion() != null;
        }
        return m_hasConversion;
    }

    /**
     * Returns the PL/SQL function to be used for converting this PL/SQL into a SQL type.
     * <br>
     * Returns null if this is not a PL/SQL type or if it does not have user-defined conversions.
     */
    public String getOutOfConversion() {
        if (m_name.equals(m_sourceName)) {
            return null;
        }
        if (isPredefined()) {
            return m_convertOutOf;
        }
        if (m_convertOutOf != null) {
            return m_convertOutOf;
        }
        m_convertOutOf = "PL_TO_SQL" + (m_pl2SQLCounter++);
        // m_convertOutOfQualified = JavaPublisher.getDeclaredWrapperPackage() + "." +
        // m_convertOutOf;

        return m_convertOutOf;
    }

    /**
     * Returns the PL/SQL function to be used for converting a SQL type into this PL/SQL type.
     * <br>
     * Returns null if this is not a PL/SQL type or if it does not have user-defined conversions.
     */
    public String getIntoConversion() {
        if (m_name.equals(m_sourceName)) {
            return null;
        }
        if (isPredefined()) {
            return m_convertInto;
        }
        if (m_convertInto != null) {
            return m_convertInto;
        }
        m_convertInto = "SQL_TO_PL" + (m_sql2PLCounter++);
        // m_convertIntoQualified = JavaPublisher.getDeclaredWrapperPackage() + "." + m_convertInto;
        return m_convertInto;
    }

    // Return the conversion function name
    // prefixed with package name,
    // if the conversion function is a generated one
    public String getOutOfConversionQualified() {
        if (getOutOfConversion() == null) {
            return null;
        }
        return m_convertOutOfQualified;
    }

    // Return the conversion function name
    // prefixed with package name,
    // if the conversion function is a generated one
    public String getIntoConversionQualified() {
        if (getIntoConversion() == null) {
            return null;
        }
        return m_convertIntoQualified;
    }

    public String getFullTypeName(int schemaName) {
        return getFullTypeName(getTypeName(), schemaName);
    }

    private String getFullTypeName(String typeName, int schemaName) {
        String name = null;
        if (m_context != null && !m_context.equals("") && m_contextFromIntype) {
            name = m_context + "." + typeName;
        }
        else {
            name = typeName;
        }
        return stripPublic(name);
    }

    public boolean isReused() {
        return m_isReused;
    }

    public static String dbifyName(String s, SqlReflector reflector) {

        if (s == null || s.equals("") || reflector == null || reflector.getConnection() == null)
            return s;
        return dbifyName(s, reflector.getConnection());
    }

    public static String dbifyName(String s, Connection conn) {
        String upper_s = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            stmt = conn.prepareStatement("SELECT UPPER(:1) AS UPPER_NAME FROM DUAL");
            stmt.setString(1, s);
            rs = stmt.executeQuery();
            if (rs.next()) {
                upper_s = rs.getString(1);
            }
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
            upper_s = s;
        } finally {
            if (rs != null)
                try {
                    rs.close();
                } catch (SQLException e) {
                }
            if (stmt != null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                }
        }

        String dbName = isQuoted(s)
                ? s.substring(1, s.length() - 1)
                : (upper_s == null) ? "" : upper_s;
        return dbName;
    }

    private String stripPublic(String name) {
        if (name.startsWith(PUBLIC)) {
            name = name.substring(PUBLIC.length());
        }
        return name;
    }

}
