use of org.datanucleus.enhancer.asm.ClassWriter in project tests by datanucleus.
the class DynamicEnhanceSchemaToolTest method createClass.
private static byte[] createClass(String className) throws Exception {
ClassWriter cw = new ClassWriter(0);
MethodVisitor mv;
FieldVisitor fv;
String classNameASM = className.replace('.', '/');
// TODO Use getAsmVersionForJRE instead of V1_6 (requires proper stack map)
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, classNameASM, null, "java/lang/Object", new String[] {});
fv = cw.visitField(Opcodes.ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
fv.visitEnd();
// Default Constructor
{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(Opcodes.RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
// String getName()
{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, classNameASM, "name", "Ljava/lang/String;");
mv.visitInsn(Opcodes.ARETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
// void setName(String)
{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setName", "(Ljava/lang/String;)V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitFieldInsn(Opcodes.PUTFIELD, classNameASM, "name", "Ljava/lang/String;");
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitInsn(Opcodes.RETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l2, 0);
mv.visitLocalVariable("s", "Ljava/lang/String;", null, l0, l2, 1);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
// Object getProperty(String)
{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getProperty", "(Ljava/lang/String;)Ljava/lang/Object;", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitInsn(Opcodes.ACONST_NULL);
mv.visitVarInsn(Opcodes.ASTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitLdcInsn("name");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l2 = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, l2);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, classNameASM, "name", "Ljava/lang/String;");
mv.visitVarInsn(Opcodes.ASTORE, 2);
mv.visitLabel(l2);
mv.visitVarInsn(Opcodes.ALOAD, 2);
mv.visitInsn(Opcodes.ARETURN);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l4, 0);
mv.visitLocalVariable("propertyName", "Ljava/lang/String;", null, l0, l4, 1);
mv.visitLocalVariable("o", "Ljava/lang/Object;", null, l1, l4, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
// void setProperty(String, Object)
{
mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "setProperty", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitLdcInsn("name");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false);
Label l1 = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, l1);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 2);
mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/String");
mv.visitFieldInsn(Opcodes.PUTFIELD, classNameASM, "name", "Ljava/lang/String;");
mv.visitLabel(l1);
mv.visitInsn(Opcodes.RETURN);
Label l3 = new Label();
mv.visitLabel(l3);
mv.visitLocalVariable("this", "L" + classNameASM + ";", null, l0, l3, 0);
mv.visitLocalVariable("propertyName", "Ljava/lang/String;", null, l0, l3, 1);
mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, l3, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
return cw.toByteArray();
}
use of org.datanucleus.enhancer.asm.ClassWriter in project datanucleus-core by datanucleus.
the class ClassEnhancerImpl method enhance.
/**
* Method to enhance a classes definition.
* @return Whether it was enhanced with no errors
*/
public boolean enhance() {
if (cmd.getPersistenceModifier() != ClassPersistenceModifier.PERSISTENCE_CAPABLE && cmd.getPersistenceModifier() != ClassPersistenceModifier.PERSISTENCE_AWARE) {
return false;
}
initialise();
if (checkClassIsEnhanced(false)) {
// Already enhanced
DataNucleusEnhancer.LOGGER.info(Localiser.msg("005014", className));
return true;
}
try {
// Check for generation of PK
if (cmd.getIdentityType() == IdentityType.APPLICATION && cmd.getObjectidClass() == null && cmd.getNoOfPrimaryKeyMembers() > 1) {
if (hasOption(OPTION_GENERATE_PK)) {
int[] pkMemberPositions = cmd.getPKMemberPositions();
AbstractMemberMetaData pkMmd0 = cmd.getMetaDataForManagedMemberAtAbsolutePosition(pkMemberPositions[0]);
if (pkMmd0 instanceof PropertyMetaData) {
// Throw exception for invalid metadata
throw new InvalidMetaDataException("044136", cmd.getFullClassName());
}
String pkClassName = cmd.getFullClassName() + AbstractClassMetaData.GENERATED_PK_SUFFIX;
if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005016", cmd.getFullClassName(), pkClassName));
}
cmd.setObjectIdClass(pkClassName);
PrimaryKeyGenerator pkGen = new PrimaryKeyGenerator(cmd, this);
pkClassBytes = pkGen.generate();
} else {
// Throw exception for invalid metadata
throw new InvalidMetaDataException("044065", cmd.getFullClassName(), cmd.getNoOfPrimaryKeyMembers());
}
}
// Create an adapter using a writer
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
EnhancerClassAdapter cv = new EnhancerClassAdapter(cw, this);
ClassReader cr = null;
InputStream classReaderInputStream = null;
try {
// Create a reader for the class and tell it to visit the adapter, performing the changes
if (inputBytes != null) {
cr = new ClassReader(inputBytes);
} else {
classReaderInputStream = clr.getResource(inputResourceName, null).openStream();
cr = new ClassReader(classReaderInputStream);
}
cr.accept(cv, 0);
// Save the bytes
classBytes = cw.toByteArray();
} finally {
if (classReaderInputStream != null) {
classReaderInputStream.close();
}
}
} catch (Exception e) {
DataNucleusEnhancer.LOGGER.error("Error thrown enhancing with ASMClassEnhancer", e);
return false;
}
update = true;
return true;
}
use of org.datanucleus.enhancer.asm.ClassWriter in project datanucleus-core by datanucleus.
the class PrimaryKeyGenerator method generate.
/**
* Method to generate the primary key class.
* @return The bytes for this pk class
*/
public byte[] generate() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
// TODO Parameterise the first argument to allow any JDK
cw.visit(EnhanceUtils.getAsmVersionForJRE(), Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, className_ASM, null, "java/lang/Object", new String[] { "java/io/Serializable" });
// Add fields
addFields(cw);
// Add constructors
addDefaultConstructor(cw);
addStringConstructor(cw);
// Add methods
addMethodToString(cw);
addMethodEquals(cw);
addMethodHashCode(cw);
cw.visitEnd();
return cw.toByteArray();
}
Aggregations