Search in sources :

Example 1 with ClassWriter

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();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) FieldVisitor(org.datanucleus.enhancer.asm.FieldVisitor) ClassWriter(org.datanucleus.enhancer.asm.ClassWriter) MethodVisitor(org.datanucleus.enhancer.asm.MethodVisitor)

Example 2 with ClassWriter

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;
}
Also used : InvalidMetaDataException(org.datanucleus.metadata.InvalidMetaDataException) EnhancerClassAdapter(org.datanucleus.enhancer.EnhancerClassAdapter) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ClassReader(org.datanucleus.enhancer.asm.ClassReader) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) ClassWriter(org.datanucleus.enhancer.asm.ClassWriter) InvalidMetaDataException(org.datanucleus.metadata.InvalidMetaDataException) IOException(java.io.IOException)

Example 3 with ClassWriter

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();
}
Also used : ClassWriter(org.datanucleus.enhancer.asm.ClassWriter)

Aggregations

ClassWriter (org.datanucleus.enhancer.asm.ClassWriter)3 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 EnhancerClassAdapter (org.datanucleus.enhancer.EnhancerClassAdapter)1 ClassReader (org.datanucleus.enhancer.asm.ClassReader)1 FieldVisitor (org.datanucleus.enhancer.asm.FieldVisitor)1 Label (org.datanucleus.enhancer.asm.Label)1 MethodVisitor (org.datanucleus.enhancer.asm.MethodVisitor)1 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)1 InvalidMetaDataException (org.datanucleus.metadata.InvalidMetaDataException)1 PropertyMetaData (org.datanucleus.metadata.PropertyMetaData)1