Search in sources :

Example 1 with MethodInsnNode

use of org.apache.xbean.asm5.tree.MethodInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addHashCodeMethod.

/**
 * This will add a hashCode method for class being generated. <br>
 * Algorithm is as follows: <br>
 * <i><p>
 * int hashCode = 7;
 * for (field: all fields) {
 * hashCode = 23 * hashCode + field.hashCode()
 * }
 * </p></i>
 * <br>
 * <b> For primitive field, hashcode implemenented is similar to the one present in its wrapper class. </b>
 *
 * @param classNode
 * @param fieldList
 * @throws JSONException
 */
@SuppressWarnings("unchecked")
private static void addHashCodeMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
    MethodNode hashCodeNode = new MethodNode(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
    hashCodeNode.visitAnnotation("Ljava/lang/Override;", true);
    hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 7));
    hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
    for (TupleSchemaRegistry.SQLFieldInfo fieldInfo : fieldList) {
        String fieldName = fieldInfo.getColumnName();
        String fieldType = fieldInfo.getType().getJavaType().getName();
        String fieldJavaType = getJavaType(fieldType);
        hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 23));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
        hashCodeNode.instructions.add(new InsnNode(Opcodes.IMUL));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
        switch(fieldType) {
            case "boolean":
                LabelNode falseNode = new LabelNode();
                LabelNode trueNode = new LabelNode();
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFEQ, falseNode));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1231));
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, trueNode));
                hashCodeNode.instructions.add(falseNode);
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1237));
                hashCodeNode.instructions.add(trueNode);
                break;
            case "byte":
            case "char":
            case "short":
            case "int":
                break;
            case "float":
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "floatToIntBits", "(F)I", false));
                break;
            case "long":
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
                hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
                break;
            case "double":
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "doubleToLongBits", "(D)J", false));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.DUP2));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LSTORE, 2));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LLOAD, 2));
                hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
                hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
                break;
            default:
                String objectOwnerType = fieldType.replace('.', '/');
                LabelNode nullNode = new LabelNode();
                LabelNode continueNode = new LabelNode();
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFNULL, nullNode));
                hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
                hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
                hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, objectOwnerType, "hashCode", "()I", false));
                hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, continueNode));
                hashCodeNode.instructions.add(nullNode);
                hashCodeNode.instructions.add(new InsnNode(Opcodes.ICONST_0));
                hashCodeNode.instructions.add(continueNode);
                break;
        }
        hashCodeNode.instructions.add(new InsnNode(Opcodes.IADD));
        hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
    }
    hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
    hashCodeNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    classNode.methods.add(hashCodeNode);
}
Also used : LabelNode(org.apache.xbean.asm5.tree.LabelNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) TupleSchemaRegistry(org.apache.apex.malhar.sql.schema.TupleSchemaRegistry) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Example 2 with MethodInsnNode

use of org.apache.xbean.asm5.tree.MethodInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addToStringMethod.

/**
 * Adds a toString method to underlying class. Uses StringBuilder to generate the final string.
 *
 * @param classNode
 * @param fieldList
 * @throws JSONException
 */
@SuppressWarnings("unchecked")
private static void addToStringMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
    MethodNode toStringNode = new MethodNode(Opcodes.ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
    toStringNode.visitAnnotation("Ljava/lang/Override;", true);
    toStringNode.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/StringBuilder"));
    toStringNode.instructions.add(new InsnNode(Opcodes.DUP));
    toStringNode.instructions.add(new LdcInsnNode(classNode.name + "{"));
    toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false));
    toStringNode.instructions.add(new VarInsnNode(Opcodes.ASTORE, 1));
    toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    for (int i = 0; i < fieldList.size(); i++) {
        TupleSchemaRegistry.SQLFieldInfo info = fieldList.get(i);
        String fieldName = info.getColumnName();
        String fieldType = info.getType().getJavaType().getName();
        String fieldJavaType = getJavaType(fieldType);
        if (i != 0) {
            toStringNode.instructions.add(new LdcInsnNode(", "));
            toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
        }
        toStringNode.instructions.add(new LdcInsnNode(fieldName + "="));
        toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
        toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        toStringNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
        // There is no StringBuilder.append method for short and byte. It takes it as int.
        if (fieldJavaType.equals(Character.toString(typeIdentifierShort)) || fieldJavaType.equals(Character.toString(typeIdentifierByte))) {
            fieldJavaType = "I";
        }
        Character pchar = PRIMITIVE_TYPES.get(fieldType);
        if (pchar == null) {
            // It's not a primitive type. StringBuilder.append method signature takes Object type.
            fieldJavaType = "Ljava/lang/Object;";
        }
        toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(" + fieldJavaType + ")Ljava/lang/StringBuilder;", false));
    }
    toStringNode.instructions.add(new LdcInsnNode("}"));
    toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
    toStringNode.instructions.add(new InsnNode(Opcodes.POP));
    toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false));
    toStringNode.instructions.add(new InsnNode(Opcodes.ARETURN));
    classNode.methods.add(toStringNode);
}
Also used : FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) TupleSchemaRegistry(org.apache.apex.malhar.sql.schema.TupleSchemaRegistry) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Example 3 with MethodInsnNode

use of org.apache.xbean.asm5.tree.MethodInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addDateFields.

/**
 * Date field is explicitly handled and provided with 3 variants of types of same data.
 * 1. java.util.Date format
 * 2. long - Epoc time in ms
 * 3. int - Epoc time in sec rounded to date
 *
 * This is purposefully done because SQL operations on Date etc happens on long or int based on whether its a SQL DATE
 * field OR SQL TIMESTAMP field. Hence to cater to that 2 more variant of the same data is added to the POJO.
 */
@SuppressWarnings("unchecked")
private static void addDateFields(ClassNode classNode, String fieldName, String fieldNameForMethods, String type) {
    FieldNode fieldNodeSec = new FieldNode(Opcodes.ACC_PRIVATE, fieldName + "Sec", getJavaType("java.lang.Integer"), null, null);
    classNode.fields.add(fieldNodeSec);
    FieldNode fieldNodeMs = new FieldNode(Opcodes.ACC_PRIVATE, fieldName + "Ms", getJavaType("java.lang.Long"), null, null);
    classNode.fields.add(fieldNodeMs);
    // Create getter for Date
    MethodNode getterNodeDate = new MethodNode(Opcodes.ACC_PUBLIC, "get" + fieldNameForMethods, "()L" + type + ";", null, null);
    getterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    getterNodeDate.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, "L" + type + ";"));
    getterNodeDate.instructions.add(new InsnNode(Opcodes.ARETURN));
    classNode.methods.add(getterNodeDate);
    // Create getter for Sec
    MethodNode getterNodeSec = new MethodNode(Opcodes.ACC_PUBLIC, "get" + fieldNameForMethods + "Sec", "()Ljava/lang/Integer;", null, null);
    getterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    getterNodeSec.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName + "Sec", "Ljava/lang/Integer;"));
    getterNodeSec.instructions.add(new InsnNode(Opcodes.ARETURN));
    classNode.methods.add(getterNodeSec);
    // Create getter for Ms
    MethodNode getterNodeMs = new MethodNode(Opcodes.ACC_PUBLIC, "get" + fieldNameForMethods + "Ms", "()Ljava/lang/Long;", null, null);
    getterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    getterNodeMs.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName + "Ms", "Ljava/lang/Long;"));
    getterNodeMs.instructions.add(new InsnNode(Opcodes.ARETURN));
    classNode.methods.add(getterNodeMs);
    // Create setter for Date
    MethodNode setterNodeDate = new MethodNode(Opcodes.ACC_PUBLIC, "set" + fieldNameForMethods, "(L" + type + ";)V", null, null);
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeDate.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName, "L" + type + ";"));
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeDate.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, type, "getTime", "()J", false));
    setterNodeDate.instructions.add(new LdcInsnNode(new Long(1000)));
    setterNodeDate.instructions.add(new InsnNode(Opcodes.LDIV));
    setterNodeDate.instructions.add(new InsnNode(Opcodes.L2I));
    setterNodeDate.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false));
    setterNodeDate.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Sec", "Ljava/lang/Integer;"));
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeDate.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeDate.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, type, "getTime", "()J", false));
    setterNodeDate.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false));
    setterNodeDate.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Ms", "Ljava/lang/Long;"));
    setterNodeDate.instructions.add(new InsnNode(Opcodes.RETURN));
    classNode.methods.add(setterNodeDate);
    // Create setter for Sec
    MethodNode setterNodeSec = new MethodNode(Opcodes.ACC_PUBLIC, "set" + fieldNameForMethods + "Sec", "(Ljava/lang/Integer;)V", null, null);
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeSec.instructions.add(new TypeInsnNode(Opcodes.NEW, type));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.DUP));
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeSec.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.I2L));
    setterNodeSec.instructions.add(new LdcInsnNode(new Long(1000)));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.LMUL));
    setterNodeSec.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Date", "<init>", "(J)V", false));
    setterNodeSec.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName, "L" + type + ";"));
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeSec.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Sec", "Ljava/lang/Integer;"));
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeSec.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/Long"));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.DUP));
    setterNodeSec.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeSec.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.I2L));
    setterNodeSec.instructions.add(new LdcInsnNode(new Long(1000)));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.LMUL));
    setterNodeSec.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Long", "<init>", "(J)V", false));
    setterNodeSec.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Ms", "Ljava/lang/Long;"));
    setterNodeSec.instructions.add(new InsnNode(Opcodes.RETURN));
    classNode.methods.add(setterNodeSec);
    // Create setter for Ms
    MethodNode setterNodeMs = new MethodNode(Opcodes.ACC_PUBLIC, "set" + fieldNameForMethods + "Ms", "(Ljava/lang/Long;)V", null, null);
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeMs.instructions.add(new TypeInsnNode(Opcodes.NEW, type));
    setterNodeMs.instructions.add(new InsnNode(Opcodes.DUP));
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeMs.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false));
    setterNodeMs.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/util/Date", "<init>", "(J)V", false));
    setterNodeMs.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName, "L" + type + ";"));
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeMs.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/Integer"));
    setterNodeMs.instructions.add(new InsnNode(Opcodes.DUP));
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeMs.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false));
    setterNodeMs.instructions.add(new LdcInsnNode(new Long(1000)));
    setterNodeMs.instructions.add(new InsnNode(Opcodes.LDIV));
    setterNodeMs.instructions.add(new InsnNode(Opcodes.L2I));
    setterNodeMs.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Integer", "<init>", "(I)V", false));
    setterNodeMs.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Sec", "Ljava/lang/Integer;"));
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    setterNodeMs.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    setterNodeMs.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, fieldName + "Ms", "Ljava/lang/Long;"));
    setterNodeMs.instructions.add(new InsnNode(Opcodes.RETURN));
    classNode.methods.add(setterNodeMs);
}
Also used : FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) FieldNode(org.apache.xbean.asm5.tree.FieldNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Example 4 with MethodInsnNode

use of org.apache.xbean.asm5.tree.MethodInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addDefaultConstructor.

/**
 * Add Default constructor for POJO
 * @param classNode ClassNode which needs to be populated with constructor
 */
@SuppressWarnings("unchecked")
private static void addDefaultConstructor(ClassNode classNode) {
    MethodNode constructorNode = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    constructorNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    constructorNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false));
    constructorNode.instructions.add(new InsnNode(Opcodes.RETURN));
    classNode.methods.add(constructorNode);
}
Also used : FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Example 5 with MethodInsnNode

use of org.apache.xbean.asm5.tree.MethodInsnNode in project apex-malhar by apache.

the class BeanClassGenerator method addEqualsMethod.

/**
 * Adds a equals method to underlying class. <br>
 * Algorithm is as follows: <br>
 * <i><p>
 * if (this == other) return true;
 * if (other == null) return false;
 * if (other is not instanceof <this class>) return false;
 * for (field: all fields) {
 * if (other.getField() != this.field) return false;
 * }
 * return true;
 * </p></i>
 * <br>
 *
 * @param classNode
 * @param fieldList
 * @throws JSONException
 */
@SuppressWarnings("unchecked")
private static void addEqualsMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
    MethodNode equalsNode = new MethodNode(Opcodes.ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
    equalsNode.visitAnnotation("Ljava/lang/Override;", true);
    LabelNode l0 = new LabelNode();
    LabelNode l1 = new LabelNode();
    LabelNode l2 = new LabelNode();
    LabelNode l3 = new LabelNode();
    LabelNode l4 = new LabelNode();
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
    // if (this == other) return true;
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    equalsNode.instructions.add(new JumpInsnNode(Opcodes.IF_ACMPNE, l0));
    equalsNode.instructions.add(new InsnNode(Opcodes.ICONST_1));
    equalsNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    equalsNode.instructions.add(l0);
    // if (other == null) return false;
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    equalsNode.instructions.add(new JumpInsnNode(Opcodes.IFNULL, l1));
    // if (!(other instanceof <this class>)) return false;
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    equalsNode.instructions.add(new TypeInsnNode(Opcodes.INSTANCEOF, classNode.name));
    equalsNode.instructions.add(new JumpInsnNode(Opcodes.IFNE, l2));
    equalsNode.instructions.add(l1);
    equalsNode.instructions.add(new InsnNode(Opcodes.ICONST_0));
    equalsNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    equalsNode.instructions.add(l2);
    // Check if it other object can cast to <this class>
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
    equalsNode.instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, classNode.name));
    equalsNode.instructions.add(new VarInsnNode(Opcodes.ASTORE, 2));
    for (int i = 0; i < fieldList.size(); i++) {
        boolean isLast = ((i + 1) == fieldList.size());
        TupleSchemaRegistry.SQLFieldInfo info = fieldList.get(i);
        String fieldName = info.getColumnName();
        String fieldType = info.getType().getJavaType().getName();
        String fieldJavaType = getJavaType(fieldType);
        String getterMethodName = (fieldType.equals("boolean") ? "is" : "get") + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
        equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2));
        equalsNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, getterMethodName, "()" + fieldJavaType, false));
        equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        equalsNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
        switch(fieldType) {
            case "boolean":
            case "byte":
            case "char":
            case "short":
            case "int":
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IF_ICMPEQ : Opcodes.IF_ICMPNE, isLast ? l4 : l3));
                break;
            case "long":
                equalsNode.instructions.add(new InsnNode(Opcodes.LCMP));
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IFEQ : Opcodes.IFNE, isLast ? l4 : l3));
                break;
            case "float":
                equalsNode.instructions.add(new InsnNode(Opcodes.FCMPL));
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IFEQ : Opcodes.IFNE, isLast ? l4 : l3));
                break;
            case "double":
                equalsNode.instructions.add(new InsnNode(Opcodes.DCMPL));
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IFEQ : Opcodes.IFNE, isLast ? l4 : l3));
                break;
            default:
                String objectOwnerType = fieldType.replace('.', '/');
                LabelNode nonNullNode = new LabelNode();
                LabelNode continueNode = new LabelNode();
                equalsNode.instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, nonNullNode));
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IFNULL : Opcodes.IFNONNULL, isLast ? l4 : l3));
                equalsNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, continueNode));
                equalsNode.instructions.add(nonNullNode);
                equalsNode.instructions.add(new InsnNode(Opcodes.POP));
                equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
                equalsNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
                equalsNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 2));
                equalsNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, getterMethodName, "()" + fieldJavaType, false));
                equalsNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, objectOwnerType, "equals", "(Ljava/lang/Object;)Z", false));
                equalsNode.instructions.add(new JumpInsnNode(isLast ? Opcodes.IFNE : Opcodes.IFEQ, isLast ? l4 : l3));
                equalsNode.instructions.add(continueNode);
                break;
        }
    }
    equalsNode.instructions.add(l3);
    equalsNode.instructions.add(new InsnNode(Opcodes.ICONST_0));
    equalsNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    equalsNode.instructions.add(l4);
    equalsNode.instructions.add(new InsnNode(Opcodes.ICONST_1));
    equalsNode.instructions.add(new InsnNode(Opcodes.IRETURN));
    classNode.methods.add(equalsNode);
}
Also used : LabelNode(org.apache.xbean.asm5.tree.LabelNode) TupleSchemaRegistry(org.apache.apex.malhar.sql.schema.TupleSchemaRegistry) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) FieldInsnNode(org.apache.xbean.asm5.tree.FieldInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) TypeInsnNode(org.apache.xbean.asm5.tree.TypeInsnNode) InsnNode(org.apache.xbean.asm5.tree.InsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) IntInsnNode(org.apache.xbean.asm5.tree.IntInsnNode) LdcInsnNode(org.apache.xbean.asm5.tree.LdcInsnNode) MethodNode(org.apache.xbean.asm5.tree.MethodNode) MethodInsnNode(org.apache.xbean.asm5.tree.MethodInsnNode) JumpInsnNode(org.apache.xbean.asm5.tree.JumpInsnNode) VarInsnNode(org.apache.xbean.asm5.tree.VarInsnNode)

Aggregations

FieldInsnNode (org.apache.xbean.asm5.tree.FieldInsnNode)5 InsnNode (org.apache.xbean.asm5.tree.InsnNode)5 IntInsnNode (org.apache.xbean.asm5.tree.IntInsnNode)5 JumpInsnNode (org.apache.xbean.asm5.tree.JumpInsnNode)5 LdcInsnNode (org.apache.xbean.asm5.tree.LdcInsnNode)5 MethodInsnNode (org.apache.xbean.asm5.tree.MethodInsnNode)5 MethodNode (org.apache.xbean.asm5.tree.MethodNode)5 TypeInsnNode (org.apache.xbean.asm5.tree.TypeInsnNode)5 VarInsnNode (org.apache.xbean.asm5.tree.VarInsnNode)5 TupleSchemaRegistry (org.apache.apex.malhar.sql.schema.TupleSchemaRegistry)3 LabelNode (org.apache.xbean.asm5.tree.LabelNode)2 FieldNode (org.apache.xbean.asm5.tree.FieldNode)1