Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gu.sql2java.generator.CodeWriter Maven / Gradle / Ivy
package gu.sql2java.generator;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.FieldMethodizer;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.SortTool;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.primitives.Primitives;
import gu.sql2java.velocity.Sql2javaClasspathResourceLoader;
import gu.sql2java.velocity.Sql2javaFileResourceLoader;
import net.gdface.utils.ClassLoaderUtils;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;;
public class CodeWriter {
public static final String NEW_LINE = System.getProperty("line.separator");
protected static final String DEFAULT_BINARY_TYPE = "byte[]";
protected static final String DEFAULT_BITSTAE_TYPE = "int";
private static final String VAR_EXT_PKG = "extensionPkg";
protected static Properties props;
public static String MGR_CLASS;
protected static String dateClassName;
protected static String timeClassName;
protected static String timestampClassName;
/** type for byte array,default 'byte[]',defined in properties */
public static String binaryClassName;
private static boolean byteBufferAsString;
private static String bitStateClassName;
private static Class> bitStateClass;
private static int bitStateClassSize;
private static String bitStateConstSuffix;
protected static Database db;
protected static Hashtable includeHash;
protected static Hashtable excludeHash;
protected static String basePackage;
/** 参见 {@link Column#getPreparedStatementMethod(String, String)} */
private static final ThreadLocal fillNull = new ThreadLocal(){
@Override
protected Boolean initialValue() {
return true;
}};
protected static String destDir;
protected static String optimisticLockType;
protected static String optimisticLockColumn;
protected static String geometrySerialType;
public static String classPrefix;
protected VelocityContext vc;
public Table table;
protected VelocityContext current_vc;
String current_fullfilename = "";
String current_filename = "";
/** 是否保存当前文件标志,模板可以通过改写此标志,跳过模板生成 */
boolean save_current_file = true;
private static String[] extLibdirs;
private static String[] extClasspath;
private static URLClassLoader extensionClassLoader;
private static boolean jsonJacksonRawValue;
private static boolean jacksonClassDeserializer;
private static boolean fastjsonClassDeserializer;
private static String superClassPackage;
private static Set superClassTablenames;
private static String samePrefixOfSuperClassTables;
private static Table[] superClassTables;
public CodeWriter(Database db, Properties props) {
try {
CodeWriter.db = db;
CodeWriter.props = props;
dateClassName = getProperty("jdbc2java.date", "java.sql.Date");
timeClassName = getProperty("jdbc2java.time", "java.sql.Time");
timestampClassName = getProperty("jdbc2java.timestamp", "java.sql.Timestamp");
binaryClassName = getProperty("binary.type", DEFAULT_BINARY_TYPE);
byteBufferAsString = getPropertyBoolean("binary.ByteBuffer.asString");
Column.setByteBufferAsString(byteBufferAsString);
bitStateClassName = getProperty("bitstate.type", DEFAULT_BITSTAE_TYPE);
bitStateClass = bitStateClassOf(bitStateClassName);
bitStateClassSize = bitSizeOf(bitStateClass);
bitStateConstSuffix = constSuffixOf(bitStateClassName);
basePackage = getPropertyRequired("codewriter.package");
extLibdirs = getPropertyExploded("extension.tools.libdirs");
extClasspath = getPropertyExploded("extension.tools.classpath");
classPrefix = props.getProperty("codewriter.classprefix");
this.setDestinationFolder(getPropertyRequired("codewriter.destdir"));
excludeHash = this.setHash(props.getProperty("tables.exclude"));
if (excludeHash.size() != 0) {
System.out.println("Excluding the following tables: " + props.getProperty("tables.exclude"));
}
if ((CodeWriter.includeHash = this.setHash(props.getProperty("tables.include"))).size() != 0) {
System.out.println("Including only the following tables: " + props.getProperty("tables.include"));
}
optimisticLockType = props.getProperty("optimisticlock.type", "none");
optimisticLockColumn = props.getProperty("optimisticlock.column");
jsonJacksonRawValue = getPropertyBoolean("json.jackson.rawvalue");
jacksonClassDeserializer = getPropertyBoolean("json.jackson.class.deserializer");
fastjsonClassDeserializer = getPropertyBoolean("json.fastjson.class.deserializer");
geometrySerialType = getProperty("codewrite.bean.geometry.serial.type");
Column.setJsonJacksonRawValue(jsonJacksonRawValue);
Column.setJacksonBeanSupport(getPropertyBoolean("jackson.annotation.bean"));
Column.setGeometrySerialType(geometrySerialType);
superClassPackage = getProperty("codewrite.bean.superClassPackage","");
superClassTablenames = getPropertyExplodedAsSet("codewrite.bean.superClassTables").stream().collect(Collectors.toCollection(TreeSet::new));
samePrefixOfSuperClassTables = Database.computeSamePrefix(superClassTablenames, getProperty("codewrite.bean.samePrefixOfSuperClassTables"));
} catch (Exception e) {
System.err.println("Threw an exception in the CodeWriter constructor:" + e.getMessage());
e.printStackTrace();
}
}
public void setDestinationFolder(String destDir) throws Exception {
CodeWriter.destDir = destDir;
if (destDir == null) {
throw new Exception("Missing property: codewriter.destdir");
}
File dir = new File(destDir);
try {
dir.mkdirs();
} catch (Exception e) {
// empty catch block
}
if (!dir.isDirectory() || !dir.canWrite()) {
throw new Exception("Cannot write to: " + destDir);
}
}
private Hashtable setHash(String str) {
if (str == null || str.trim().equals("")) {
return new Hashtable();
}
Hashtable hash = new Hashtable();
StringTokenizer st = new StringTokenizer(str);
while (st.hasMoreTokens()) {
String val = st.nextToken().toLowerCase();
hash.put(val, val);
}
return hash;
}
public boolean checkTable(Table newTable) throws Exception {
System.out.println(" checking table " + newTable.getName() + " ...");
boolean error = false;
Column[] primaryKeys = newTable.getPrimaryKeys();
if (newTable.getColumns().length == 0) {
System.err.println(" WARN : no column found !");
error = false;
}
if (primaryKeys.length == 0) {
System.err.println(" WARN : No primary key is defined on table " + newTable.getName());
System.err.println(" Tables without primary key are not fully supported");
error = false;
} else if (primaryKeys.length > 1) {
System.err.print(" WARN : Composite primary key ");
for (int ii = 0; ii < primaryKeys.length; ++ii) {
System.err.print(primaryKeys[ii].getFullName() + ", ");
}
System.err.println();
System.err.println(" Tables with composite primary key are not fully supported");
} else {
String normalKey;
Column pk = primaryKeys[0];
String pkName = pk.getName();
if (!pkName.equalsIgnoreCase(normalKey = newTable.getName() + "_id")) {
System.err.println(" WARN : primary key should be of form _ID");
System.err.println(" found " + pkName + " expected " + normalKey);
}
if (!pk.isColumnNumeric()) {
System.err.println(" WARN : primary key should be a number ");
System.err.println(" found " + pk.getJavaType());
}
}
return error;
}
public void checkDatabase() throws Exception {
System.out.println("Checking database tables");
boolean error = false;
Table[] tables = db.getTables();
for (int i = 0; i < tables.length; ++i) {
if (!CodeWriter.authorizeProcess(tables[i].getName(), "tables.include", "tables.exclude")
|| !this.checkTable(tables[i]))
continue;
error = true;
}
if (error) {
System.err.println(
" Failed : at least one of the mandatory rule for sql2java is followed by your schema.");
System.err.println(" Please check the documentation for more information");
System.exit(-1);
}
System.out.println(" Passed.");
}
public synchronized void process() throws Exception {
if ("true".equalsIgnoreCase(getProperty("check.database"))) {
this.checkDatabase();
}
if ("true".equalsIgnoreCase(getProperty("check.only.database"))) {
return;
}
Properties vprops = new Properties();
vprops.put(Velocity.RESOURCE_LOADER,"class,file");
vprops.put(Velocity.FILE_RESOURCE_LOADER_PATH, Joiner.on(',').join(this.getLoadingPathExt()));
vprops.put("file.resource.loader.class", Sql2javaFileResourceLoader.class.getName());
vprops.put("class.resource.loader.description", "Velocity Classpath Resource Loader");
vprops.put("class.resource.loader.class",Sql2javaClasspathResourceLoader.class.getName());
vprops.put("class.resource.loader.prefix", Joiner.on(',').join(this.getClassLoadingPath()));
vprops.put(Velocity.VM_LIBRARY, "/templates/velocity/includes/macros.include.vm");
vprops.put(Velocity.SET_NULL_ALLOWED, "true");
vprops.put(Velocity.INPUT_ENCODING,"UTF-8");
vprops.put(Velocity.OUTPUT_ENCODING,"UTF-8");
Velocity.init(vprops);
this.vc = new VelocityContext();
this.vc.put("CodeWriter", (Object) new FieldMethodizer((Object) this));
this.vc.put("codewriter", (Object) this);
this.vc.put("esc", new EscapeTool());
this.vc.put("sorter", new SortTool());
this.vc.put("pkg", (Object) basePackage);
this.vc.put(VAR_EXT_PKG,getExtensionPkg());
this.vc.put("isGeneral", Boolean.TRUE);
this.vc.put("pkgPath", (Object) basePackage.replace('.', '/'));
this.vc.put("strUtil",StringUtilities.getInstance());
this.vc.put("fecha", new Date());
this.current_vc = new VelocityContext((Context) this.vc);
generate("velocity.templates");
// 如果定义了扩展模板的输出文件夹就用它替换destDir,用完后恢复
String destDirExt = getProperty("codewriter.destdir.extension","");
String oldDest = destDir;
if(!destDirExt.isEmpty()){
destDir = destDirExt;
}
try{
// 生成外部扩展模板代码
generate("velocity.templates.extension");
}finally{
destDir = oldDest;
}
}
private void generate(String propName) throws Exception{
if(null == getProperty(propName))
return;
String[] schema_templates = this.getSchemaTemplates(propName);
for (int i = 0; i < schema_templates.length; ++i) {
this.writeComponent(schema_templates[i]);
}
if ("true".equalsIgnoreCase(getProperty("write.only.per.schema.templates"))) {
return;
}
Table[] tables = db.getTables();
for (int i2 = 0; i2 < tables.length; ++i2) {
if (!CodeWriter.authorizeProcess(tables[i2].getName(), "tables.include", "tables.exclude"))
continue;
this.writeTable(tables[i2], propName);
}
}
private void writeTable(Table currentTable, String propName) throws Exception {
if (currentTable.getColumns().length == 0) {
return;
}
this.current_vc = new VelocityContext((Context) this.vc);
this.table = currentTable;
this.current_vc.put("table", (Object) currentTable);
String[] table_templates = this.getTableTemplates(propName);
for (int i = 0; i < table_templates.length; ++i) {
this.writeComponent(table_templates[i]);
}
}
private String clearHeadOfLoadPath(String templateName){
checkNotNull(templateName);
List loadPath = getLoadingPathExt();
File template= new File(templateName);
for(String path:loadPath){
File pfile = new File(path);
try {
if(template.getCanonicalPath().startsWith(pfile.getCanonicalPath())){
String tmpl = template.getCanonicalPath().replace(pfile.getCanonicalPath(), "").replace('\\', '/');
if(Velocity.resourceExists(tmpl)){
return tmpl;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return templateName;
}
private static final String PREFIX_DESTDIR = "destdir.";
private static final String PREFIX_PACKAGE = "package.";
private String backupDestDir;
private String backupExtensionPkg;
/**
* 改变脚本支持上下文
* 如果为模板定义了目标输出文件夹('destdir.${template name}'属性),则使用指定的位置作为{@link #destDir}
* 如果为模板定义包名('package.${template name}'属性),则使用指定的值为引擎上下文的'extensionPkg'属性值
* @param templateName 模板文件名
*/
private void changeContextIfNeeded(String templateName){
String name = templateName.substring(templateName.lastIndexOf("/") + 1);
backupDestDir = destDir;
backupExtensionPkg = (String) this.vc.get(VAR_EXT_PKG);
destDir = getProperty(PREFIX_DESTDIR + name, destDir);
this.vc.put(VAR_EXT_PKG,getProperty(PREFIX_PACKAGE + name, backupExtensionPkg));
}
/**
* 恢复脚本支持上下文
* 恢复{@link #destDir}的值,
* 恢复引擎上下文的'extensionPkg'属性值
* 需要与{@link #changeDestDirIfNeeded}成对调用
*/
private void restoreContext(){
destDir = backupDestDir;
this.vc.put(VAR_EXT_PKG,backupExtensionPkg);
}
public void writeComponent(String templateName) throws Exception {
try {
templateName = clearHeadOfLoadPath(templateName);
System.out.println("Generating template " + templateName);
Velocity.getTemplate((String) templateName);
} catch (ResourceNotFoundException rnfe) {
System.err.println("Aborted writing component:" + templateName
+ (this.table != null
? new StringBuffer().append(" for table:").append(this.table.getName()).toString()
: "")
+ " because Velocity could not find the resource.");
return;
} catch (ParseErrorException pee) {
System.err.println("Aborted writing component:" + templateName
+ (this.table != null
? new StringBuffer().append(" for table:").append(this.table.getName()).toString()
: "")
+ " because there was a parse error in the resource.\n" + pee.getLocalizedMessage());
return;
} catch (Exception e) {
System.err.println("Aborted writing component:" + templateName
+ (this.table != null
? new StringBuffer().append(" for table:").append(this.table.getName()).toString()
: "")
+ " there was an error initializing the template.\n" + e.getLocalizedMessage());
return;
}
StringWriter sw = new StringWriter();
// reset
save_current_file = true;
this.current_vc.put("template", new File(templateName).getName());
try {
changeContextIfNeeded(templateName);
Velocity.mergeTemplate((String) templateName, (String) "UTF-8", (Context) this.current_vc, (Writer) sw);
} finally {
restoreContext();
}
if(save_current_file){
System.out.println(" .... writing to " + this.current_fullfilename);
File file = new File(this.current_fullfilename);
new File(file.getParent()).mkdirs();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.current_fullfilename),"UTF-8"));
// 换行符归一化:所有换行符替换为当前系统的换行符
String content = Pattern.compile("(\r\n|\n|\r)", Pattern.MULTILINE).matcher(sw.toString()).replaceAll(NEW_LINE);
writer.write(content);
writer.flush();
writer.close();
System.out.println(" " + this.current_filename + " done.");
}else
System.out.println(" " + this.current_filename + " skip.");
}
public void setCurrentFilename(String relpath_or_package, String fn) throws Exception {
this.current_filename = relpath_or_package.replace('.', File.separatorChar) + File.separatorChar + fn;
this.current_fullfilename = destDir + File.separatorChar + relpath_or_package.replace('.', File.separatorChar)
+ File.separatorChar + fn;
UserCodeParser uc = new UserCodeParser(this.current_fullfilename);
this.current_vc.put("userCode", (Object) uc);
}
public void setCurrentJavaFilename(String relpath_or_package, String fn) throws Exception {
this.setCurrentFilename("java" + File.separatorChar + relpath_or_package, fn);
}
public void log(String logStr) {
System.out.println(" " + logStr);
}
public static String getClassPrefix() {
return classPrefix;
}
public Database getDb() {
return db;
}
public List getTables() {
Table[] tabs = db.getTables();
ArrayList tables = new ArrayList(tabs.length);
for (int i = 0; i < tabs.length; ++i) {
tables.add(tabs[i]);
}
return tables;
}
public Table getTable(String tableName) {
return db.getTable(tableName);
}
public List getRelationTables() {
Table[] tabs = db.getTables();
ArrayList tables = new ArrayList(tabs.length);
for (int i = 0; i < tabs.length; ++i) {
if (!tabs[i].isRelationTable())
continue;
tables.add(tabs[i]);
}
return tables;
}
public String tableName() {
if (this.table == null) {
return "";
}
return this.table.getName();
}
public Table getTable() {
return this.table;
}
public static String getProperty(String key) {
String s = props.getProperty(key);
return s != null ? s.trim() : s;
}
public static String getProperty(String key, String defaultVal) {
String s = props.getProperty(key, defaultVal);
return s != null ? s.trim() : s;
}
public static String getPropertyRequired(String property) {
return checkNotNull(getProperty(property),"Missing property %s",property).trim();
}
public static String[] getPropertyExploded(String key) {
return getPropertyExploded(key, "");
}
public static Set getPropertyExplodedAsSet(String key) {
return getPropertyExploded(key, "",new LinkedHashSet<>());
}
public static List getPropertyExplodedAsList(String key) {
return getPropertyExplodedAsList(key, "");
}
private static > C getPropertyExploded(String mkey, String defaultValue,C collection) {
String v = getProperty(mkey,defaultValue);
return CodeWriter.getExplodedString(v,collection);
}
public static List getPropertyExplodedAsList(String mkey, String defaultValue) {
return CodeWriter.getPropertyExploded(mkey,defaultValue,new ArrayList<>());
}
public static String[] getPropertyExploded(String mkey, String defaultValue) {
return getPropertyExplodedAsList(mkey,defaultValue).toArray(new String[0]);
}
private static > C getExplodedString(String value,C collection) {
if (value != null) {
StringTokenizer st = new StringTokenizer(value, " ,;\t");
while (st.hasMoreTokens()) {
collection.add(st.nextToken().trim());
}
}
return collection;
}
public static List getExplodedStringAsList(String value) {
return getExplodedString(value,new ArrayList<>());
}
public static String[] getExplodedString(String value) {
return getExplodedStringAsList(value).toArray(new String[0]);
}
public static boolean getPropertyBoolean(String value){
try{
Pattern p = Pattern.compile("yes|true|on",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(getProperty(value,""));
return m.matches();
}catch(Exception e){
return false;
}
}
public static Integer getPropertyInteger(String value){
try{
return Integer.parseInt(getProperty(value,"0"));
}catch(Exception e){
return null;
}
}
public List getClassLoadingPath() {
return getPropertyExplodedAsList("velocity.templates.loadingpath", "/templates/velocity/includes,/templates/velocity");
}
public List getLoadingPathExt() {
return getPropertyExplodedAsList("velocity.templates.loadingpath.extension", "");
}
public String[] getSchemaTemplates(String property) {
return this.getTemplates(property, true);
}
public String[] getTableTemplates(String property) {
return this.getTemplates(property, false);
}
public String[] getTemplates(String property, boolean perShema) {
Vector files = new Vector();
// 支持多个模板路径
for(String path:getPropertyExploded(property)){
this.recurseTemplate(files, path, perShema);
}
return files.toArray(new String[files.size()]);
}
public Vector recurseTemplate(Vector files, String folder, boolean perSchema) {
Iterable dirEntries;
String schemaOrTable = perSchema ? "perschema" : "pertable";
try {
String content = (String) RuntimeSingleton.getContent(folder).getData();
String[] entires = content.split("\n");
dirEntries = Iterables.filter(Lists.newArrayList(entires),new Predicate() {
@Override
public boolean apply(String filename) {
if (filename.endsWith("/")) {
return true;
}
if (!filename.endsWith(".vm")) {
return false;
}
return CodeWriter.authorizeProcess(filename, "template.file.include",
"template.file.exclude");
}
});
} catch (ResourceNotFoundException e) {
return files;
}
for (Iterator itor = dirEntries.iterator();itor.hasNext();) {
String file = itor.next();
if (file.endsWith(".vm")) {
if (!CodeWriter.authorizeFile(folder, schemaOrTable))
continue;
files.add(StringUtilities.combinePath(folder,file));
continue;
}
this.recurseTemplate(files, StringUtilities.combinePath(folder,file), perSchema);
}
return files;
}
public static boolean authorizeProcess(String autorizePattern, String includeProperty, String excludeProperty) {
boolean accept = true;
String[] include = CodeWriter.getPropertyExploded(includeProperty);
String[] exclude = CodeWriter.getPropertyExploded(excludeProperty);
if (include.length != 0) {
if (CodeWriter.isInArray((String[]) include, (String) autorizePattern)) {
Velocity.getLog().info("Processing " + autorizePattern + " (specified in " + includeProperty + ")");
return true;
}
accept = false;
}
if (exclude.length != 0 && CodeWriter.isInArray((String[]) exclude, (String) autorizePattern)) {
Velocity.getLog().info("Skipping " + autorizePattern + " (specified in " + excludeProperty + ")");
return false;
}
return accept;
}
public static boolean folderContainsPattern(String folder, String[] patterns) {
if (patterns == null || folder == null) {
return false;
}
for (int i = 0; i < patterns.length; ++i) {
String pattern = "/" + patterns[i].toLowerCase() + "/";
if (folder.toLowerCase().indexOf(pattern) == -1)
continue;
return true;
}
return false;
}
public static boolean authorizeFile(String folder, String schemaOrTable) {
if (folder.toLowerCase().indexOf(schemaOrTable.toLowerCase()) == -1) {
return false;
}
String[] include = CodeWriter.getPropertyExploded("template.folder.include");
String[] exclude = CodeWriter.getPropertyExploded("template.folder.exclude");
if (include.length != 0) {
if (CodeWriter.folderContainsPattern(folder, include)) {
return true;
}
return false;
}
if (exclude.length != 0) {
if (CodeWriter.folderContainsPattern(folder, exclude)) {
return false;
}
return true;
}
return true;
}
static {
MGR_CLASS = "Manager";
classPrefix = "";
}
public static String getBinaryClassName() {
return binaryClassName;
}
public static boolean isByteBufferAsString() {
return byteBufferAsString;
}
public static String getBitStateClassName() {
return bitStateClassName;
}
public static String getBitStateClassWrapName() {
return Primitives.wrap(bitStateClass).getSimpleName();
}
public Class> getBitStateClass() {
return bitStateClass;
}
public static int getBitStateClassSize() {
return bitStateClassSize;
}
private static Class> bitStateClassOf(String className) {
switch(className){
case "byte":
return byte.class;
case "short":
return short.class;
case "int":
return int.class;
case "long":
return long.class;
}
throw new IllegalArgumentException("INVALID class name for state type [" + className + "]");
}
private static int bitSizeOf(Class> clazz) {
try {
// access field such as Integer.SIZE
Field size = Primitives.wrap(clazz).getField("SIZE");
return size.getInt(null);
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
private static String constSuffixOf(String className) {
if("byte".equals(className)){
return "";
}
if("shot".equals(className)){
return "";
}
if("int".equals(className)){
return "";
}
if("long".equals(className)){
return "L";
}
throw new IllegalArgumentException("INVALID class name for state type [" + className + "]");
}
public static String getBitStateConstSuffix() {
return bitStateConstSuffix;
}
public static int getBitStateMask() {
return (1< loadClass(String classname,ClassLoader classLoader) throws ClassNotFoundException{
return null == classLoader?
Class.forName(classname) : Class.forName(classname,true,classLoader);
}
/**
* 加载指定的类
* 读取 'extension.tools.libdirs','extension.tools.classpath'分别对应{@code libdirs,classpath}参数
* 如果上述property都没有定义则抛出异常
* @param classname
* @return 加载的类
* @throws ClassNotFoundException
*/
public static Class> loadExtensionClass(String classname) throws ClassNotFoundException{
return loadClass(classname,getExtensionClassLoader());
}
private static synchronized URLClassLoader getExtensionClassLoader(){
if(null ==extensionClassLoader){
if( 0 == extLibdirs.length && 0 == extClasspath.length)
throw new IllegalStateException("property 'extension.tools.libdirs' and 'extension.tools.classpath' is all undefined");
extensionClassLoader = ClassLoaderUtils.makeURLClassLoader(CodeWriter.class.getClassLoader(),true, extLibdirs, extClasspath);
}
return extensionClassLoader;
}
/**
* 使用当前类的class loader加载工具对象
* @param classname
* @return 创建的对象
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public Object loadTool(String classname) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class> clazz = loadClass(classname,null);
return clazz.newInstance();
}
private static boolean isInArray(String[] ar, String code) {
if (ar == null) {
return false;
}
for (int i = 0; i < ar.length; ++i) {
if (!code.equalsIgnoreCase(ar[i]))
continue;
return true;
}
return false;
}
/**
* 返回类的源文件位置
* @param baseDir 源文件夹
* @param clazz
*/
public static String getSourceFile(String baseDir,Class> clazz){
if(null == baseDir || null == clazz )return null;
return baseDir + File.separatorChar + clazz.getName().replace('.', File.separatorChar) + ".java";
}
public static Boolean getFillNull(){
return fillNull.get();
}
public static void setFillNull(Boolean fill){
fillNull.set(fill);
}
public static boolean isJsonJacksonRawValue() {
return jsonJacksonRawValue;
}
/**
* @since 3.21.3
*/
public static boolean isJacksonClassDeserializer() {
return jacksonClassDeserializer;
}
/**
* @since 3.21.3
*/
public static boolean isFastjsonClassDeserializer() {
return fastjsonClassDeserializer;
}
public static String getGeometrySerialType() {
return geometrySerialType;
}
/**
* @since 3.31.0
*/
public static String getSuperClassPackage() {
return superClassPackage;
}
/**
* @since 3.31.0
*/
public static Set getSuperClassTablenames() {
return superClassTablenames;
}
/**
* @since 3.31.0
*/
public static Table[] getSuperClassTables() {
if(null == superClassTables) {
synchronized (CodeWriter.class) {
if(null == superClassTables) {
superClassTables = superClassTablenames.stream().map(CodeWriter::getTableFlexible).toArray(Table[]::new);
}
}
}
return superClassTables;
}
/**
* @since 3.31.0
*/
public static String getSamePrefixOfSuperClassTables() {
return samePrefixOfSuperClassTables;
}
private static Table getTableFlexible(String name) {
Table table = db.getTableFlexible(name,getSamePrefixOfSuperClassTables());
checkArgument(null != table,"NOT FOUND Table matched %s",name);
return table;
}
}