
com.github.obase.mysql.asm.AsmKit Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of obase-mysql Show documentation
Show all versions of obase-mysql Show documentation
A very simple/efficient Mysql Client Framework
The newest version!
package com.github.obase.mysql.asm;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.asm.ClassReader;
import org.springframework.asm.Type;
import org.springframework.core.io.Resource;
import com.github.obase.MessageException;
import com.github.obase.kit.ClassKit;
import com.github.obase.kit.StringKit;
import com.github.obase.mysql.JdbcMeta;
import com.github.obase.mysql.MysqlErrno;
import com.github.obase.mysql.annotation.Column;
import com.github.obase.mysql.annotation.ForeignKey;
import com.github.obase.mysql.annotation.Indexes;
import com.github.obase.mysql.annotation.Meta;
import com.github.obase.mysql.annotation.OptimisticLock;
import com.github.obase.mysql.annotation.PrimaryKey;
import com.github.obase.mysql.annotation.Table;
import com.github.obase.mysql.data.ClassMetaInfo;
import com.github.obase.mysql.data.FieldMetaInfo;
import com.github.obase.mysql.data.MethodMetaInfo;
public final class AsmKit {
static final String JdbcMetaSuffix = "__JdbcMeta";
static final String Object_INTERNAL_NAME = Type.getInternalName(Object.class);
static final String SqlAction_INTERNAL_NAME = Type.getInternalName(JdbcMeta.class);
static final String GETTER_METHOD_PREFIX = "get";
static final String SETTER_METHOD_PREFIX = "set";
static final String TABLE_ANNOTATION_DESC = Type.getDescriptor(Table.class);
static final String META_ANNOTATION_DESC = Type.getDescriptor(Meta.class);
static final String PRIMARY_KEY_ANNOTATION_DESC = Type.getDescriptor(PrimaryKey.class);
static final String FOREIGN_KEY_ANNOTATION_DESC = Type.getDescriptor(ForeignKey.class);
static final String INDEXES_KEY_ANNOTATION_DESC = Type.getDescriptor(Indexes.class);
static final String COLUMN_ANNOTATION_DESC = Type.getDescriptor(Column.class);
static final String OPTIMISTIC_LOCK_ANNOTATION_DESC = Type.getDescriptor(OptimisticLock.class);
static final int CLASS_READER_ACCEPT_FLAGS = ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES;
public static JdbcMeta newJdbcMeta(ClassMetaInfo classMetaInfo) throws IOException, ReflectiveOperationException {
String internalName = classMetaInfo.internalName + JdbcMetaSuffix;
String className = ClassKit.getClassNameFromInternalName(internalName);
Class> c = null;
try {
c = ClassKit.loadClass(className);
} catch (ClassNotFoundException e) {
byte[] data = JdbcMetaClassWriter.dump(internalName, classMetaInfo);
synchronized (AsmKit.class) {
try {
c = ClassKit.loadClass(className);
} catch (ClassNotFoundException e2) {
c = ClassKit.defineClass(className, data);
}
}
}
return (JdbcMeta) c.newInstance();
}
public static JdbcMeta newJdbcMeta(String targetClassName) throws IOException, ReflectiveOperationException {
String className = targetClassName + JdbcMetaSuffix;
Class> c = null;
try {
c = ClassKit.loadClass(className);
} catch (ClassNotFoundException e) {
ClassMetaInfo classMetaInfo = getClassMetaInfo(targetClassName);
String internalName = ClassKit.getInternalNameFromClassName(className);
byte[] data = JdbcMetaClassWriter.dump(internalName, classMetaInfo);
synchronized (AsmKit.class) {
try {
c = ClassKit.loadClass(className);
} catch (ClassNotFoundException e2) {
c = ClassKit.defineClass(className, data);
}
}
}
return (JdbcMeta) c.newInstance();
}
public static ClassMetaInfo getAnnotationClassMetaInfo(Resource rs) throws IOException {
ClassReader cr = null;
InputStream is = null;
try {
is = rs.getInputStream();
cr = new ClassReader(is);
} finally {
if (is != null) {
is.close();
}
}
ClassMetaInfo result = new ClassMetaInfo();
cr.accept(new AnnotationMetaInfoClassVisitor(result), CLASS_READER_ACCEPT_FLAGS);
return postProcessClassMetaInfo(result);
}
public static ClassMetaInfo getAnnotationClassMetaInfo(String className) throws IOException {
ClassReader cr = new ClassReader(className);
ClassMetaInfo result = new ClassMetaInfo();
cr.accept(new AnnotationMetaInfoClassVisitor(result), CLASS_READER_ACCEPT_FLAGS);
return postProcessClassMetaInfo(result);
}
public static ClassMetaInfo getClassMetaInfo(String className) throws IOException {
ClassReader cr = new ClassReader(ClassKit.getResourceAsStream(ClassKit.getClassPathFromClassName(className)));
ClassMetaInfo result = new ClassMetaInfo();
cr.accept(new MetaInfoClassVisitor(result), CLASS_READER_ACCEPT_FLAGS);
return postProcessClassMetaInfo(result);
}
static ClassMetaInfo postProcessClassMetaInfo(ClassMetaInfo classMetaInfo) {
if (classMetaInfo.tableAnnotation != null) {
gatherTableMetaData(classMetaInfo);
if (classMetaInfo.keys == null || classMetaInfo.keys.size() == 0) {
throw new MessageException(MysqlErrno.SOURCE, MysqlErrno.META_INFO_EXT_FAILED, "Undefine primary key for table:" + classMetaInfo.internalName);
}
}
changeGetterOrSetterToColumnName(classMetaInfo.getters, classMetaInfo.fields);
changeGetterOrSetterToColumnName(classMetaInfo.setters, classMetaInfo.fields);
return classMetaInfo;
}
static final int CAP_DIF = ('A' - 'a');
static void changeGetterOrSetterToColumnName(Map methods, Map fields) {
String name = null;
FieldMetaInfo field = null;
StringBuilder sb = new StringBuilder(128);
Set keys = new HashSet(methods.keySet());
for (String method : keys) {
sb.setLength(0);
sb.append(method).delete(0, 3).setCharAt(0, (char) (sb.charAt(0) - CAP_DIF));
name = sb.toString();
field = fields.get(name);
if (field != null && field.columnAnnotation != null && StringKit.isNotEmpty(field.columnAnnotation.name)) {
name = field.columnAnnotation.name;
}
methods.put(name, methods.remove(method));
}
}
static final Comparator FieldMetaInfoComparator = new Comparator() {
@Override
public int compare(FieldMetaInfo o1, FieldMetaInfo o2) {
if (o1.order > o2.order) {
return -1;
} else if (o1.order < o2.order) {
return 1;
} else {
return 0;
}
}
};
static void gatherTableMetaData(ClassMetaInfo classMetaInfo) {
String tableName = null;
if (classMetaInfo.tableAnnotation != null) {
tableName = classMetaInfo.tableAnnotation.name;
if (StringKit.isEmpty(tableName)) {
int pos = classMetaInfo.internalName.lastIndexOf('/');
tableName = (pos != -1) ? classMetaInfo.internalName.substring(pos + 1) : classMetaInfo.internalName;
}
}
classMetaInfo.tableName = tableName;
List fields = new LinkedList(classMetaInfo.fields.values());
Collections.sort(fields, FieldMetaInfoComparator);
classMetaInfo.fields.clear();
for (FieldMetaInfo field : fields) {
classMetaInfo.fields.put(field.name, field);
}
List keys = new LinkedList();
List cols = new LinkedList();
for (FieldMetaInfo field : fields) {
if (field.columnAnnotation != null) {
String name = field.columnAnnotation.name;
if (StringKit.isEmpty(name)) {
name = field.name;
}
cols.add(name);
if (Boolean.TRUE.equals(field.columnAnnotation.key)) {
keys.add(name);
}
}
}
if (classMetaInfo.primaryKeyAnnotation != null) {
keys.clear();
keys.addAll(classMetaInfo.primaryKeyAnnotation.columns);
}
classMetaInfo.keys = keys;
classMetaInfo.columns = cols;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy