package jef.codegen; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.net.URL; import java.util.Date; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import jef.accelerator.asm.Attribute; import jef.accelerator.asm.ClassReader; import jef.accelerator.asm.ClassVisitor; import jef.accelerator.asm.ClassWriter; import jef.accelerator.asm.Opcodes; import jef.database.DataObject; import jef.database.VarObject; import jef.database.dialect.ColumnType; import jef.database.meta.MetaHolder; import jef.database.meta.TupleMetadata; import jef.json.JsonUtil; import jef.orm.onetable.model.TestEntity; import jef.tools.DateFormats; import jef.tools.IOUtils; import jef.tools.reflect.BeanWrapper; import jef.tools.string.RandomData; import org.junit.Test; public class EntityEnhancerTest { @Test public void testEntityEnhancer() { EntityEnhancer e = new EntityEnhancer(); e.setOut(System.out); e.setRoot(new File("./")); e.setExcludePatter(new String[] { "java.lang.*" }); e.setIncludePattern("javax.xml"); e.getExcludePatter(); e.getIncludePattern(); e.enhance("jef"); } @Test public void testEnhanceTask() throws Exception { EnhanceTaskASM asm = new EnhanceTaskASM(); ClassReader reader = new ClassReader("jef.orm.multitable.model.Person"); URL url=ClassLoader.getSystemResource("jef.orm.multitable.model.Person$Field".replace('.', '/') + ".class"); ClassWriter writer = new ClassWriter(0); reader.accept(new ClassVisitor(Opcodes.ASM5,writer){ @Override public void visitAttribute(Attribute attr) { if(!"jefd".equals(attr.type)){ super.visitAttribute(attr); } } }, 0); byte[] bytes=asm.doEnhance( writer.toByteArray(),IOUtils.toByteArray(url)); assertNotNull(bytes); byte[] bytes2=asm.doEnhance(bytes,IOUtils.toByteArray(url)); assertTrue(bytes2.length==0); } @Test public void testWrapperSettingPrimitiveNull(){ BeanWrapper bw=BeanWrapper.wrap(new FieldParent()); bw.setPropertyValue("id", 1); bw.setPropertyValue("id", null); } /** * 1 可以增强内部类 * * 增强操作队显示为对一切IQuerableEnrity生效,但对任意类来说,都只按Field中的枚举来增强属性。(可以吗?) * * * * * * 现在支持,父子类之间继承field属性。 * 2 有Field的子类 (OK) * 3 无Field的子类 (OK) * * 4 父类没有Field,子类有全部的Field * 4 父类没有Field,子类有部分的Field (结果:仅在子类中属性得到了增强,父类的属性未增强:解决办法是在父类中也将该字段定义为Field. * 考虑制作功能用于增强父类,但是—— * a 父类可能在JAR包中,不能直接修改。 * b 如果在子类中通过覆盖方法来实现,也有问题,因为ASM中去解析父类并查找同名方法较为复杂。在增强前,不能调用类实现反射,因此相当于要自行用ASM实现父子类解析的JAVA逻辑,太麻烦了…… * * 办法,在增强子类时,查找哪些子类中定义了元模型,但并未定义的属性,然后到父类中去找,直到找到其getter setter方法,再然后编写一个增强的方法覆盖父类方法…… * 用CG lib倒是可以很方便的实现,但是用ASM就悲剧了。 * 此外,如果父类本身也定义了该元模型,子类覆盖父类元模型,此时也很悲剧——延迟加载和等植入代码将被执行两遍,子类一遍父类一遍…… * * 因此,我们还是要尽可能避免这种父类定义属性,子类定义元模型的方式。 * * * ) */ @Test public void testInnerClass()throws Exception { System.out.println(MetaHolder.getMeta(NoFieldParent.class)); System.out.println(MetaHolder.getMeta(ExtendsNoFIeldClass.class)); //此处如果仅输出一个列,是不对的 System.out.println(MetaHolder.getMeta(FieldParent.class)); System.out.println(MetaHolder.getMeta(OverrideParent.class)); System.out.println(MetaHolder.getMeta(NoFIeldChild.class)); System.out.println(MetaHolder.getMeta(Ts.class)); } public static class NoFieldParent extends DataObject{ private int noFid; private String noFname; public int getNoFid() { return noFid; } public void setNoFid(int noFid) { this.noFid = noFid; } public String getNoFname() { return noFname; } public void setNoFname(String noFname) { this.noFname = noFname; } public enum Field implements jef.database.Field{ noFid } } public static class FieldParent extends DataObject{ private int id; private String name; private Date date; private String notDefine; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getNotDefine() { return notDefine; } public void setNotDefine(String notDefine) { this.notDefine = notDefine; } public enum Field implements jef.database.Field{ id,name,date,notDefine } } /** * 将父类中的属性(非列)定义为数据库列 * 父类无列,子类有列 * @author jiyi * */ public static class ExtendsNoFIeldClass extends NoFieldParent{ private String desc; private String noFname; public String getNoFname() { return noFname; } public void setNoFname(String noFname) { this.noFname = noFname; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public enum Field implements jef.database.Field{ noFid,noFname,desc } } /** * 父类有列,子类无列 * @author jiyi * */ public static class NoFIeldChild extends FieldParent{ private String ext; @OneToOne @JoinColumn(name="id",referencedColumnName="noFid") private ExtendsNoFIeldClass extend; public ExtendsNoFIeldClass getExtend() { return extend; } public void setExtend(ExtendsNoFIeldClass extend) { this.extend = extend; } public String getExt() { return ext; } public void setExt(String ext) { this.ext = ext; } } public static class OverrideParent extends FieldParent{ private String comment; public enum Field implements jef.database.Field{ comment,notDefine } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } } /** * 测试动态Entity和静态Entity的 bean被序列化时的表现 */ @Test public void testDataObjectAsJson(){ TestEntity t1=RandomData.newInstance(TestEntity.class); t1.prepareUpdate(TestEntity.Field.boolField, "false"); t1.setBinaryData(null); t1.setTt1(null); t1.setTt2(null); t1.setTt3(null); String s=JsonUtil.toJson(t1, DateFormats.DATE_TIME_CS.get()); System.out.println(s); TupleMetadata GroupTable = new TupleMetadata("URM_GROUP"); GroupTable.addColumn("id", new ColumnType.AutoIncrement(8)); GroupTable.addColumn("serviceId", new ColumnType.Int(8)); GroupTable.addColumn("name", new ColumnType.Varchar(100)); VarObject var=new VarObject(GroupTable); var.set("id", 123); var.set("serviceId",456); var.set("name","addfvdf"); s=JsonUtil.toJson(var, DateFormats.DATE_TIME_CS.get()); System.out.println(s); } @Test public void test123(){ EntityEnhancer e=new EntityEnhancer(); e.enhance("com.hikvision"); } }