org.swan.plugin.DbMojo Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.swan.plugin;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.type.MapType;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.swan.plugin.bean.Field;
import org.swan.plugin.bean.Pojo;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;
import static org.swan.plugin.ConfigFileMojo.DEFAULT_CONFIG_JSON;
/**
* Goal which generate pojo file from db
*/
@Mojo(name = "db", defaultPhase = LifecyclePhase.PROCESS_SOURCES,threadSafe = true)
public class DbMojo extends AbstractMojo {
public static final String TABLE_NAME = "TABLE_NAME";
@Parameter(defaultValue = "${project.basedir}/template", property = "db.dataPath", required = true)
private File basedir;
@Parameter(defaultValue = "", property = "db.driver", required = true)
private String driver;
@Parameter(defaultValue = "", property = "db.url", required = true)
private String url;
@Parameter(defaultValue = "", property = "db.user", required = true)
private String user;
@Parameter(defaultValue = "", property = "db.password", required = true)
private String password;
@Parameter(defaultValue = "", property = "db.database", required = true)
private String database;
@Parameter(defaultValue = "", property = "db.schema", required = true)
private String schema;
@Parameter(defaultValue = "", property = "db.packageName", required = true)
private String packageName;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Map defaultData = new TreeMap<>(Comparator.comparingInt(String::length));
defaultData.putAll(loadDefaultData());
try {
Class.forName(driver);
try (Connection connection = DriverManager.getConnection(url, user, password)) {
DatabaseMetaData metaData = connection.getMetaData();
getLog().info("database:" + database + "\tschema:" + schema);
ResultSet resultSet = metaData.getColumns(database, schema, null, null);
processDbColumn(resultSet, (tableName, fields) -> exportPojo(defaultData, tableName, getNewPojo(tableName).setFields(fields)));
}
} catch (ClassNotFoundException | SQLException e) {
getLog().error(e);
}
}
/**
* export pojo to file/files
*
* @param defaultData default data in config file
* @param tableName table name
* @param pojo pojo instance
* @throws IOException
*/
private void exportPojo(Map defaultData, String tableName, Pojo pojo) {
if (pojo != null) {
//Save to file
File f = basedir;
if (!f.exists())
f.mkdirs();
f = new File(f, tableName + ".pojo.json");
if (!f.exists()) {
ObjectMapper om = new ObjectMapper();
AtomicReference tmp = new AtomicReference<>();
final Pojo finalPojo = pojo;
defaultData.entrySet().stream().filter(entry -> Pattern.compile(entry.getKey()).matcher(finalPojo.getId()).matches()).forEach(entry -> tmp.set(mergePojo(tmp.get(), entry.getValue(), om)));
tmp.set(mergePojo(tmp.get(), pojo, om));
try {
new ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(new FileWriter(f), new Pojo[]{tmp.get()});
getLog().info(f.getName() + " created successfully.");
} catch (IOException e) {
getLog().info(f.getName() + " created fail with exception:" + e.getMessage());
}
}
}
}
/**
* Create Pojo instance from table information
*
* @param tableName table information
* @return
*/
private Pojo getNewPojo(String tableName) {
String className = tableName;
className = Character.toUpperCase(className.charAt(0)) + className.substring(1);
Pojo.TemplateBean templateBean = new Pojo.TemplateBean().setClassName(className);
Pojo newPojo = new Pojo().setId(className).addTemplate(templateBean);
if (packageName != null && !packageName.trim().isEmpty()) {
templateBean.setPackageName(packageName);
}
return newPojo;
}
private Pojo mergePojo(Pojo source, Pojo override, ObjectMapper objectMapper) {
if (source == null) {
return override;
}
if (override == null)
return source;
ObjectReader updater = objectMapper.readerForUpdating(source);
try {
return updater.readValue(objectMapper.writeValueAsString(override));
} catch (JsonProcessingException e) {
return source;
}
}
private Map loadDefaultData() {
ObjectMapper om = new ObjectMapper();
MapType mapType = om.getTypeFactory().constructMapType(Map.class, String.class, Pojo.class);
File f = new File(basedir, DEFAULT_CONFIG_JSON);
if (f.exists()) {
try {
return om.readValue(f, mapType);
} catch (IOException e) {
return new HashMap<>();
}
}
return new HashMap<>();
}
private Map> processDbColumn(ResultSet resultSet, BiConsumer> consumer) throws SQLException {
Map> result = new HashMap<>();
String tableName = null;
List fields = new ArrayList<>();
while (resultSet.next()) {
if (!resultSet.getString(TABLE_NAME).equals(tableName)) {
getLog().info("table:" + resultSet.getString(TABLE_NAME));
result.put(tableName, fields);
if (consumer != null)
consumer.accept(tableName, fields);
fields = new ArrayList<>();
}
fields.add(new Field(resultSet.getString("COLUMN_NAME"), resultSet.getString("REMARKS"), typeMapper(resultSet.getInt("DATA_TYPE"))));
tableName = resultSet.getString(TABLE_NAME);
}
if (tableName != null) {
result.put(tableName, fields);
if (consumer != null)
consumer.accept(tableName, fields);
}
return result;
}
public static String typeMapper(int type) {
switch (type) {
case Types.BIT:
case Types.BOOLEAN:
return "boolean";
case Types.INTEGER:
case Types.TINYINT:
return "int";
case Types.BIGINT:
return "long";
case Types.DECIMAL:
case Types.DOUBLE:
case Types.FLOAT:
return "double";
case Types.BLOB:
case Types.CLOB:
case Types.VARBINARY:
case Types.BINARY:
case Types.LONGVARBINARY:
return "byte[]";
case Types.VARCHAR:
case Types.NVARCHAR:
case Types.LONGVARCHAR:
case Types.LONGNVARCHAR:
return "String";
case Types.TIMESTAMP:
case Types.DATE:
case Types.TIME:
return "LocalDateTime";
default:
return "String";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy