/*
 * 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 schema
     * @param 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;
    }

}
