Package org.xorm.tools.generator

Source Code of org.xorm.tools.generator.GenerateInterfaces

/*
    $Header: /cvsroot/xorm/xorm/tools/src/org/xorm/tools/generator/GenerateInterfaces.java,v 1.4 2003/06/23 17:39:43 dcheckoway Exp $

    This file is part of XORM.

    XORM is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    XORM is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with XORM; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package org.xorm.tools.generator;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigInteger;
import java.sql.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import javax.sql.DataSource;
import org.xorm.XORM;
import org.xorm.datastore.sql.SQLConnectionInfo;
import org.xorm.datastore.sql.SQLType;

/**
* Connects to the database and writes out interfaces for all of the
* tables and columns it finds.  Requires a recent JDBC driver.  To execute,
* give the properties file as the first parameter.
*/
public class GenerateInterfaces {
    /** SQL to Java type mappings for non-nullable columns.  Note that since
        the column is not nullable, we can use primitive types in many cases.
    */
    private static Hashtable nonStringTypes;
    static {
        nonStringTypes = new Hashtable();
        nonStringTypes.put("bigint", BigInteger.class);
        nonStringTypes.put("bit", Boolean.TYPE);
        nonStringTypes.put("boolean", Boolean.TYPE);
        //let char be String...nonStringTypes.put("char", Character.TYPE);
        nonStringTypes.put("date", Date.class);
        nonStringTypes.put("decimal", Double.TYPE);
        nonStringTypes.put("double", Double.TYPE);
        nonStringTypes.put("float", Float.TYPE);
        nonStringTypes.put("integer", Integer.TYPE);
        nonStringTypes.put("numeric", Double.TYPE);
        nonStringTypes.put("real", Double.TYPE);
        nonStringTypes.put("smallint", Integer.TYPE);
        nonStringTypes.put("time", Date.class);
        nonStringTypes.put("timestamp", Date.class);
        nonStringTypes.put("tinyint", Integer.TYPE);
    }
   
    /** SQL to Java type mappings for nullable columns.  Note that none of
        these uses the .TYPE primitive class.  If the table column is an
        integer, but it's nullable, then we need to return Integer, not int.
        That way the field value can be treated as null properly.
    */
    private static Hashtable nullableNonStringTypes;
    static {
        nullableNonStringTypes = new Hashtable();
        nullableNonStringTypes.put("bigint", BigInteger.class);
        nullableNonStringTypes.put("bit", Boolean.class);
        nullableNonStringTypes.put("boolean", Boolean.class);
        //let char be String...nullableNonStringTypes.put("char", Character.class);
        nullableNonStringTypes.put("date", Date.class);
        nullableNonStringTypes.put("decimal", Double.class);
        nullableNonStringTypes.put("double", Double.class);
        nullableNonStringTypes.put("float", Float.class);
        nullableNonStringTypes.put("integer", Integer.class);
        nullableNonStringTypes.put("numeric", Double.class);
        nullableNonStringTypes.put("real", Double.class);
        nullableNonStringTypes.put("smallint", Integer.class);
        nullableNonStringTypes.put("time", Date.class);
        nullableNonStringTypes.put("timestamp", Date.class);
        nullableNonStringTypes.put("tinyint", Integer.class);
    }
   
    public static void main(String[] argv) {
        int exitCode = 0;
        try {
            String propertiesFileName = null;
            String outputDirName = null;
            String packageName = null;
            boolean abstractClass = false;
            String tablePattern = null;

            for (int k = 0; k < argv.length; ++k) {
                if (argv[k].startsWith("-prop")) {
                    propertiesFileName = argv[++k];
                }
                else if (argv[k].startsWith("-out")) {
                    outputDirName = argv[++k];
                }
                else if (argv[k].startsWith("-pack")) {
                    packageName = argv[++k];
                }
                else if (argv[k].startsWith("-ab")) {
                    abstractClass = new Boolean(argv[++k]).booleanValue();
                }
                else if (argv[k].startsWith("-t")) {
                    tablePattern = argv[++k];
                }
                else {
                    System.out.println("Unrecognized command line option: " + argv[k]);
                }
            }
           
            if (propertiesFileName == null || propertiesFileName.equals("")) {
                System.out.println("Usage: GenerateInterfaces -properties path/to/xorm.properties [-output outputDir] [-package packageName]");
                System.exit(0);
            }

            if (outputDirName == null || outputDirName.equals("")) {
                outputDirName = "./";
            }

            File outputDir = new File(outputDirName);
            if (!outputDir.exists()) {
                outputDir.mkdir();
            }
            System.out.println("Output is going to: " + outputDir.getCanonicalPath());

            Properties properties = new Properties();
            properties.load(new FileInputStream(propertiesFileName));
            SQLConnectionInfo info = new SQLConnectionInfo();
            info.setProperties(properties);
            DataSource dataSource = (DataSource) info.getDataSource();
            Connection connection = dataSource.getConnection();
            DatabaseMetaData metadata = connection.getMetaData();
            ResultSet results;

            String[] tableTypes = new String[1];

            // Read list of tables
            tableTypes[0] = "TABLE";
            results = metadata.getTables(null, null, null, tableTypes);
            ArrayList tables = new ArrayList();
            while (results.next()) {
                String tableName = results.getString("TABLE_NAME");
                if (tablePattern != null &&
                    !tablePattern.equals("") &&
                    !tableName.matches(tablePattern)) {
                    continue;
                }
                tables.add(results.getString("TABLE_NAME"));
            }
            results.close();

            // Read columns for each table
            Iterator i = tables.iterator();
            while (i.hasNext()) {
                String tableName = (String) i.next();

                // See if it has a primary key
                results = metadata.getPrimaryKeys(null, null, tableName);
                ArrayList primaryKeyColumnNames = new ArrayList();
                while (results.next()) {
                    String pkColumnName = results.getString("COLUMN_NAME");
                    System.out.println("Primary key column: " + pkColumnName);
                    primaryKeyColumnNames.add(pkColumnName);
                }
                results.close();
                if (primaryKeyColumnNames.isEmpty()) {
                    System.out.println("Skipping table with no primary key: " +
                                       tableName);
                    continue;
                }
           
                System.out.println("Processing table: " + tableName);
               
                StringWriter strWriter = new StringWriter();
                PrintWriter methodsOut = new PrintWriter(strWriter);

                ArrayList importedClasses = new ArrayList();
                boolean firstColumn = true;
       
                results = metadata.getColumns(null, null, tableName, null);
                while (results.next()) {
                    String columnName = results.getString("COLUMN_NAME");
                    if (primaryKeyColumnNames.contains(columnName)) {
                        // Skip any primary key columns...this may be slightly
                        // flawed in cases where a table has more than one
                        // primary key column.  But I think 99% of the time
                        // people use a numeric id column.  We'll see how this
                        // ends up working out (assuming anybody uses this).
                        System.out.println("Skipping primary key column: " +
                                           columnName);
                        continue;
                    }
                   
                    String returnType = null;
                    if (columnName.toLowerCase().endsWith("_id")) {
                        String refTableName = columnName.substring(0, columnName.length() - 3);
                        // See if the table exists
                        ResultSet refResults = metadata.getTables(null, null, refTableName, tableTypes);
                        if (refResults != null && refResults.next()) {
                            // Yep, this id column most likely references the
                            // other table...at least it's named that way.
                            System.out.println("Column \"" + columnName +
                                               "\" appears to reference table " +
                                               refTableName);
                            returnType = makeJavaName(refTableName);
                            columnName = refTableName;
                        }
                    }

                    if (returnType == null) {
                        String typeName = SQLType.nameFor(results.getInt("DATA_TYPE"));
                        Class javaType;
                        if (results.getInt("NULLABLE") == metadata.columnNoNulls) {
                            // The column is not nullable...so use the
                            // non-nullable set of type mappings.
                            javaType = (Class)nonStringTypes.get(typeName.toLowerCase());
                        }
                        else {
                            // The column may be nullable...so use the nullable
                            // set of type mappings.
                            javaType = (Class)nullableNonStringTypes.get(typeName.toLowerCase());
                        }
                        if (javaType == null) {
                            javaType = String.class;
                        }
                        else if (javaType.equals(Date.class) ||
                                 javaType.equals(BigInteger.class)) {
                            if (!importedClasses.contains(javaType)) {
                                importedClasses.add(javaType);
                            }
                        }
                        returnType = makeSimpleClassName(javaType);
                    }
                       
                    if (firstColumn) {
                        firstColumn = false;
                    }
                    else {
                        methodsOut.println();
                    }
                   
                    //System.out.println("Column: " + columnName + ", type: " + typeName + ", return: " + returnType);
                    methodsOut.print("    ");
                    if (abstractClass) {
                        methodsOut.print("public abstract ");
                    }
                    methodsOut.println(returnType + " get" +
                                       makeJavaName(columnName) + "();");
                    methodsOut.print("    ");
                    if (abstractClass) {
                        methodsOut.print("public abstract ");
                    }
                    methodsOut.println("void set" +
                                       makeJavaName(columnName) +
                                       "(" + returnType + " val);");
                }
                results.close();

                String className = makeJavaName(tableName);
                File outputFile = new File(outputDir, className + ".java");
                System.out.println("Writing file: " + outputFile.getCanonicalPath());
                FileOutputStream fileOut = new FileOutputStream(outputFile);
                PrintStream out = new PrintStream(fileOut);
                if (packageName != null && !packageName.equals("")) {
                    out.println("package " + packageName + ";");
                    out.println();
                }
                if (!importedClasses.isEmpty()) {
                    for (Iterator iter = importedClasses.iterator(); iter.hasNext(); ) {
                        Class clazz = (Class)iter.next();
                        out.println("import " + clazz.getName() + ";");
                    }
                    out.println();
                }
                out.print("public ");
                if (abstractClass) {
                    out.print("abstract class");
                }
                else {
                    out.print("interface");
                }
                out.println(" " + className +
                            " {");
                out.print(strWriter.toString()); // no newline afterward
                out.println("}");
            }
            connection.close();
        }
        catch (Throwable t) {
            t.printStackTrace();
            exitCode = 1;
        }
        finally {
            Runtime.getRuntime().exit(exitCode);
        }
    }

    /** Make a Java coding style name out of a database column name.
        This simply makes the first character uppercase, and will uppercase
        any character following an underscore.
        @param columnName the database column name
        @return the Java coding style name
    */
    public static String makeJavaName(String columnName) {
        StringBuffer buf = new StringBuffer();
        boolean nextUpper = false;
        for (int k = 0; k < columnName.length(); ++k) {
            if (k == 0) {
                buf.append(Character.toUpperCase(columnName.charAt(k)));
            }
            else if (columnName.charAt(k) == '_') {
                nextUpper = true;
            }
            else {
                if (nextUpper) {
                    buf.append(Character.toUpperCase(columnName.charAt(k)));
                    nextUpper = false;
                }
                else {
                    buf.append(columnName.charAt(k));
                }
            }
        }
        return buf.toString();
    }
   
    /** Get the "simple" class name, which has the package removed
        @param clazz the class
        @return the simple class name string
    */
    public static String makeSimpleClassName(Class clazz) {
        if (clazz.getPackage() == null) {
            return clazz.getName();
        }
       
        String packageName = clazz.getPackage().getName();
        String className = clazz.getName();

        String shortName = className;
       
        if (packageName != null) {
            int packageLength = packageName.length();
            int packageIdx = className.indexOf(packageName);
            shortName = className.substring(packageIdx + packageLength + 1); //chop off the package name, and the last "."
        }
        else if (shortName.startsWith("L")) {
            shortName = shortName.substring(1);
        }

        if (shortName.endsWith(";")) {
            //chop off the trailing semicolon
            shortName = shortName.substring(0, shortName.length() - 1);
        }

        return shortName;
    }
}
TOP

Related Classes of org.xorm.tools.generator.GenerateInterfaces

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.