Reveng.java
/**
*
*/
package org.andromda.jdbcmetadata;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
/**
* Creates a hibernate reveng.xml file from JDBC metadata
* @see "http://docs.redhat.com/docs/en-US/JBoss_Developer_Studio/3.0/html/Hibernate_Tools_Reference_Guide/hibernaterevengxmlfile.html"
*/
public class Reveng
{
private static final Logger logger = Logger.getLogger(Reveng.class);
private List<String> output = new ArrayList<String>();
private String outputFile = "${basedir}\\reveng.xml";
// TODO Set from configuration
private String outputPackage; // = "org.andromda.persist.entity";
private Populator pop;
// Output documentation, inheritance info in reveng file
private boolean metaTags = true;
private String extendClasses;
private String implementInterfaces;
private List<String> extendList = new ArrayList<String>();
private List<String> implementList = new ArrayList<String>();
/**
*
*/
public Reveng()
{
// TODO Auto-generated constructor stub
}
/**
* @param args
*/
public static void main(String[] args)
{
Reveng reveng = new Reveng();
reveng.createReveng();
}
/**
* Set the configuration values
*/
// TODO Read configuration from file or command line
public void setConfiguration()
{
}
/**
* @param populator Populator DB object to use
*/
public void createReveng(Populator populator)
{
//this.extendList.add("org.andromda.persist.entity.AuditedEntity");
//this.extendList.add("org.andromda.persist.AbstractAuditedVersionedEntity");
validateConfiguration();
this.pop = populator;
this.pop.readOverrideConfiguration("${basedir}/override.properties");
this.pop.populate();
createHeader();
createTypeMappings();
createTableFilter();
createTables();
createFooter();
outputFile();
}
/**
*/
public void createReveng()
{
this.createReveng(new Populator());
}
/**
*/
public void validateConfiguration()
{
if (StringUtils.isBlank(this.outputPackage))
{
logger.error("Reveng outputPackage not set");
throw new RuntimeException("Reveng outputPackage not set");
}
if (StringUtils.isBlank(this.outputFile))
{
logger.error("Reveng outputFile not set");
throw new RuntimeException("Reveng outputFile not set");
}
}
/**
*
*/
public void outputFile()
{
try
{
FileUtils.writeLines(new File(this.outputFile), this.output);
logger.info("Wrote " + this.output.size() + " lines to file " + this.outputFile);
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
*/
public void createHeader()
{
this.output.add("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
this.output.add("<!-- See http://docs.jboss.org/tools/latest/en/hibernatetools/html/reverseengineering.html#hibernaterevengxmlfile");
String date = new Date().toString();
this.output.add("Generated by andromda schema2uml2 jdbcmetadata on " + date + " . -->");
this.output.add("<!DOCTYPE hibernate-reverse-engineering ");
// Official hibernate dtd does not allow meta tags even though hibernate-tools processes them
this.output.add(" SYSTEM \"http://seaminaction.googlecode.com/svn/demos/articles/edas2-perflab/resources/hibernate-reverse-engineering-3.0.dtd\">");
//this.output.add(" SYSTEM \"http://www.hibernate.org/dtd/hibernate-reverse-engineering-3.0.dtd\">");
this.output.add("");
this.output.add("<hibernate-reverse-engineering>");
}
/**
*/
public void createTypeMappings()
{
this.output.add(" <schema-selection match-schema=\"PUBLIC\" />");
this.output.add(" <type-mapping>");
this.output.add(" <!-- This maps all numerics with precision 0 to Long, instead of primitive long or BigDecimal -->");
this.output.add(" <!-- jdbc-type is name for java.sql.Types -->");
this.output.add(" <!-- length, scale and precision can be used to specify the mapping precisely -->");
this.output.add(" <!-- type-mappings are ordered. Later mappings will be consulted last, thus overriding the previous one -->");
this.output.add(" <sql-type jdbc-type=\"NUMERIC\" hibernate-type=\"java.lang.Long\"/>");
this.output.add(" <sql-type jdbc-type=\"BIGINT\" hibernate-type=\"java.lang.Long\"/>");
this.output.add(" <sql-type jdbc-type=\"DECIMAL\" scale=\"0\" hibernate-type=\"java.lang.Long\"/>");
this.output.add(" </type-mapping>");
}
/**
* Create table-filter output in reveng file
*/
public void createTableFilter()
{
this.output.add("");
this.output.add(" <!-- BIN$ is recycle bin tables in Oracle. -->");
this.output.add(" <table-filter match-name=\"BIN$.*\" exclude=\"true\" />");
for (String exclude : this.pop.getTableNameExcludePatterns())
{
this.output.add(" <table-filter match-name=\"" + exclude + "\" exclude=\"true\" />");
}
this.output.add(" <table-filter match-catalog=\"" + this.pop.getSchema().getCatalog() +
"\" match-name=\"" + this.pop.getSchema().getTableNamePattern() +
"\" package=\"" + this.outputPackage + "\" />");
this.output.add("");
}
/**
* Create table output in reveng file
*/
public void createTables()
{
// Put extends/implements declaration in file once before all table declarations
for (Table table : this.pop.getTables())
{
if (!table.isExcluded())
{
this.output.add(" <table name=\"" + table.getName() +
"\" class=\"" + table.getUmlName() +
"\" schema=\"" + this.pop.getSchema().getSchemaName() +
"\" catalog=\"" + this.pop.getSchema().getCatalog() + "\" >");
if (this.metaTags && StringUtils.isNotBlank(table.getDescription()))
{
this.output.add(" <meta attribute=\"class-description\">" + table.getDescription() + "</meta>");
for (String extend : this.extendList)
{
this.output.add(" <meta attribute=\"extends\">" + extend + "</meta>");
}
for (String implement : this.implementList)
{
this.output.add(" <meta attribute=\"implements\">" + implement + "</meta>");
}
}
createSequence(table);
createColumns(table);
this.output.add(" </table>");
}
}
}
/**
* Add Column definitions for the table
* @param table
*/
public void createSequence(Table table)
{
for (Column column : table.getColumns())
{
if (column.pkSeqNum > 0 && StringUtils.isNotBlank(column.getGeneratorName()))
{
}
}
}
/**
* Add primary-key annotation if column is a numeric primary key
* @param table Table to create columns
*/
public void createColumns(Table table)
{
for (Column column : table.getColumns())
{
String columnElement = " <column name=\"" + column.getColumnName() + "\"" +
(StringUtils.isNotBlank(column.getUmlName()) ? " property=\"" + column.getUmlName() + "\"" : "") +
(column.isExcluded()? " exclude=\"" + column.isExcluded() + "\"" : "");
String description = column.getDescription();
// TODO If no description and the column is a FK association, use the FK table description
if (this.metaTags && StringUtils.isNotBlank(description))
{
this.output.add(columnElement + " >");
this.output.add(" <meta attribute=\"field-description\">" + description + "</meta>");
this.output.add(" </column>");
}
else
{
this.output.add(columnElement + " />");
}
}
}
/**
*/
public void createFooter()
{
this.output.add("</hibernate-reverse-engineering>");
}
/**
* @return the output
*/
public List<String> getOutput()
{
return this.output;
}
/**
* @param output the output to set
*/
public void setOutput(List<String> output)
{
this.output = output;
}
/**
* @return the outputFile
*/
public String getOutputFile()
{
return this.outputFile;
}
/**
* @param outputFile the outputFile to set
*/
public void setOutputFile(String outputFile)
{
this.outputFile = outputFile;
}
/**
* @return the outputPackage
*/
public String getOutputPackage()
{
return this.outputPackage;
}
/**
* @param outputPackage the outputPackage to set
*/
public void setOutputPackage(String outputPackage)
{
this.outputPackage = outputPackage;
}
/**
* @return the metaTags
*/
public boolean isMetaTags()
{
return this.metaTags;
}
/**
* @param metaTags the metaTags to set
*/
public void setMetaTags(boolean metaTags)
{
this.metaTags = metaTags;
}
/**
* @return the extendList
*/
public List<String> getExtendList()
{
return this.extendList;
}
/**
* @param extendList the extendList to set
*/
public void setExtendList(List<String> extendList)
{
this.extendList = extendList;
}
/**
* @return the implementList
*/
public List<String> getImplementList()
{
return this.implementList;
}
/**
* @param implementList the implementList to set
*/
public void setImplementList(List<String> implementList)
{
this.implementList = implementList;
}
/**
* @return the extendClasses
*/
public String getExtendClasses()
{
return this.extendClasses;
}
/**
* @param extendClasses the extendClasses to set
*/
public void setExtendClasses(String extendClasses)
{
this.extendClasses = extendClasses;
if (StringUtils.isNotBlank(extendClasses))
{
String[] classes = StringUtils.split(extendClasses, " ,|");
for (String extend : classes)
{
if (!this.extendList.contains(extend))
{
this.extendList.add(extend);
}
}
}
}
/**
* @return the implementInterfaces
*/
public String getImplementInterfaces()
{
return this.implementInterfaces;
}
/**
* @param implementInterfaces the implementInterfaces to set
*/
public void setImplementInterfaces(String implementInterfaces)
{
this.implementInterfaces = implementInterfaces;
if (StringUtils.isNotBlank(implementInterfaces))
{
String[] classes = StringUtils.split(implementInterfaces, " ,|");
for (String impl : classes)
{
if (!this.implementList.contains(impl))
{
this.implementList.add(impl);
}
}
}
}
/**
* @param pop the pop to set
*/
public void setPop(Populator pop)
{
this.pop = pop;
}
}