📄 sourcegen.java.predonlyonchange
字号:
/*
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.mozilla.org/MPL
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* The Original Code is jRelationalFramework.
*
* The Initial Developer of the Original Code is is.com.
* Portions created by is.com are Copyright (C) 2000 is.com.
* All Rights Reserved.
*
* Contributor: Ralph Schaer (ralphschaer@yahoo.com)
* Contributor: Jonathan Carlson (joncrlsn@users.sourceforge.net)
* Contributor: ______________________________________
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License (the "GPL") or the GNU Lesser General
* Public license (the "LGPL"), in which case the provisions of the GPL or
* LGPL are applicable instead of those above. If you wish to allow use of
* your version of this file only under the terms of either the GPL or LGPL
* and not to allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and replace them
* with the notice and other provisions required by either the GPL or LGPL
* License. If you do not delete the provisions above, a recipient may use
* your version of this file under either the MPL or GPL or LGPL License.
*
*/
package com.is.jrf.extras;
import com.is.jrf.JDBCHelperFactory;
import com.is.jrf.JRFProperties;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.exolab.javasource.JConstructor;
import org.exolab.javasource.JClass;
import org.exolab.javasource.JMember;
import org.exolab.javasource.JMethod;
import org.exolab.javasource.JParameter;
import org.exolab.javasource.JSourceCode;
import org.apache.log4j.Category;
/**
*
* Generate AbstractDomain and PersistentObject subclasses based on the
* JDBC database metadata.
*
* Thank you to Ralph Schaer for suggesting and submitting his code to do
* this.
*
* Before using this, there are some properties in the jrf.properties file
* that you should be aware of. The JDBC properties are taken from there
* and a couple other of properties (like SourceGen.package and
* SourceGen.outputdir) need to be populated as well.
*
*/
public class SourceGen
{
private String i_outputdir;
private String i_packageName;
private String i_policy;
private DatabaseMetaData i_metaData;
private static final boolean CAPITALIZE = true; // used in javaName()
private static final boolean UNCAPITALIZE = false; // used in javaName()
/** log4j category for debugging and errors */
private static final Category LOG =
Category.getInstance("SourceGen.class.getName()");
public SourceGen(
String outputDir,
String packageName,
String policy)
throws SQLException
{
i_outputdir = outputDir;
i_packageName = packageName;
i_policy = policy;
try
{
Connection conn = JDBCHelperFactory.create().getConnection();
i_metaData = conn.getMetaData();
}
catch (Exception e)
{
LOG.error("Exception occured in SourceGen", e);
System.exit(-1);
}
}
public void generatePersistentObjectClass(String tableName, List columnList)
{
LOG.info("Generating PersistentObject subclass for table " + tableName);
JClass newClass;
if (i_packageName != null &&
i_packageName.length() > 0)
{
newClass =
new JClass(
i_packageName + "."
+ this.className(tableName));
}
else
{
newClass = new JClass(this.className(tableName));
}
newClass.addImport("com.is.jrf.PersistentObject");
newClass.getModifiers().makePublic();
newClass.setSuperClass("PersistentObject");
// add basic contructor
JConstructor constructor = newClass.createConstructor();
constructor.setSourceCode("super();");
newClass.addConstructor(constructor);
Iterator iterator = columnList.iterator();
while (iterator.hasNext())
{
ColumnData cd = (ColumnData) iterator.next();
// Define a member field
JMember member = new JMember(this.getJClass(cd.colType),
this.fieldName(cd.colName));
member.getModifiers().makePrivate();
member.setInitString("null");
member.setComment("This is a database field.");
newClass.addMember(member);
// Define a getter method
JMethod meth = new JMethod(this.getJClass(cd.colType),
this.getterName(cd.colName));
meth.getModifiers().makePublic();
meth.setComment("Getter for a database field.");
meth.getSourceCode().add("return " + this.fieldName(cd.colName) + ";");
newClass.addMethod(meth);
// Define a setter method.
meth = new JMethod(
null,
this.setterName(cd.colName));
String parmName = this.javaName(cd.colName,UNCAPITALIZE);
meth.addParameter(
new JParameter(
this.getJClass(cd.colType),
parmName));
meth.getModifiers().makePublic();
meth.setComment("Setter for a database field.");
JSourceCode sc = meth.getSourceCode();
sc.add(this.fieldName(cd.colName)
+ " = "
+ parmName
+ ";");
if (cd.isPrimaryKey)
{
sc.add("// Changing a primary key so we force this to new.");
sc.add("this.forceNewPersistentState();");
}
else
{
sc.add("this.markModifiedPersistentState();");
}
newClass.addMethod(meth);
}
newClass.print(i_outputdir, null, 2);
}
public void generateDomainClass(String tableName, List columnList)
{
LOG.info("Generating AbstractDomain subclass for table " + tableName);
JClass newClass;
if (i_packageName != null &&
i_packageName.length() > 0)
{
newClass = new JClass(
i_packageName + "." + this.className(tableName) + "Domain");
}
else
{
newClass = new JClass(
this.className(tableName) + "Domain");
}
newClass.addImport("com.is.jrf.*");
newClass.getModifiers().makePublic();
newClass.setSuperClass("AbstractDomain");
JMethod meth = new JMethod(null, "setup");
meth.getModifiers().makePublic();
JSourceCode sc = new JSourceCode();
sc.add("// These setters could be used to override the default.");
sc.add("// this.setDatabasePolicy(new " + i_policy + "());");
sc.add("// this.setJDBCHelper(JDBCHelperFactory.create());");
sc.add("");
sc.add("this.setTableName(\"" + tableName + "\");");
sc.add("");
Iterator iterator = columnList.iterator();
while (iterator.hasNext())
{
ColumnData cd = (ColumnData) iterator.next();
if (cd.colSpecName != null)
{
sc.add("this.addColumnSpec(");
sc.add("new " + cd.colSpecName + "(", (short) 2);
sc.add("\"" + cd.colName + "\",", (short) 4);
sc.add("\"" + this.getterName(cd.colName) + "\",",
(short) 4);
sc.add("\"" + this.setterName(cd.colName) + "\",",
(short) 4);
sc.add(
this.getDefaultValue(cd.colType, cd.isNullable),
(short) 4);
if (cd.isPrimaryKey)
{
// convention assumption: sequenced primary keys are all
// named "id"
if (cd.colName.equalsIgnoreCase("ID"))
{
sc.add(",SEQUENCED_PRIMARY_KEY", (short) 4);
}
else
{
sc.add(",NATURAL_PRIMARY_KEY", (short) 4);
}
}
else
{
if (!cd.isNullable)
{
sc.add(",REQUIRED", (short) 4);
}
}
sc.add("));");
}
}
meth.setSourceCode(sc);
newClass.addMethod(meth);
meth = new JMethod(new JClass("PersistentObject"), "newPersistentObject");
meth.getModifiers().makePublic();
meth.getSourceCode().add(
"return new " + this.className(tableName) + "();");
newClass.addMethod(meth);
newClass.print(i_outputdir, null, 2);
}
private JClass getJClass(short type)
{
switch (type)
{
case -9:
case -10:
case Types.LONGVARCHAR:
case Types.CHAR:
case Types.VARCHAR:
return JClass.String;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
return new JClass("Byte[]");
case Types.BIT:
return JClass.Boolean;
case Types.TINYINT: // use Short because byte is signed -128 to 127
case Types.SMALLINT:
return JClass.Short;
case Types.INTEGER:
return JClass.Integer;
case Types.BIGINT:
return JClass.Long;
case Types.REAL:
return JClass.Float;
// JDBC Guide: Getting Started: 8 - Mapping SQL and Java Types
// recommends FLOAT be represented as Java Double.
case Types.FLOAT:
case Types.DOUBLE:
return JClass.Double;
case Types.NUMERIC:
case Types.DECIMAL:
return JClass.BigDecimal;
case Types.DATE:
return new JClass("java.sql.Date");
case Types.TIME:
return new JClass("java.sql.Time");
case Types.TIMESTAMP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -