package cn.org.rapid_framework.generator;
import static cn.org.rapid_framework.generator.GeneratorConstants.GENERATOR_TOOLS_CLASS;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import cn.org.rapid_framework.generator.Generator.GeneratorModel;
import cn.org.rapid_framework.generator.provider.db.sql.model.Sql;
import cn.org.rapid_framework.generator.provider.db.table.TableFactory;
import cn.org.rapid_framework.generator.provider.db.table.model.Table;
import cn.org.rapid_framework.generator.provider.java.model.JavaClass;
import cn.org.rapid_framework.generator.util.BeanHelper;
import cn.org.rapid_framework.generator.util.ClassHelper;
import cn.org.rapid_framework.generator.util.GLogger;
import cn.org.rapid_framework.generator.util.GeneratorException;
import cn.org.rapid_framework.generator.util.StringHelper;
/**
* 生成器的主要入口类,包装相关方法供外部生成代码使用
*
* 使用GeneratorFacade之前,需要设置Generator的相关属性
* @author badqiu
*
*/
public class GeneratorFacade {
private Generator generator = new Generator();
public GeneratorFacade(){
if(StringHelper.isNotBlank(GeneratorProperties.getProperty("outRoot"))) {
generator.setOutRootDir(GeneratorProperties.getProperty("outRoot"));
}
}
public static void printAllTableNames() throws Exception {
PrintUtils.printAllTableNames(TableFactory.getInstance().getAllTables());
}
public void deleteOutRootDir() throws IOException {
generator.deleteOutRootDir();
}
/**
* 自定义变量,生成文件,文件路径与模板引用的变量相同
* @throws Exception
*/
public void generateByMap(Map... maps) throws Exception {
for(Map map : maps) {
new ProcessUtils().processByMap(map,false);
}
}
/**
* 自定义变量,删除生成的文件,文件路径与模板引用的变量相同
* @throws Exception
*/
public void deleteByMap(Map... maps) throws Exception {
for(Map map : maps) {
new ProcessUtils().processByMap(map, true);
}
}
/**
* 自定义变量,生成文件,可以自定义文件路径与模板引用的变量
* @throws Exception
*/
public void generateBy(GeneratorModel... models) throws Exception {
for(GeneratorModel model : models) {
new ProcessUtils().processByGeneratorModel(model,false);
}
}
/**
* 自定义变量,删除生成的文件,可以自定义文件路径与模板引用的变量
* @throws Exception
*/
public void deleteBy(GeneratorModel... models) throws Exception {
for(GeneratorModel model : models) {
new ProcessUtils().processByGeneratorModel(model,true);
}
}
/**
* 扫描数据库中所有表对象,然后生成文件,模板引用的变量名称为: table, 实体类为: @see cn.org.rapid_framework.generator.provider.db.table.model.Table
* @throws Exception
*/
public void generateByAllTable() throws Exception {
new ProcessUtils().processByAllTable(false);
}
/**
* 扫描数据库中所有表对象,然后删除生成的文件,模板引用的变量名称为: table, 实体类为: @see cn.org.rapid_framework.generator.provider.db.table.model.Table
* @throws Exception
*/
public void deleteByAllTable() throws Exception {
new ProcessUtils().processByAllTable(true);
}
/**
* 根据Table生成文件,模板引用的变量名称为: table, 实体类为: @see cn.org.rapid_framework.generator.provider.db.table.model.Table
* @throws Exception
*/
public void generateByTable(String... tableNames) throws Exception {
for(String tableName : tableNames) {
new ProcessUtils().processByTable(tableName,false);
}
}
/**
* 根据Table删除生成的文件,模板引用的变量名称为: table 实体类为: cn.org.rapid_framework.generator.provider.db.table.model.Table
* @throws Exception
*/
public void deleteByTable(String... tableNames) throws Exception {
for(String tableName : tableNames) {
new ProcessUtils().processByTable(tableName,true);
}
}
/**
* 根据Class生成文件,模板引用的变量名称为: clazz 实体类为: cn.org.rapid_framework.generator.provider.java.model.JavaClass
*/
public void generateByClass(Class... clazzes) throws Exception {
for(Class clazz : clazzes) {
new ProcessUtils().processByClass(clazz,false);
}
}
/**
* 根据Class删除生成的文件,模板引用的变量名称为: clazz 实体类为: cn.org.rapid_framework.generator.provider.java.model.JavaClass
*/
public void deleteByClass(Class... clazzes) throws Exception {
for(Class clazz : clazzes) {
new ProcessUtils().processByClass(clazz,true);
}
}
/**
* 根据Sql生成文件,模板引用的变量名称为: sql
*/
public void generateBySql(Sql... sqls) throws Exception {
for(Sql sql : sqls) {
new ProcessUtils().processBySql(sql,false);
}
}
/**
* 根据Sql删除生成的文件,模板引用的变量名称为: sql
*/
public void deleteBySql(Sql... sqls) throws Exception {
for(Sql sql : sqls) {
new ProcessUtils().processBySql(sql,true);
}
}
public Generator getGenerator() {
return generator;
}
public void setGenerator(Generator generator) {
this.generator = generator;
}
public class ProcessUtils {
public void processByGeneratorModel(GeneratorModel model,boolean isDelete) throws Exception, FileNotFoundException {
Generator g = getGenerator();
GeneratorModel targetModel = GeneratorModelUtils.newDefaultGeneratorModel();
targetModel.filePathModel.putAll(model.filePathModel);
targetModel.templateModel.putAll(model.templateModel);
processByGeneratorModel(isDelete, g, targetModel);
}
public void processByMap(Map params,boolean isDelete) throws Exception, FileNotFoundException {
Generator g = getGenerator();
GeneratorModel m = GeneratorModelUtils.newFromMap(params);
processByGeneratorModel(isDelete, g, m);
}
public void processBySql(Sql sql,boolean isDelete) throws Exception {
Generator g = getGenerator();
GeneratorModel m = GeneratorModelUtils.newGeneratorModel("sql",sql);
PrintUtils.printBeginProcess("sql:"+sql.getSourceSql(),isDelete);
processByGeneratorModel(isDelete,g,m);
}
public void processByClass(Class clazz,boolean isDelete) throws Exception, FileNotFoundException {
Generator g = getGenerator();
GeneratorModel m = GeneratorModelUtils.newGeneratorModel("clazz",new JavaClass(clazz));
PrintUtils.printBeginProcess("JavaClass:"+clazz.getSimpleName(),isDelete);
processByGeneratorModel(isDelete, g, m);
}
private void processByGeneratorModel(boolean isDelete, Generator g,
GeneratorModel m)
throws Exception,
FileNotFoundException {
try {
if(isDelete)
g.deleteBy(m.templateModel, m.filePathModel);
else
g.generateBy(m.templateModel, m.filePathModel);
}catch(GeneratorException ge) {
PrintUtils.printExceptionsSumary(ge.getMessage(),getGenerator().getOutRootDir(),ge.getExceptions());
throw ge;
}
}
public void processByTable(String tableName,boolean isDelete) throws Exception {
if("*".equals(tableName)) {
if(isDelete)
deleteByAllTable();
else
generateByAllTable();
return;
}
Generator g = getGenerator();
Table table = TableFactory.getInstance().getTable(tableName);
try {
processByTable(g,table,isDelete);
}catch(GeneratorException ge) {
PrintUtils.printExceptionsSumary(ge.getMessage(),getGenerator().getOutRootDir(),ge.getExceptions());
throw ge;
}
}
public void processByAllTable(boolean isDelete) throws Exception {
List<Table> tables = TableFactory.getInstance().getAllTables();
List exceptions = new ArrayList();
for(int i = 0; i < tables.size(); i++ ) {
try {
processByTable(getGenerator(),tables.get(i),isDelete);
}catch(GeneratorException ge) {
exceptions.addAll(ge.getExceptions());
}
}
PrintUtils.printExceptionsSumary("",getGenerator().getOutRootDir(),exceptions);
if(!exceptions.isEmpty()) {
throw new GeneratorException("batch generate by all table occer error",exceptions);
}
}
public void processByTable(Generator g, Table table,boolean isDelete) throws Exception {
GeneratorModel m = GeneratorModelUtils.newGeneratorModel("table",table);
PrintUtils.printBeginProcess(table.getSqlName()+" => "+table.getClassName(),isDelete);
if(isDelete)
g.deleteBy(m.templateModel,m.filePathModel);
else
g.generateBy(m.templateModel,m.filePathModel);
}
}
@SuppressWarnings("all")
public static class GeneratorModelUtils {
public static GeneratorModel newGeneratorModel(String key,Object valueObject) {
GeneratorModel gm = newDefaultGeneratorModel();
gm.templateModel.put(key, valueObject);
gm.filePathModel.putAll(BeanHelper.describe(valueObject));
return gm;
}
public static GeneratorModel newFromMap(Map params) {
GeneratorModel gm = newDefaultGeneratorModel();
gm.templateModel.putAll(params);
gm.filePathModel.putAll(params);
return gm;
}
public static GeneratorModel newDefaultGeneratorModel() {
Map templateModel = new HashMap();
templateModel.putAll(getShareVars());
Map filePathModel = new HashMap();
filePathModel.putAll(getShareVars());
return new GeneratorModel(templateModel,filePathModel);
}
public static Map getShareVars() {
Map templateModel = new HashMap();
templateModel.putAll(System.getProperties());
templateModel.putAll(GeneratorProperties.getProperties());
templateModel.put("env", System.getenv());
templateModel.put("now", new Date());
templateModel.put(GeneratorConstants.DATABASE_TYPE.code, GeneratorProperties.getDatabaseType(GeneratorConstants.DATABASE_TYPE.code));
templateModel.putAll(GeneratorContext.getContext());
templateModel.putAll(getToolsMap());
return templateModel;
}
/** 得到模板可以引用的工具类 */
private static Map getToolsMap() {
Map toolsMap = new HashMap();
String[] tools = GeneratorProperties.getStringArray(GENERATOR_TOOLS_CLASS);
for(String className : tools) {
try {
Object instance = ClassHelper.newInstance(className);
toolsMap.put(Class.forName(className).getSimpleName(), instance);
GLogger.debug("put tools class:"+className+" with key:"+Class.forName(className).getSimpleName());
}catch(Exception e) {
GLogger.error("cannot load tools by className:"+className+" cause:"+e);
}
}
return toolsMap;
}
}
private static class PrintUtils {
private static void printExceptionsSumary(String msg,String outRoot,List<Exception> exceptions) throws FileNotFoundException {
File errorFile = new File(outRoot,"generator_error.log");
if(exceptions != null && exceptions.size() > 0) {
System.err.println("[Generate Error Summary] : "+msg);
errorFile.getParentFile().mkdirs();
PrintStream output = new PrintStream(new FileOutputStream(errorFile));
for(int i = 0; i < exceptions.size(); i++) {
Exception e = exceptions.get(i);
System.err.println("[GENERATE ERROR]:"+e);
if(i == 0) e.printStackTrace();
e.printStackTrace(output);
}
output.close();
System.err.println("***************************************************************");
System.err.println("* "+"* 输出目录已经生成generator_error.log用于查看错误 ");
System.err.println("***************************************************************");
}
}
private static void printBeginProcess(String displayText,boolean isDatele) {
GLogger.println("***************************************************************");
GLogger.println("* BEGIN " + (isDatele ? " delete by " : " generate by ")+ displayText);
GLogger.println("***************************************************************");
}
public static void printAllTableNames(List<Table> tables) throws Exception {
GLogger.println("\n----All TableNames BEGIN----");
for(int i = 0; i < tables.size(); i++ ) {
String sqlName = ((Table)tables.get(i)).getSqlName();
GLogger.println("g.generateTable(\""+sqlName+"\");");
}
GLogger.println("----All TableNames END----");
}
}
}