com.github.freegeese.maven.plugin.autocode.AutoCodeMojo Maven / Gradle / Ivy
package com.github.freegeese.maven.plugin.autocode;
import com.github.freegeese.maven.plugin.autocode.configuration.DefaultProperties;
import com.github.freegeese.maven.plugin.autocode.configuration.JdbcConnection;
import com.github.freegeese.maven.plugin.autocode.configuration.ModelType;
import com.github.freegeese.maven.plugin.autocode.configuration.Template;
import com.github.freegeese.maven.plugin.autocode.metadata.Column;
import com.github.freegeese.maven.plugin.autocode.metadata.Table;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;
import ognl.Ognl;
import ognl.OgnlException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Mojo(name = "autocode", threadSafe = true)
public class AutoCodeMojo extends AbstractMojo {
@Parameter(property = "freegeese.autocode.properties")
private Map properties = new LinkedHashMap<>();
@Parameter(property = "freegeese.autocode.jdbcConnection")
private JdbcConnection jdbcConnection;
@Parameter(property = "freegeese.autocode.tables")
private List tables;
@Parameter(property = "freegeese.autocode.templateDirectory")
private File templateDirectory;
@Parameter(property = "freegeese.autocode.templates")
private List templates;
private List dbTables = null;
private Configuration templateConfiguration = null;
public AutoCodeMojo() throws IOException {
templateConfiguration = new Configuration(Configuration.VERSION_2_3_24);
templateConfiguration.setDefaultEncoding("UTF-8");
}
public void execute() throws MojoExecutionException {
Log log = getLog();
try {
templateConfiguration.setDirectoryForTemplateLoading(templateDirectory);
// 属性设置
String customCodeStart = DefaultProperties.CUSTOM_CODE_START.name();
if (!properties.containsKey(customCodeStart)) {
properties.put(customCodeStart, customCodeStart);
}
String customCodeEnd = DefaultProperties.CUSTOM_CODE_END.name();
if (!properties.containsKey(customCodeEnd)) {
properties.put(customCodeEnd, customCodeEnd);
}
// 获取数据库所有的Table信息
log.info("获取数据连接:" + jdbcConnection);
Connection conn = DatabaseUtils.getConnection(jdbcConnection);
// 获取数据库所有表格信息
log.info("获取数据库所有表格元数据");
this.dbTables = DatabaseMetadataUtils.getAllTableMetadata(conn);
DatabaseUtils.closeConnection(conn);
// 解析Table配置信息
List filteredTables = new ArrayList<>();
for (Table cfgTable : this.tables) {
// 匹配Table元数据
Table dbTable = findTableMetadata(cfgTable.getTableCat(), cfgTable.getTableSchem(), cfgTable.getTableName());
// 完善Table配置信息
initTableConfiguration(cfgTable, dbTable);
// 合并数据库Table信息
Table merged = new Table();
BeanPropertyUtils.merge(merged, dbTable, cfgTable);
// model type
ModelType modelType = merged.getModelType();
if (null != modelType) {
modelType.setTable(merged);
}
filteredTables.add(merged);
// TODO: 2017/4/1 校验Table配置
}
// 根据模板配置,生成代码
for (Table table : filteredTables) {
// 一个Table对应所有模板
for (Template template : templates) {
generateCode(table, template);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void generateCode(Table table, Template template) {
FileWriter writer = null;
try {
Template initialized = initTemplateConfiguration(table, template);
freemarker.template.Template ftl = templateConfiguration.getTemplate(initialized.getName());
String outputPath = initialized.getOutputPath();
File outputFile = new File(outputPath);
// output file exists and template not override
if (outputFile.exists() && !template.isOverride()) {
getLog().info("output file exists(" + outputFile + ") -> skip");
return;
}
if (!outputFile.getParentFile().exists()) {
outputFile.getParentFile().mkdirs();
}
// process custom code
Map parameterMap = initialized.getParameterMap();
if (outputFile.exists()) {
String customCodeStart = initialized.getCustomCodeStart();
String customCodeEnd = initialized.getCustomCodeEnd();
// 已存在的标记内容
String oldMarkContent = Helper.findMarkContent(outputFile, customCodeStart, customCodeEnd);
writer = new FileWriter(outputFile);
ftl.process(parameterMap, writer);
// 根据模板生成的标记内容
String newMarkContent = Helper.findMarkContent(outputFile, customCodeStart, customCodeEnd);
if (null != oldMarkContent && null != newMarkContent) {
Path path = Paths.get(outputFile.getAbsolutePath());
String content = new String(Files.readAllBytes(path));
content = content.replace(newMarkContent, oldMarkContent);
Files.write(path, content.getBytes());
} else if (null != oldMarkContent) {
Helper.appendToTail(outputFile, oldMarkContent);
}
} else {
writer = new FileWriter(outputFile);
ftl.process(parameterMap, writer);
}
} catch (IOException | TemplateException e) {
e.printStackTrace();
} finally {
if (null != writer) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private Template initTemplateConfiguration(Table table, Template template) {
Template merged = new Template();
BeanPropertyUtils.merge(merged, template);
// template parameter merge
Map parameters = new LinkedHashMap<>();
parameters.put("table", table);
Map parameterMap = merged.getParameterMap();
if (null != parameterMap) {
parameters.putAll(parameterMap);
}
merged.setParameterMap(parameters);
// template output path
StringBuilder matchInput = new StringBuilder(merged.getOutputPath());
String regex = "(%ognl\\[[^\\[\\]]+])";
Matcher matcher = Pattern.compile(regex).matcher(matchInput.toString());
while (matcher.find()) {
String group = matcher.group();
String expression = group.substring("%ognl[".length(), group.length() - 1).trim();
try {
Object expressionResult = Ognl.getValue(expression, merged.getParameterMap());
matchInput.replace(matcher.start(), matcher.end(), expressionResult.toString());
} catch (OgnlException e) {
e.printStackTrace();
}
}
merged.setOutputPath(matchInput.toString());
// custom code mark
if (null == merged.getCustomCodeStart()) {
merged.setCustomCodeStart(properties.get(DefaultProperties.CUSTOM_CODE_START.name()));
}
if (null == merged.getCustomCodeEnd()) {
merged.setCustomCodeEnd(properties.get(DefaultProperties.CUSTOM_CODE_END.name()));
}
return merged;
}
/**
* 初始化Table配置信息
*
* @param cfgTable
* @param dbTable
* @return
*/
private Table initTableConfiguration(Table cfgTable, Table dbTable) {
Log log = getLog();
// init column configuration
log.info("init column configuration");
// 过滤后的列(这些列是最终确定需要的列)
List filteredColumns = new ArrayList<>();
List columns = dbTable.getColumns();
for (Column dbColumn : columns) {
Column column = initColumnConfiguration(cfgTable, dbColumn);
// ignore column
if (null == column) {
log.info("ignore column: " + dbColumn.getColumnName());
continue;
}
filteredColumns.add(column);
}
cfgTable.setFilteredColumns(filteredColumns);
// init model name
log.info("init model name");
if (null == cfgTable.getModelName()) {
cfgTable.setModelName(DatabaseMetadataUtils.underlineToCamelHump(cfgTable.getTableName()));
}
return cfgTable;
}
/**
* 初始化Column配置信息
*
* @param cfgTable
* @param column
* @return
*/
private Column initColumnConfiguration(Table cfgTable, Column column) {
List includeColumns = cfgTable.getIncludeColumns();
String columnName = column.getColumnName();
// 配置了include columns 但是没有包含此列
if (null != includeColumns && !includeColumns.contains(columnName)) {
return null;
}
// 配置了exclude columns 包含此列
List excludeColumns = cfgTable.getExcludeColumns();
if (null != excludeColumns && excludeColumns.contains(columnName)) {
return null;
}
// 主键列处理
Column idColumn = cfgTable.getIdColumn();
// 已配置主键列
if (null != idColumn && columnName.equalsIgnoreCase(idColumn.getColumnName())) {
return idColumn;
}
// 未配置主键列
if (null == idColumn && column.isPrimaryKey()) {
cfgTable.setIdColumn(column);
return column;
}
// 获取覆盖此列的配置
Column overrideColumn = findOverrideColumn(cfgTable, column);
if (null != overrideColumn) {
Column merged = new Column();
BeanPropertyUtils.merge(merged, column, overrideColumn);
return merged;
}
return column;
}
/**
* 匹配覆盖的列
*
* @param table
* @param column
* @return
*/
private Column findOverrideColumn(Table table, Column column) {
List overrideColumns = table.getColumns();
if (null == overrideColumns) {
return null;
}
for (Column overrideColumn : overrideColumns) {
if (overrideColumn.getColumnName().equalsIgnoreCase(column.getColumnName())) {
return overrideColumn;
}
}
return null;
}
/**
* 匹配对应的Table元数据
*
* @param catalog
* @param schema
* @param tableName
* @return
*/
private Table findTableMetadata(String catalog, String schema, String tableName) {
for (Table t : this.dbTables) {
if (null == catalog && null == schema) {
if (tableName.equalsIgnoreCase(t.getTableName())) {
return t;
}
continue;
}
if (null == catalog) {
if (catalog.equalsIgnoreCase(t.getTableCat()) && tableName.equalsIgnoreCase(t.getTableName())) {
return t;
}
continue;
}
if (null == schema) {
if (schema.equalsIgnoreCase(t.getTableSchem()) && tableName.equalsIgnoreCase(t.getTableName())) {
return t;
}
continue;
}
if (catalog.equalsIgnoreCase(t.getTableCat()) && schema.equalsIgnoreCase(t.getTableSchem()) && tableName.equalsIgnoreCase(t.getTableName())) {
return t;
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy