⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fieldtransformer.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.hibernate.bytecode.javassist;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.Iterator;import java.util.List;import javassist.CannotCompileException;import javassist.bytecode.AccessFlag;import javassist.bytecode.BadBytecode;import javassist.bytecode.Bytecode;import javassist.bytecode.ClassFile;import javassist.bytecode.CodeAttribute;import javassist.bytecode.CodeIterator;import javassist.bytecode.ConstPool;import javassist.bytecode.Descriptor;import javassist.bytecode.FieldInfo;import javassist.bytecode.MethodInfo;import javassist.bytecode.Opcode;/** * The thing that handles actual class enhancement in regards to * intercepting field accesses. * * @author Muga Nishizawa * @author Steve Ebersole */public class FieldTransformer {	private static final String EACH_READ_METHOD_PREFIX = "$javassist_read_";	private static final String EACH_WRITE_METHOD_PREFIX = "$javassist_write_";	private static final String FIELD_HANDLED_TYPE_NAME = FieldHandled.class			.getName();	private static final String HANDLER_FIELD_NAME = "$JAVASSIST_READ_WRITE_HANDLER";	private static final String FIELD_HANDLER_TYPE_NAME = FieldHandler.class			.getName();	private static final String HANDLER_FIELD_DESCRIPTOR = 'L' + FIELD_HANDLER_TYPE_NAME			.replace('.', '/') + ';';	private static final String GETFIELDHANDLER_METHOD_NAME = "getFieldHandler";	private static final String SETFIELDHANDLER_METHOD_NAME = "setFieldHandler";	private static final String GETFIELDHANDLER_METHOD_DESCRIPTOR = "()"	                                                                + HANDLER_FIELD_DESCRIPTOR;	private static final String SETFIELDHANDLER_METHOD_DESCRIPTOR = "("	                                                                + HANDLER_FIELD_DESCRIPTOR + ")V";	private FieldFilter filter;	public FieldTransformer() {		this(null);	}	public FieldTransformer(FieldFilter f) {		filter = f;	}	public void setFieldFilter(FieldFilter f) {		filter = f;	}	public void transform(File file) throws Exception {		DataInputStream in = new DataInputStream(new FileInputStream(file));		ClassFile classfile = new ClassFile(in);		transform(classfile);		DataOutputStream out = new DataOutputStream(new FileOutputStream(file));		try {			classfile.write(out);		} finally {			out.close();		}	}	public void transform(ClassFile classfile) throws Exception {		if (classfile.isInterface()) {			return;		}		try {			addFieldHandlerField(classfile);			addGetFieldHandlerMethod(classfile);			addSetFieldHandlerMethod(classfile);			addFieldHandledInterface(classfile);			addReadWriteMethods(classfile);			transformInvokevirtualsIntoPutAndGetfields(classfile);		} catch (CannotCompileException e) {			throw new RuntimeException(e.getMessage(), e);		}	}	private void addFieldHandlerField(ClassFile classfile)			throws CannotCompileException {		ConstPool cp = classfile.getConstPool();		FieldInfo finfo = new FieldInfo(cp, HANDLER_FIELD_NAME,		                                HANDLER_FIELD_DESCRIPTOR);		finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.TRANSIENT);		classfile.addField(finfo);	}	private void addGetFieldHandlerMethod(ClassFile classfile)			throws CannotCompileException {		ConstPool cp = classfile.getConstPool();		int this_class_index = cp.getThisClassInfo();		MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME,		                                  GETFIELDHANDLER_METHOD_DESCRIPTOR);		/* local variable | this | */		Bytecode code = new Bytecode(cp, 2, 1);		// aload_0 // load this		code.addAload(0);		// getfield // get field "$JAVASSIST_CALLBACK" defined already		code.addOpcode(Opcode.GETFIELD);		int field_index = cp.addFieldrefInfo(this_class_index,		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);		code.addIndex(field_index);		// areturn // return the value of the field		code.addOpcode(Opcode.ARETURN);		minfo.setCodeAttribute(code.toCodeAttribute());		minfo.setAccessFlags(AccessFlag.PUBLIC);		classfile.addMethod(minfo);	}	private void addSetFieldHandlerMethod(ClassFile classfile)			throws CannotCompileException {		ConstPool cp = classfile.getConstPool();		int this_class_index = cp.getThisClassInfo();		MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME,		                                  SETFIELDHANDLER_METHOD_DESCRIPTOR);		/* local variables | this | callback | */		Bytecode code = new Bytecode(cp, 3, 3);		// aload_0 // load this		code.addAload(0);		// aload_1 // load callback		code.addAload(1);		// putfield // put field "$JAVASSIST_CALLBACK" defined already		code.addOpcode(Opcode.PUTFIELD);		int field_index = cp.addFieldrefInfo(this_class_index,		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);		code.addIndex(field_index);		// return		code.addOpcode(Opcode.RETURN);		minfo.setCodeAttribute(code.toCodeAttribute());		minfo.setAccessFlags(AccessFlag.PUBLIC);		classfile.addMethod(minfo);	}	private void addFieldHandledInterface(ClassFile classfile) {		String[] interfaceNames = classfile.getInterfaces();		String[] newInterfaceNames = new String[interfaceNames.length + 1];		System.arraycopy(interfaceNames, 0, newInterfaceNames, 0,		                 interfaceNames.length);		newInterfaceNames[newInterfaceNames.length - 1] = FIELD_HANDLED_TYPE_NAME;		classfile.setInterfaces(newInterfaceNames);	}	private void addReadWriteMethods(ClassFile classfile)			throws CannotCompileException {		List fields = classfile.getFields();		for (Iterator field_iter = fields.iterator(); field_iter.hasNext();) {			FieldInfo finfo = (FieldInfo) field_iter.next();			if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0			    && (!finfo.getName().equals(HANDLER_FIELD_NAME))) {				// case of non-static field				if (filter.handleRead(finfo.getDescriptor(), finfo						.getName())) {					addReadMethod(classfile, finfo);				}				if (filter.handleWrite(finfo.getDescriptor(), finfo						.getName())) {					addWriteMethod(classfile, finfo);				}			}		}	}	private void addReadMethod(ClassFile classfile, FieldInfo finfo)			throws CannotCompileException {		ConstPool cp = classfile.getConstPool();		int this_class_index = cp.getThisClassInfo();		String desc = "()" + finfo.getDescriptor();		MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX		                                      + finfo.getName(), desc);		/* local variables | target obj | each oldvalue | */		Bytecode code = new Bytecode(cp, 5, 3);		// aload_0		code.addAload(0);		// getfield // get each field		code.addOpcode(Opcode.GETFIELD);		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo				.getName(), finfo.getDescriptor());		code.addIndex(base_field_index);		// aload_0		code.addAload(0);		// invokeinterface // invoke Enabled.getInterceptFieldCallback()		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);		code.addInvokeinterface(enabled_class_index,		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,		                        1);		// ifnonnull		code.addOpcode(Opcode.IFNONNULL);		code.addIndex(4);		// *return // each type		addTypeDependDataReturn(code, finfo.getDescriptor());		// *store_1 // each type		addTypeDependDataStore(code, finfo.getDescriptor(), 1);		// aload_0		code.addAload(0);		// invokeinterface // invoke Enabled.getInterceptFieldCallback()		code.addInvokeinterface(enabled_class_index,		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,		                        1);		// aload_0		code.addAload(0);		// ldc // name of the field		code.addLdc(finfo.getName());		// *load_1 // each type		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);		// invokeinterface // invoke Callback.read*() // each type		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),		                            true);		// *return // each type		addTypeDependDataReturn(code, finfo.getDescriptor());		minfo.setCodeAttribute(code.toCodeAttribute());		minfo.setAccessFlags(AccessFlag.PUBLIC);		classfile.addMethod(minfo);	}	private void addWriteMethod(ClassFile classfile, FieldInfo finfo)			throws CannotCompileException {		ConstPool cp = classfile.getConstPool();		int this_class_index = cp.getThisClassInfo();		String desc = "(" + finfo.getDescriptor() + ")V";		MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX		                                      + finfo.getName(), desc);		/* local variables | target obj | each oldvalue | */		Bytecode code = new Bytecode(cp, 6, 3);		// aload_0		code.addAload(0);		// invokeinterface // enabled.getInterceptFieldCallback()		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);		code.addInvokeinterface(enabled_class_index,		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,		                        1);		// ifnonnull (label1)		code.addOpcode(Opcode.IFNONNULL);		code.addIndex(9);		// aload_0		code.addAload(0);		// *load_1		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);		// putfield		code.addOpcode(Opcode.PUTFIELD);		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo				.getName(), finfo.getDescriptor());		code.addIndex(base_field_index);		code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));		// return ;		code.addOpcode(Opcode.RETURN);		// aload_0		code.addAload(0);		// dup		code.addOpcode(Opcode.DUP);		// invokeinterface // enabled.getInterceptFieldCallback()		code.addInvokeinterface(enabled_class_index,		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,		                        1);		// aload_0		code.addAload(0);		// ldc // field name		code.addLdc(finfo.getName());		// aload_0		code.addAload(0);		// getfield // old value of the field		code.addOpcode(Opcode.GETFIELD);		code.addIndex(base_field_index);		code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);		// *load_1		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);		// invokeinterface // callback.write*(..)		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),		                            false);		// putfield // new value of the field

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -