Maven+Freemarker to generate Java Pojos Dynamically

Hi guys, from past couple of months i was working on lot many plugin development and reporting plugins which i was asked to make the data populate dynamically, So i started using “Freemarker” templates to render data dynamically from java. While i was doing this i got an idea where i can specify my database schema and the code should generate “Java Pojo” classes on the fly, yes there are some tools available but we can make our own custom tool with “Freemarker” and below is my solution to it.

CodeGenerator.java

/**
*
*/
package com.spark.code.generator;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.spark.code.generator.freemarker.engine.FreemarkerEngine;
import com.spark.code.generator.model.ColumnMetaData;

/**
* @author Mantha Pavan Kumar
*
*/
public class CodeGenerator {

/**
* @param args
*/
public static void main(String[] args) {

Connection connection = getConnection();
List<String> list = new ArrayList<String>();
PreparedStatement preparedStatement = null;
Map<String, List<ColumnMetaData>> map = new HashMap<String, List<ColumnMetaData>>();
List<ColumnMetaData> columnMetaDataList = null;
ColumnMetaData columnMetaData = null;

try {
DatabaseMetaData databaseMetaData = connection.getMetaData();
ResultSet resultSet = databaseMetaData.getTables(
connection.getCatalog(), null, null,
new String[] { "TABLE" });
while (resultSet.next()) {
list.add(resultSet.getString("TABLE_NAME"));
}
resultSet.close();
for (int i = 0; i < list.size(); i++) {
columnMetaDataList = new ArrayList<ColumnMetaData>();
String sql = "select * from " + list.get(i) + " where 1=2";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();

ResultSetMetaData metaData = resultSet.getMetaData();
int colCount = metaData.getColumnCount();
for (int j = 0; j < colCount; j++) {
columnMetaData = new ColumnMetaData();
columnMetaData.setColumnName(metaData.getColumnName(j + 1));
columnMetaData.setColumnType(metaData
.getColumnTypeName(j + 1));
columnMetaDataList.add(columnMetaData);
}
map.put(list.get(i), columnMetaDataList);
}

} catch (SQLException e) {
e.printStackTrace();
}

Map<String, Object> templateMap = new HashMap<String, Object>();
templateMap.put("data", map);
System.out.println(FreemarkerEngine.getInstance().getTemplate(
"src/ftl/PojoGen.tmpl", templateMap));

}

private static String toProperCase(String inputString) {
StringBuilder ff = new StringBuilder();

for (String f : inputString.split("_")) {
/*
* if (ff.length() > 0) { ff.append(" "); }
*/
ff.append(f.substring(0, 1).toUpperCase()).append(
f.substring(1, f.length()).toLowerCase());
}

return ff.toString();
}

public static Connection getConnection() {

Connection connection = null;

try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test", "root", "root");

} catch (Exception e) {
e.printStackTrace();
}
return connection;
}

}

The above class gets the meta data of database schema(schema:test in my case) and populates into a map object. Its time to push this map object to Freemarker so that it generates POJO classes. below is the freemarker template which generates the pojo classes

PojoGen.tmpl

/**
*    <p>Generated by Spark Code Generation Tool
*    @author Mantha Pavan Kumar
*    @version 1.0</p>
**/

import java.io.Serializable;
import java.util.Date;

<#list data?keys as key>
public class ${key?cap_first} implements Serializable{

<#list data[key] as value>
/**
*  Attribute ${value.columnName}
**/
private <#if value.columnType == 'INT UNSIGNED' || value.columnType == 'INT' || value.columnType == 'BIGINT UNSIGNED'>int<#elseif value.columnType == 'VARCHAR'>String<#elseif value.columnType == 'DATE' || value.columnType == 'DATETIME'>Date<#elseif value.columnType == 'DOUBLE'>double</#if> ${value.columnName};
</#list>

<#list data[key] as value>
/**
*  @param ${value.columnName}
**/
public void set${value.columnName}(<#if value.columnType == 'INT UNSIGNED' || value.columnType == 'INT' || value.columnType == 'BIGINT UNSIGNED'>int<#elseif value.columnType == 'VARCHAR'>String<#elseif value.columnType == 'DATE' || value.columnType == 'DATETIME'>Date<#elseif value.columnType == 'DOUBLE'>double</#if> ${value.columnName}){
this.${value.columnName} = ${value.columnName};
}
/**
*  @return
**/
public <#if value.columnType == 'INT UNSIGNED' || value.columnType == 'INT' || value.columnType == 'BIGINT UNSIGNED'>int<#elseif value.columnType == 'VARCHAR'>String<#elseif value.columnType == 'DATE' || value.columnType == 'DATETIME'>Date<#elseif value.columnType == 'DOUBLE'>double</#if> get${value.columnName}(){
return ${value.columnName};
}
</#list>
}
</#list>

for this logic to work we have a helper class which will invoke the Freemarker engine and the code is as below

FreemarkerEngine.java

/**
*
*/
package com.spark.code.generator.freemarker.engine;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
* @author Mantha Pavan Kumar
*
*/
public class FreemarkerEngine {

Configuration configuration ;

public FreemarkerEngine() {
configuration = new Configuration();
}

public static FreemarkerEngine getInstance(){

FreemarkerEngine engine = new FreemarkerEngine();
return engine;
}

public String getTemplate(String tempalte,Map params){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStreamWriter output = new OutputStreamWriter(bos);
Template template = null;
try {
template = configuration.getTemplate(tempalte);
template.process(params, output);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}

return bos.toString();
}

}
Advertisements

One thought on “Maven+Freemarker to generate Java Pojos Dynamically

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s