package org.eweb4j.orm.config;
import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.eweb4j.cache.ORMConfigBeanCache;
import org.eweb4j.config.LogFactory;
import org.eweb4j.orm.PropType;
import org.eweb4j.orm.annotation.Ignore;
import org.eweb4j.orm.config.bean.ORMConfigBean;
import org.eweb4j.orm.config.bean.Property;
import org.eweb4j.util.ClassUtil;
import org.eweb4j.util.FileUtil;
import org.eweb4j.util.ReflectUtil;
/**
* Persistent obj annotation read to cache
*
* @author weiwei
*
*/
public class PojoAnnotationConfig {
/**
* 读取注解,并存入配置缓存中
*
* @param scanPackage
* @return
*/
public static String readAnnotation(List<String> scanPackages) {
String error = null;
if (scanPackages == null)
return null;
for (String scanPackage : scanPackages) {
if (scanPackage == null || scanPackage.length() == 0)
continue;
String classDir = FileUtil
.getTopClassPath(PojoAnnotationConfig.class);
scanDir(scanPackage, classDir);
String classDir2 = FileUtil.getClassPath("classes");
scanDir(scanPackage, classDir2);
// 扫描jar包
String jarPath = FileUtil.getJarPath();
try {
scanPackage(jarPath, scanPackage);
} catch (Error e) {
continue;
} catch (Exception e) {
continue;
}
}
return error;
}
private static void scanDir(String scanPackage, String classDir) {
File dir = null;
if (".".equals(scanPackage)) {
scanPackage = "";
dir = new File(classDir);
} else
dir = new File(classDir + File.separator
+ scanPackage.replace(".", File.separator));
if (dir.isDirectory())
scanPackage(dir, scanPackage);
}
/**
* 扫描包目录下的所有文件
*
* @param dir
* @param actionPackage
* @throws Exception
*/
private static void scanPackage(File dir, String actionPackage) {
if (!dir.isDirectory())
return;
LogFactory.getORMLogger("INFO").write("scan " + dir);
File[] files = dir.listFiles();
if (files == null || files.length == 0)
return;
for (File file : files) {
// 递归
if (file.isDirectory()) {
if (actionPackage.length() == 0)
scanPackage(file, file.getName());
else
scanPackage(file, actionPackage + "." + file.getName());
} else if (file.isFile()) {
String fname = file.getName();
if (!fname.endsWith(".class"))
continue;
String clsName = actionPackage + "."
+ fname.substring(0, fname.lastIndexOf("."));
if (clsName == null || "".equals(clsName))
continue;
try {
handlePojoClass(clsName);
} catch (Exception e) {
}
}
}
}
/**
* scan package by jars
*
* @param jarsParentDirPath
* @param packageName
* @throws Exception
*/
public static void scanPackage(String jarsParentDirPath, String packageName) {
String path = jarsParentDirPath;
LogFactory.getORMLogger("INFO").write("scan " + path + " for jars");
File[] ff = new File(path).listFiles();
if (ff == null)
return;
for (File f : ff) {
ZipInputStream zin = null;
ZipEntry entry = null;
try {
zin = new ZipInputStream(new FileInputStream(f));
entry = zin.getNextEntry();
} catch (Error e) {
continue;
} catch (Exception e) {
continue;
}
while (entry != null) {
try {
entry = zin.getNextEntry();
String entryName = entry.getName().replace('/', '.');
if (".".equals(packageName)
|| entryName.startsWith(packageName))
handlePojoClass(entryName.replace(".class", ""));
zin.closeEntry();
} catch (Error e) {
continue;
} catch (Exception e) {
continue;
}
}
try {
zin.close();
} catch (Error e) {
continue;
} catch (Exception e) {
continue;
}
}
}
/**
*
* @param clsName
* @throws Exception
*/
public static void handlePojoClass(String clsName) {
Class<?> clazz = null;
ReflectUtil ru;
try {
clazz = Class.forName(clsName);
} catch (Error e) {
return;
} catch (Exception e) {
return;
}
if (clazz == null)
return;
Entity entity = clazz.getAnnotation(Entity.class);
if (entity == null && !clsName.endsWith("PO")
&& !clsName.endsWith("POJO") && !clsName.endsWith("Entity")
&& !clsName.endsWith("Model")) {
return;
}
Table tableAnn = clazz.getAnnotation(Table.class);
String table = tableAnn == null ? "" : tableAnn.name();
table = "".equals(table.trim()) ? clazz.getSimpleName()
.replace("PO", "").replace("POJO", "").replace("Entity", "")
.replace("Model", "") : table;
ORMConfigBean ormBean = new ORMConfigBean();
ormBean.setClazz(clazz.getName());
ormBean.setId(clazz.getSimpleName());
ormBean.setTable(table);
try {
ru = new ReflectUtil(clazz);
} catch (Error e) {
return;
} catch (Exception e) {
return;
}
List<Property> pList = new ArrayList<Property>();
for (Field f : ru.getFields()) {
String name = f.getName();
Method getter = ru.getGetter(name);
if (getter == null)
continue;
Ignore igAnn = f.getAnnotation(Ignore.class);
if (igAnn != null)
continue;
OneToMany manyAnn = getter.getAnnotation(OneToMany.class);
if (manyAnn != null)
continue;
else {
manyAnn = f.getAnnotation(OneToMany.class);
if (manyAnn != null)
continue;
}
ManyToMany mmAnn = getter.getAnnotation(ManyToMany.class);
if (mmAnn != null)
continue;
else {
mmAnn = f.getAnnotation(ManyToMany.class);
if (mmAnn != null)
continue;
}
Property p = new Property();
Id idAnn = getter.getAnnotation(Id.class);
if (idAnn == null)
idAnn = f.getAnnotation(Id.class);
if (idAnn != null) {
p.setAutoIncrement("1");
p.setPk("1");
}
Column colAnn = getter.getAnnotation(Column.class);
if (colAnn == null) {
colAnn = f.getAnnotation(Column.class);
}
String column = colAnn == null ? "" : colAnn.name();
column = "".equals(column.trim()) ? name : column;
p.setName(name);
p.setColumn(column);
p.setType(f.getType().getName());
if (ClassUtil.isPojo(f.getType())) {
OneToOne oneAnn = getter.getAnnotation(OneToOne.class);
if (oneAnn == null) {
oneAnn = f.getAnnotation(OneToOne.class);
}
if (oneAnn != null) {
p.setType(PropType.ONE);
p.setColumn(oneAnn.mappedBy());
}
}
pList.add(p);
}
ormBean.setProperty(pList);
ORMConfigBeanCache.add(clazz, ormBean);
}
}