package ca.sqlpower.sql;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
public class BeanGenerator {
public static final String VERSION_STRING="SQLPower BeanGenerator v1.0";
PrintWriter out;
ResultSetMetaData md;
String tableName;
String className;
String packageName;
String uniqueIdColName;
public BeanGenerator(ResultSet rs,
String schemaName,
String tableName,
String packageName,
String destDir)
throws SQLException, IOException {
md=rs.getMetaData();
this.tableName=tableName;
className=convertToClassName(tableName);
List priKey=SQL.findPrimaryKey(rs.getStatement().getConnection(),
schemaName, tableName);
uniqueIdColName=(String)priKey.get(priKey.size()-1);
try {
out=new PrintWriter(new FileOutputStream(destDir+className+".java"));
outputPackageStatement();
outputImports();
outputDeclaration();
outputConstructor();
outputStoreMethod();
outputFindMethod();
outputSetGetMethods();
outputEnding();
} finally {
out.close();
}
}
void outputPackageStatement() {
if(packageName != null && packageName.length() > 0) {
out.print("package ");
out.println(packageName);
out.println();
}
}
void outputImports() {
out.println("import java.sql.*;");
out.println("import ca.sqlpower.sql.SQL;");
out.println();
}
void outputDeclaration() throws SQLException {
out.println("/**");
out.println(" * The "+className+" class is a database persistence ");
out.println(" * object which is tightly coupled with the underlying ");
out.println(" * "+tableName+" database table.");
out.println(" * ");
out.println(" * @author Autogenerated by "+VERSION_STRING);
out.println(" * @version Autogenerated on "+new java.util.Date());
out.println(" */");
out.println("public class "+className+" {");
out.print(" protected static final String UNIQUE_ID_COL_NAME=\"");
out.print(uniqueIdColName);
out.println("\";");
out.println(" protected boolean _alreadyInDatabase;");
for(int col=1; col<=md.getColumnCount(); col++) {
out.print(" protected String ");
out.print(convertToMemberName(md.getColumnName(col)));
out.println(";");
}
out.println();
}
void outputConstructor() throws SQLException {
out.println(" public "+className+"() {");
out.println(" _alreadyInDatabase=false;");
for(int col=1; col<=md.getColumnCount(); col++) {
out.print(" ");
out.print(convertToMemberName(md.getColumnName(col)));
out.println("=null;");
}
out.println(" }");
out.println();
}
void outputStoreMethod() throws SQLException {
// Create the UPDATE statement
StringBuffer upd=new StringBuffer(1000);
upd.append("UPDATE ");
upd.append(tableName);
upd.append(" SET (");
for(int col=1; col<=md.getColumnCount(); col++) {
if(col>1) upd.append(", ");
upd.append(md.getColumnName(col));
upd.append("=\"+SQL.quote(");
upd.append(convertToMemberName(md.getColumnName(col)));
upd.append(")+\"");
}
upd.append(") WHERE \"+UNIQUE_ID_COL_NAME+\" = \"+");
upd.append("SQL.quote(getUniqueId())");
// Create the INSERT statement
StringBuffer ins=new StringBuffer(1000);
ins.append("INSERT INTO ");
ins.append(tableName);
ins.append("(");
for(int col=1; col<=md.getColumnCount(); col++) {
if(col>1) ins.append(", ");
ins.append(md.getColumnName(col));
}
ins.append(") VALUES (");
for(int col=1; col<=md.getColumnCount(); col++) {
if(col>1) ins.append(", ");
ins.append("\"+SQL.quote(");
ins.append(convertToMemberName(md.getColumnName(col)));
ins.append(")+\"");
}
ins.append(")\"");
// Output the method that uses it
out.println(" public void store(Connection con) throws SQLException {");
out.println(" Statement stmt=null;");
out.println(" try {");
out.println(" stmt=con.createStatement();");
out.println(" if(_alreadyInDatabase) {");
out.println(" stmt.executeUpdate(\""+upd.toString()+");");
out.println(" } else {");
out.println(" stmt.executeUpdate(\""+ins.toString()+");");
out.println(" _alreadyInDatabase=true;");
out.println(" }");
out.println(" } finally {");
out.println(" if(stmt != null) {");
out.println(" stmt.close();");
out.println(" }");
out.println(" }");
out.println(" }");
}
void outputFindMethod() throws SQLException {
// Create the SELECT statement
StringBuffer sql=new StringBuffer(1000);
sql.append("SELECT ");
for(int col=1; col<=md.getColumnCount(); col++) {
if(col>1) sql.append(", ");
sql.append(md.getColumnName(col));
}
sql.append(" FROM ");
sql.append(tableName);
sql.append(" WHERE ");
sql.append(uniqueIdColName);
sql.append(" = \"+");
sql.append("SQL.quote(");
sql.append(convertToMemberName(uniqueIdColName));
sql.append(")+\""); // needs to end "inside" the string
out.print(" public static ");
out.print(className);
out.print(" findByPrimaryKey(Connection con, String ");
out.print(convertToMemberName(uniqueIdColName));
out.println(") throws SQLException {");
out.println(" Statement stmt=null;");
out.println(" ResultSet rs=null;");
out.println(" try {");
out.println(" stmt=con.createStatement();");
out.println(" rs=stmt.executeQuery(\""+sql.toString()+"\");");
out.println(" if(!rs.next()) { return null; }");
out.println(" "+className+" newBean=new "+className+"();");
out.println(" newBean._alreadyInDatabase=true;");
for(int col=1; col<=md.getColumnCount(); col++) {
out.print(" newBean.set");
out.print(convertToClassName(md.getColumnName(col)));
out.print("(rs.getString(");
out.print(col);
out.println("));");
}
out.println(" return newBean;");
out.println(" } finally {");
out.println(" if(stmt != null) {");
out.println(" stmt.close();");
out.println(" }");
out.println(" }");
out.println(" }");
}
void outputSetGetMethods() throws SQLException {
out.println(" public String getUniqueId() {");
out.print(" return get");
out.print(convertToClassName(uniqueIdColName));
out.println("();");
out.println(" }");
out.println();
for(int col=1; col<=md.getColumnCount(); col++) {
String Member=convertToClassName(md.getColumnName(col));
String member=convertToMemberName(md.getColumnName(col));
out.println(" public String get"+Member+"() {");
out.print(" return ");
out.print(member);
out.println(";");
out.println(" }");
out.println();
out.println(" public void set"+Member+"(String v) {");
out.print(" ");
out.print(member);
out.println("=v;");
out.println(" }");
out.println();
}
}
void outputEnding() throws SQLException {
out.println("}");
}
static String convertToClassName(String underscores) {
return convertToCamelCaps(underscores, true);
}
static String convertToMemberName(String underscores) {
return convertToCamelCaps(underscores, false);
}
static String convertToCamelCaps(String underscores, boolean initialCap) {
boolean nextCharIsUpper=initialCap;
StringBuffer camelCaps=new StringBuffer(underscores.length());
for(int srcIndex=0; srcIndex<underscores.length(); srcIndex++) {
char c=underscores.charAt(srcIndex);
if(c=='_') {
nextCharIsUpper=true;
continue;
}
if(nextCharIsUpper) {
c=Character.toUpperCase(c);
nextCharIsUpper=false;
} else {
c=Character.toLowerCase(c);
}
camelCaps.append(c);
}
return camelCaps.toString();
}
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value={"SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE"},
justification="This SQL code chooses which table to select from dynamically, based on a command-line argument. A Prepared Statement is not appropriate.")
public static void main(String args[]) throws Exception {
try {
// Lookup the database named in args[0] in databases.xml
String dbxml="databases.xml";
String name=args[0];
DBCSSource xmlSource=new XMLFileDBCSSource(dbxml);
List dbcsList=xmlSource.getDBCSList();
DBConnectionSpec dbcs=DBConnectionSpec.searchListForName(dbcsList, name);
if(dbcs==null) {
System.err.println("No database definition '"+name+"' in "+dbxml+".");
return;
}
String dbclass=dbcs.getDriverClass();
String dburl=dbcs.getUrl();
String dbuser=dbcs.getUser();
String dbpass=dbcs.getPass();
String schemaName=args[1];
String tableName=args[2];
Connection con;
Statement stmt;
ResultSet rs;
ResultSetMetaData rsmd;
Class.forName(dbclass, true, BeanGenerator.class.getClassLoader()).newInstance();
con=DriverManager.getConnection(dburl, dbuser, dbpass);
stmt=con.createStatement();
rs=stmt.executeQuery("SELECT * FROM " + tableName);
new BeanGenerator(rs, schemaName, tableName, null, "");
con.close();
} catch (Exception e) {
if (e instanceof DatabaseListReadException) {
System.out.println("Caught DatabaseListReadException. Root cause:");
((DatabaseListReadException) e).getRootCause().printStackTrace();
} else {
e.printStackTrace();
}
}
}
}