
com.easycodebox.jdbc.res.GenerateBeanRes Maven / Gradle / Ivy
package com.easycodebox.jdbc.res;
import com.easycodebox.common.freemarker.ConfigurationFactory;
import com.easycodebox.common.lang.Strings;
import com.easycodebox.common.lang.Symbol;
import com.easycodebox.common.lang.reflect.Classes;
import com.easycodebox.common.log.slf4j.Logger;
import com.easycodebox.common.log.slf4j.LoggerFactory;
import com.easycodebox.common.validate.Assert;
import com.easycodebox.jdbc.GenerateRes;
import com.easycodebox.jdbc.entity.Entity;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.*;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.asm.ClassReader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* @author WangXiaoJin
*
*/
public class GenerateBeanRes {
private final Logger log = LoggerFactory.getLogger(getClass());
/**
* 要生成资源文件的Bean对象所在的路径
*/
private String[] basePackages;
private String resourcePattern = "**/*.class";
private String template = "bean_resource.ftl";
private String outputFile;
/**
* 生成的R文件package名时,忽略的前缀信息 。设置了packageName参数时则忽略此参数
*/
private String[] ignorePrefixes = {"src/main/java/"};
/**
* 生成的R文件package名 - 设置后则忽略ignorePrefixes参数,因为ignorePrefixes是用来计算packageName使用的
*/
private String packageName;
private TemplateLoader templateLoader;
/**
* 生成资源文件
*/
public void generate() {
Resource[] rs = new Resource[0];
int lastIndex = rs.length;
try {
for(String basePackage : basePackages) {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
basePackage + Symbol.SLASH + resourcePattern;
Resource[] tmp = new PathMatchingResourcePatternResolver()
.getResources(packageSearchPath);
if(tmp.length > 0) {
lastIndex = rs.length;
rs = Arrays.copyOf(rs, rs.length + tmp.length);
System.arraycopy(tmp, 0, rs, lastIndex, tmp.length);
}
}
} catch (IOException e) {
log.error("generate value-object resource error.", e);
}
Writer out = null;
try {
Configuration cfg = ConfigurationFactory.instance(null);
//方法1
/*URL url = GenerateBeanRes.class.getResource("");
File tlFile = new File(url.toURI());
cfg.setDirectoryForTemplateLoading(tlFile);*/
//方法2
/*URL url = GenerateBeanRes.class.getResource("");
cfg.setTemplateLoader(new FileTemplateLoader(new File(url.toURI())));*/
//方法3
cfg.setTemplateLoader(templateLoader == null ? new ClassTemplateLoader(GenerateBeanRes.class, Symbol.EMPTY) : templateLoader);
//设置包装器,并将对象包装为数据模型
Template tpl = cfg.getTemplate(template, "UTF-8");
Map root = new LinkedHashMap<>();
root.put("data", processRes2BeanData(rs));
File outPutFile = new File(outputFile);
if(!outPutFile.getParentFile().exists()) {
outPutFile.getParentFile().mkdirs();
}
//设置R文件的package name
if (Strings.isBlank(packageName)) {
//如果packageName参数为空则自动计算出R文件的packageName
String basePathOfOutput = new File(Symbol.EMPTY).getCanonicalPath();
packageName = outPutFile.getCanonicalPath().replaceFirst("\\Q" + basePathOfOutput + File.separator + "\\E", Symbol.EMPTY);
for (String prefix : ignorePrefixes) {
prefix = FilenameUtils.separatorsToSystem(prefix);
if (packageName.startsWith(prefix)) {
packageName = packageName.substring(prefix.length());
}
}
packageName = FilenameUtils.getPathNoEndSeparator(packageName).replaceAll("[\\\\/]", Symbol.PERIOD);
}
root.put("packageName", packageName);
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outPutFile),"UTF-8"));
if(log.isInfoEnabled()) {
log.info("=== ********* Begin generate template *********** =====");
}
tpl.process(root, out);
if(log.isInfoEnabled()) {
log.info("=== ********* End generate template *********** =====");
}
} catch (IOException | TemplateException e) {
log.error("generate value-object resource error.", e);
} finally {
IOUtils.closeQuietly(out);
}
}
private List processRes2BeanData(Resource[] rs) {
Assert.notEmpty(rs);
List beanDatas = new ArrayList<>(rs.length);
try {
for(int i = 0; i < rs.length; i++) {
Resource r = rs[i];
if(r.isReadable()) {
BeanData data = new BeanData();
ClassReader cr = new ClassReader(r.getInputStream());
String className = cr.getClassName();
Class> clazz = Classes.getClass(className
.replace(Symbol.SLASH, Symbol.PERIOD));
if (clazz.isAnnotation() || clazz.isAnonymousClass() || clazz.isArray() || clazz.isEnum()) {
continue;
}
GenerateRes res = clazz.getAnnotation(GenerateRes.class);
if (res != null && !res.value()) {
continue;
}
List properties = new ArrayList<>();
data.setClazz(clazz.getName() + ".class");
data.setClassName(clazz.getSimpleName());
if(Classes.isAssignable(clazz, Entity.class))
data.setEntity(true);
else
data.setEntity(false);
for(Class> curClazz = clazz;
curClazz != null && curClazz != Object.class;
curClazz = curClazz.getSuperclass()) {
Field[] fields = curClazz.getDeclaredFields();
for(Field f : fields) {
if(Modifier.isFinal(f.getModifiers())
|| Modifier.isStatic(f.getModifiers()))
continue;
properties.add(f.getName());
}
}
if (properties.size() == 0) {
continue;
}
data.setProperties(properties);
if(log.isInfoEnabled()) {
log.info("==== Add {0} class to resources.", clazz);
}
beanDatas.add(data);
}
}
} catch (IOException | ClassNotFoundException e) {
log.error("generate value-object resource error.", e);
}
return beanDatas;
}
public class BeanData {
private String clazz;
private String className;
private boolean entity;
private List properties;
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public boolean isEntity() {
return entity;
}
public void setEntity(boolean entity) {
this.entity = entity;
}
public List getProperties() {
return properties;
}
public void setProperties(List properties) {
this.properties = properties;
}
}
public String[] getBasePackages() {
return basePackages;
}
public void setBasePackages(String[] basePackages) {
this.basePackages = basePackages;
}
public String getResourcePattern() {
return resourcePattern;
}
public void setResourcePattern(String resourcePattern) {
this.resourcePattern = resourcePattern;
}
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
public String getOutputFile() {
return outputFile;
}
public void setOutputFile(String outputFile) {
this.outputFile = outputFile;
}
public String[] getIgnorePrefixes() {
return ignorePrefixes;
}
public void setIgnorePrefixes(String[] ignorePrefixes) {
this.ignorePrefixes = ignorePrefixes;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public TemplateLoader getTemplateLoader() {
return templateLoader;
}
public void setTemplateLoader(TemplateLoader templateLoader) {
this.templateLoader = templateLoader;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy