Search in sources :

Example 81 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.

the class CopyKeyFieldsToObjectId2 method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    visitor.visitCode();
    ClassMetaData cmd = enhancer.getClassMetaData();
    if (cmd.getIdentityType() == IdentityType.APPLICATION) {
        // application identity
        if (!cmd.isInstantiable()) {
            // Application identity but mapped-superclass with no PK defined, so just "return"
            Label startLabel = new Label();
            visitor.visitLabel(startLabel);
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], getNamer().getObjectIdFieldSupplierDescriptor(), null, startLabel, endLabel, 1);
            visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
            visitor.visitMaxs(0, 3);
        } else {
            String objectIdClass = cmd.getObjectidClass();
            String ACN_objectIdClass = objectIdClass.replace('.', '/');
            if (IdentityUtils.isSingleFieldIdentityClass(objectIdClass)) {
                // SingleFieldIdentity
                Label startLabel = new Label();
                visitor.visitLabel(startLabel);
                visitor.visitTypeInsn(Opcodes.NEW, getNamer().getFatalInternalExceptionAsmClassName());
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitLdcInsn("It's illegal to call dnCopyKeyFieldsToObjectId for a class with single-field identity.");
                visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, getNamer().getFatalInternalExceptionAsmClassName(), "<init>", "(Ljava/lang/String;)V");
                visitor.visitInsn(Opcodes.ATHROW);
                Label endLabel = new Label();
                visitor.visitLabel(endLabel);
                visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                visitor.visitLocalVariable(argNames[0], EnhanceUtils.CD_Object, null, startLabel, endLabel, 1);
                visitor.visitLocalVariable("paramObject", "Ljava/lang/Object;", null, startLabel, endLabel, 2);
                visitor.visitMaxs(3, 3);
            } else {
                // User-provided app identity, and compound identity
                Label l0 = new Label();
                Label l1 = new Label();
                Label l2 = new Label();
                visitor.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
                Label startLabel = new Label();
                visitor.visitLabel(startLabel);
                visitor.visitVarInsn(Opcodes.ALOAD, 1);
                Label l4 = new Label();
                visitor.visitJumpInsn(Opcodes.IFNONNULL, l4);
                visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalArgumentException");
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitLdcInsn("ObjectIdFieldSupplier is null");
                visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
                visitor.visitInsn(Opcodes.ATHROW);
                visitor.visitLabel(l4);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 2);
                visitor.visitTypeInsn(Opcodes.INSTANCEOF, ACN_objectIdClass);
                Label l5 = new Label();
                visitor.visitJumpInsn(Opcodes.IFNE, l5);
                visitor.visitTypeInsn(Opcodes.NEW, "java/lang/ClassCastException");
                visitor.visitInsn(Opcodes.DUP);
                visitor.visitLdcInsn("oid is not instanceof " + objectIdClass);
                visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/ClassCastException", "<init>", "(Ljava/lang/String;)V");
                visitor.visitInsn(Opcodes.ATHROW);
                visitor.visitLabel(l5);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 2);
                visitor.visitTypeInsn(Opcodes.CHECKCAST, ACN_objectIdClass);
                visitor.visitVarInsn(Opcodes.ASTORE, 3);
                visitor.visitLabel(l0);
                // Copy the PK members using the appropriate method for each field/property
                int[] pkFieldNums = enhancer.getClassMetaData().getPKMemberPositions();
                Label reflectionFieldStart = null;
                for (int i = 0; i < pkFieldNums.length; i++) {
                    AbstractMemberMetaData fmd = enhancer.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(pkFieldNums[i]);
                    String fieldTypeDesc = Type.getDescriptor(fmd.getType());
                    String typeMethodName = EnhanceUtils.getTypeNameForPersistableMethod(fmd.getType());
                    int pkFieldModifiers = ClassUtils.getModifiersForFieldOfClass(enhancer.getClassLoaderResolver(), objectIdClass, fmd.getName());
                    // Check if the PK field type is a PC (CompoundIdentity)
                    AbstractClassMetaData acmd = enhancer.getMetaDataManager().getMetaDataForClass(fmd.getType(), enhancer.getClassLoaderResolver());
                    if (acmd != null && acmd.getIdentityType() != IdentityType.NONDURABLE) {
                        // CompoundIdentity, this field of the PK is a PC
                        visitor.visitVarInsn(Opcodes.ALOAD, 3);
                        visitor.visitVarInsn(Opcodes.ALOAD, 1);
                        EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
                        visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
                        if (typeMethodName.equals("Object")) {
                            visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
                        }
                        // Note that we swap JDOHelper.getObjectId(obj) for ((Persistable)obj).dnGetObjectId())
                        visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getPersistableAsmClassName(), getNamer().getGetObjectIdMethodName(), "()Ljava/lang/Object;", true);
                        // visitor.visitMethodInsn(Opcodes.INVOKESTATIC, getNamer().getHelperAsmClassName(), "getObjectId", "(Ljava/lang/Object;)Ljava/lang/Object;");
                        visitor.visitTypeInsn(Opcodes.CHECKCAST, acmd.getObjectidClass().replace('.', '/'));
                        // TODO Cater for property, and private field cases
                        visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), "L" + acmd.getObjectidClass().replace('.', '/') + ";");
                    } else {
                        // Standard application-identity
                        if (fmd instanceof PropertyMetaData) {
                            // Field in PK is property, hence use setXXX in PK
                            visitor.visitVarInsn(Opcodes.ALOAD, 3);
                            visitor.visitVarInsn(Opcodes.ALOAD, 1);
                            EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
                            visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
                            if (typeMethodName.equals("Object")) {
                                visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
                            }
                            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ACN_objectIdClass, ClassUtils.getJavaBeanSetterName(fmd.getName()), "(" + fieldTypeDesc + ")V");
                        } else if (Modifier.isPublic(pkFieldModifiers)) {
                            // Field in PK is public so update directly
                            visitor.visitVarInsn(Opcodes.ALOAD, 3);
                            visitor.visitVarInsn(Opcodes.ALOAD, 1);
                            EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
                            visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetch" + typeMethodName + "Field", "(I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fmd.getType()));
                            if (typeMethodName.equals("Object")) {
                                visitor.visitTypeInsn(Opcodes.CHECKCAST, fmd.getTypeName().replace('.', '/'));
                            }
                            visitor.visitFieldInsn(Opcodes.PUTFIELD, ACN_objectIdClass, fmd.getName(), fieldTypeDesc);
                        } else {
                            // Field in PK is protected/private so use reflection, generating
                            // "Field field = o.getClass().getDeclaredField("pmIDFloat");"
                            // "field.setAccessible(true);"
                            // "field.set(o, fs.fetchObjectField(1));"
                            visitor.visitVarInsn(Opcodes.ALOAD, 3);
                            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
                            visitor.visitLdcInsn(fmd.getName());
                            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
                            visitor.visitVarInsn(Opcodes.ASTORE, 4);
                            if (reflectionFieldStart == null) {
                                reflectionFieldStart = new Label();
                                visitor.visitLabel(reflectionFieldStart);
                            }
                            visitor.visitVarInsn(Opcodes.ALOAD, 4);
                            visitor.visitInsn(Opcodes.ICONST_1);
                            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setAccessible", "(Z)V");
                            visitor.visitVarInsn(Opcodes.ALOAD, 4);
                            visitor.visitVarInsn(Opcodes.ALOAD, 3);
                            visitor.visitVarInsn(Opcodes.ALOAD, 1);
                            EnhanceUtils.addBIPUSHToMethod(visitor, fmd.getFieldId());
                            if (fmd.getTypeName().equals("boolean")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchBooleanField", "(I)Z");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setBoolean", "(Ljava/lang/Object;Z)V");
                            } else if (fmd.getTypeName().equals("byte")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchByteField", "(I)B");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setByte", "(Ljava/lang/Object;B)V");
                            } else if (fmd.getTypeName().equals("char")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchCharField", "(I)C");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setChar", "(Ljava/lang/Object;C)V");
                            } else if (fmd.getTypeName().equals("double")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchDoubleField", "(I)D");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setDouble", "(Ljava/lang/Object;D)V");
                            } else if (fmd.getTypeName().equals("float")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchFloatField", "(I)F");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setFloat", "(Ljava/lang/Object;F)V");
                            } else if (fmd.getTypeName().equals("int")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchIntField", "(I)I");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setInt", "(Ljava/lang/Object;I)V");
                            } else if (fmd.getTypeName().equals("long")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchLongField", "(I)J");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setLong", "(Ljava/lang/Object;J)V");
                            } else if (fmd.getTypeName().equals("short")) {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchShortField", "(I)S");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "setShort", "(Ljava/lang/Object;S)V");
                            } else {
                                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getObjectIdFieldSupplierAsmClassName(), "fetchObjectField", "(I)Ljava/lang/Object;");
                                visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/reflect/Field", "set", "(Ljava/lang/Object;Ljava/lang/Object;)V");
                            }
                        }
                    }
                }
                visitor.visitLabel(l1);
                Label l20 = new Label();
                visitor.visitJumpInsn(Opcodes.GOTO, l20);
                visitor.visitLabel(l2);
                visitor.visitFrame(Opcodes.F_FULL, 4, new Object[] { getClassEnhancer().getASMClassName(), getClassEnhancer().getNamer().getObjectIdFieldSupplierAsmClassName(), "java/lang/Object", ACN_objectIdClass }, 1, new Object[] { "java/lang/Exception" });
                visitor.visitVarInsn(Opcodes.ASTORE, 4);
                visitor.visitLabel(l20);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitInsn(Opcodes.RETURN);
                Label endLabel = new Label();
                visitor.visitLabel(endLabel);
                visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
                visitor.visitLocalVariable(argNames[0], getNamer().getObjectIdFieldSupplierDescriptor(), null, startLabel, endLabel, 1);
                visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
                visitor.visitLocalVariable("o", "L" + ACN_objectIdClass + ";", null, l0, endLabel, 3);
                if (reflectionFieldStart != null) {
                    visitor.visitLocalVariable("field", "Ljava/lang/reflect/Field;", null, reflectionFieldStart, l2, 4);
                    visitor.visitMaxs(4, 5);
                } else {
                    visitor.visitMaxs(3, 4);
                }
            }
        }
    } else {
        // datastore/nondurable identity
        Label startLabel = new Label();
        visitor.visitLabel(startLabel);
        visitor.visitInsn(Opcodes.RETURN);
        Label endLabel = new Label();
        visitor.visitLabel(endLabel);
        visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
        visitor.visitLocalVariable(argNames[0], "L" + getNamer().getObjectIdFieldSupplierAsmClassName() + ";", null, startLabel, endLabel, 1);
        visitor.visitLocalVariable(argNames[1], EnhanceUtils.CD_Object, null, startLabel, endLabel, 2);
        visitor.visitMaxs(0, 3);
    }
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) ClassMetaData(org.datanucleus.metadata.ClassMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 82 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.

the class PrimaryKeyGenerator method addStringConstructor.

/**
 * Method to add a constructor taking in a String.
 * @param cw The ClassWriter to use
 */
protected void addStringConstructor(ClassWriter cw) {
    if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
        DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005020", pkClassName + "(String str)"));
    }
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null);
    mv.visitCode();
    int[] pkPositions = cmd.getPKMemberPositions();
    Label[] fieldLabels = new Label[pkPositions.length];
    Label startLabel = new Label();
    mv.visitLabel(startLabel);
    // Invoke default constructor of superclass (Object)
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
    // StringTokenizer tokeniser = new StringTokenizer(str, {stringSeparator});
    mv.visitTypeInsn(Opcodes.NEW, "java/util/StringTokenizer");
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitLdcInsn(stringSeparator);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/StringTokenizer", "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
    mv.visitVarInsn(Opcodes.ASTORE, 2);
    Label l5 = new Label();
    mv.visitLabel(l5);
    // Get the next token and set the respective field from it
    int astorePosition = 2;
    for (int i = 0; i < pkPositions.length; i++) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtRelativePosition(pkPositions[i]);
        String typeName_ASM = mmd.getTypeName().replace('.', '/');
        astorePosition++;
        // String tokenX = tokeniser.nextToken();
        mv.visitVarInsn(Opcodes.ALOAD, 2);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/StringTokenizer", "nextToken", "()Ljava/lang/String;");
        mv.visitVarInsn(Opcodes.ASTORE, astorePosition);
        fieldLabels[i] = new Label();
        mv.visitLabel(fieldLabels[i]);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        if (mmd.getType() == long.class || mmd.getType() == int.class || mmd.getType() == short.class) {
            // Uses the following pattern (e.g for Integer)
            // fieldX = Integer.valueOf(tokenX).intValue();
            String type_desc = EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName());
            String wrapperClassName_ASM = "java/lang/Long";
            String wrapperConverterMethod = "longValue";
            if (mmd.getType() == int.class) {
                wrapperClassName_ASM = "java/lang/Integer";
                wrapperConverterMethod = "intValue";
            } else if (mmd.getType() == short.class) {
                wrapperClassName_ASM = "java/lang/Short";
                wrapperConverterMethod = "shortValue";
            }
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClassName_ASM, "valueOf", "(Ljava/lang/String;)L" + wrapperClassName_ASM + ";");
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, wrapperClassName_ASM, wrapperConverterMethod, "()" + type_desc);
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), type_desc);
        } else if (mmd.getType() == char.class) {
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, "field1", "C");
        } else if (mmd.getType() == String.class) {
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName()));
        } else if (mmd.getType() == Long.class || mmd.getType() == Integer.class || mmd.getType() == Short.class || mmd.getType() == BigInteger.class) {
            // Uses the following pattern (e.g for Long)
            // fieldX = Long.valueOf(tokenX);
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, typeName_ASM, "valueOf", "(Ljava/lang/String;)L" + typeName_ASM + ";");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "L" + typeName_ASM + ";");
        } else if (mmd.getType() == Currency.class) {
            // "fieldX = TypeX.newInstance(tokenX)"
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Currency", "getInstance", "(Ljava/lang/String;)Ljava/util/Currency;");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/Currency;");
        } else if (mmd.getType() == TimeZone.class) {
            // "fieldX = TimeZone.getTimeZone(tokenX)"
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/TimeZone;");
        } else if (mmd.getType() == UUID.class) {
            // "fieldX = UUID.fromString(tokenX)"
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/UUID", "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/UUID;");
        } else if (Date.class.isAssignableFrom(mmd.getType())) {
            // fieldX = new Date(new Long(tokenX).longValue());
            mv.visitTypeInsn(Opcodes.NEW, typeName_ASM);
            mv.visitInsn(Opcodes.DUP);
            mv.visitTypeInsn(Opcodes.NEW, "java/lang/Long");
            mv.visitInsn(Opcodes.DUP);
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Long", "<init>", "(Ljava/lang/String;)V");
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, typeName_ASM, "<init>", "(J)V");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName()));
        } else if (Calendar.class.isAssignableFrom(mmd.getType())) {
            // fieldX = Calendar.getInstance();
            // fieldX.setTimeInMillis(Long.valueOf(tokenX).longValue());
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/Calendar", "getInstance", "()Ljava/util/Calendar;");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), "Ljava/util/Calendar;");
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitFieldInsn(Opcodes.GETFIELD, className_ASM, mmd.getName(), "Ljava/util/Calendar;");
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(Ljava/lang/String;)Ljava/lang/Long;");
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Calendar", "setTimeInMillis", "(J)V");
        } else {
            // "fieldX = new TypeX(tokenX)"
            // TODO If this is compound identity and the related object uses SingleFieldIdentity then
            // we need to use a different constructor with this value
            String fieldTypeName = getTypeNameForField(mmd);
            String fieldTypeName_ASM = fieldTypeName.replace('.', '/');
            mv.visitTypeInsn(Opcodes.NEW, fieldTypeName_ASM);
            mv.visitInsn(Opcodes.DUP);
            mv.visitVarInsn(Opcodes.ALOAD, astorePosition);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, fieldTypeName_ASM, "<init>", "(Ljava/lang/String;)V");
            mv.visitFieldInsn(Opcodes.PUTFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(fieldTypeName));
        }
    }
    mv.visitInsn(Opcodes.RETURN);
    Label endLabel = new Label();
    mv.visitLabel(endLabel);
    int variableNum = 0;
    mv.visitLocalVariable("this", className_DescName, null, startLabel, endLabel, variableNum++);
    mv.visitLocalVariable("str", "Ljava/lang/String;", null, startLabel, endLabel, variableNum++);
    mv.visitLocalVariable("tokeniser", "Ljava/util/StringTokenizer;", null, l5, endLabel, variableNum++);
    for (int i = 0; i < pkPositions.length; i++) {
        mv.visitLocalVariable("token" + i, "Ljava/lang/String;", null, fieldLabels[i], endLabel, variableNum++);
    }
    mv.visitMaxs(6, variableNum);
    mv.visitEnd();
}
Also used : TimeZone(java.util.TimeZone) Label(org.datanucleus.enhancer.asm.Label) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) Date(java.util.Date) MethodVisitor(org.datanucleus.enhancer.asm.MethodVisitor)

Example 83 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.

the class PrimaryKeyGenerator method addMethodHashCode.

/**
 * Method to add a hashCode() method.
 * @param cw The ClassWriter to use
 */
protected void addMethodHashCode(ClassWriter cw) {
    if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
        DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005019", "int " + pkClassName + ".hashCode()"));
    }
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
    mv.visitCode();
    Label startLabel = new Label();
    mv.visitLabel(startLabel);
    int[] pkPositions = cmd.getPKMemberPositions();
    for (int i = 0; i < pkPositions.length; i++) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtRelativePosition(pkPositions[i]);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, className_ASM, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(mmd.getTypeName()));
        if (mmd.getType() == long.class) {
            // "(int)fieldX"
            mv.visitInsn(Opcodes.L2I);
        } else if (mmd.getType() == int.class || mmd.getType() == short.class || mmd.getType() == char.class) {
        // "fieldX"
        } else {
            // "fieldX.hashCode"
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, mmd.getTypeName().replace('.', '/'), "hashCode", "()I");
        }
        if (i > 0) {
            // "^"
            mv.visitInsn(Opcodes.IXOR);
        }
    }
    mv.visitInsn(Opcodes.IRETURN);
    Label endLabel = new Label();
    mv.visitLabel(endLabel);
    mv.visitLocalVariable("this", className_DescName, null, startLabel, endLabel, 0);
    mv.visitMaxs(3, 1);
    mv.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) MethodVisitor(org.datanucleus.enhancer.asm.MethodVisitor)

Example 84 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.

the class PrimaryKeyGenerator method addFields.

/**
 * Method to add fields to match the PK fields of the persistable class
 * @param cw The ClassWriter to use
 */
protected void addFields(ClassWriter cw) {
    int[] pkPositions = cmd.getPKMemberPositions();
    for (int i = 0; i < pkPositions.length; i++) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtRelativePosition(pkPositions[i]);
        String fieldTypeName = getTypeNameForField(mmd);
        if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
            DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005021", fieldTypeName + " " + pkClassName + " " + mmd.getName()));
        }
        FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, mmd.getName(), EnhanceUtils.getTypeDescriptorForType(fieldTypeName), null, null);
        fv.visitEnd();
    }
}
Also used : AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) FieldVisitor(org.datanucleus.enhancer.asm.FieldVisitor)

Example 85 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData in project datanucleus-core by datanucleus.

the class ReplaceField method execute.

/**
 * Method to add the contents of the class method.
 */
public void execute() {
    AbstractMemberMetaData[] fields = enhancer.getClassMetaData().getManagedMembers();
    String pcSuperclassName = enhancer.getClassMetaData().getPersistableSuperclass();
    visitor.visitCode();
    Label startLabel = new Label();
    visitor.visitLabel(startLabel);
    if (pcSuperclassName != null) {
        if (fields.length > 0) {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
            Label l1 = new Label();
            visitor.visitJumpInsn(Opcodes.IFNONNULL, l1);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("state manager is null");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            visitor.visitLabel(l1);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitFieldInsn(Opcodes.GETSTATIC, getClassEnhancer().getASMClassName(), getNamer().getInheritedFieldCountFieldName(), "I");
            visitor.visitInsn(Opcodes.ISUB);
            Label[] fieldOptions = new Label[fields.length];
            for (int i = 0; i < fields.length; i++) {
                fieldOptions[i] = new Label();
            }
            Label defaultLabel = new Label();
            Label endSwitchLabel = new Label();
            // switch:
            visitor.visitTableSwitchInsn(0, fields.length - 1, defaultLabel, fieldOptions);
            for (int i = 0; i < fields.length; i++) {
                visitor.visitLabel(fieldOptions[i]);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ILOAD, 1);
                String methodNameType = EnhanceUtils.getTypeNameForPersistableMethod(fields[i].getType());
                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), "replacing" + methodNameType + "Field", "(" + getNamer().getPersistableDescriptor() + "I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fields[i].getType()));
                if (methodNameType.equals("Object")) {
                    // Check any Object types for casting
                    visitor.visitTypeInsn(Opcodes.CHECKCAST, fields[i].getTypeName().replace('.', '/'));
                }
                if (fields[i] instanceof PropertyMetaData) {
                    // Persistent properties so use dnSetXXX(...)
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getSetMethodPrefixMethodName() + fields[i].getName(), "(" + Type.getDescriptor(fields[i].getType()) + ")V");
                } else {
                    // Persistent field so use xxx = ...
                    visitor.visitFieldInsn(Opcodes.PUTFIELD, getClassEnhancer().getASMClassName(), fields[i].getName(), Type.getDescriptor(fields[i].getType()));
                }
                visitor.visitJumpInsn(Opcodes.GOTO, endSwitchLabel);
            }
            // default:
            visitor.visitLabel(defaultLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, pcSuperclassName.replace('.', '/'), getNamer().getReplaceFieldMethodName(), "(I)V");
            // End of switch
            visitor.visitLabel(endSwitchLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(4, 2);
        } else {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, pcSuperclassName.replace('.', '/'), getNamer().getReplaceFieldMethodName(), "(I)V");
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(2, 2);
        }
    } else {
        if (fields.length > 0) {
            visitor.visitVarInsn(Opcodes.ALOAD, 0);
            visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
            Label l1 = new Label();
            visitor.visitJumpInsn(Opcodes.IFNONNULL, l1);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalStateException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("state manager is null");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            visitor.visitLabel(l1);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            Label[] fieldOptions = new Label[fields.length];
            for (int i = 0; i < fields.length; i++) {
                fieldOptions[i] = new Label();
            }
            Label defaultLabel = new Label();
            Label endSwitchLabel = new Label();
            // switch:
            visitor.visitTableSwitchInsn(0, fields.length - 1, defaultLabel, fieldOptions);
            for (int i = 0; i < fields.length; i++) {
                visitor.visitLabel(fieldOptions[i]);
                visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitFieldInsn(Opcodes.GETFIELD, getClassEnhancer().getASMClassName(), getNamer().getStateManagerFieldName(), getNamer().getStateManagerDescriptor());
                visitor.visitVarInsn(Opcodes.ALOAD, 0);
                visitor.visitVarInsn(Opcodes.ILOAD, 1);
                String methodNameType = EnhanceUtils.getTypeNameForPersistableMethod(fields[i].getType());
                visitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, getNamer().getStateManagerAsmClassName(), "replacing" + methodNameType + "Field", "(" + getNamer().getPersistableDescriptor() + "I)" + EnhanceUtils.getTypeDescriptorForEnhanceMethod(fields[i].getType()));
                if (methodNameType.equals("Object")) {
                    // Check any Object types for casting
                    visitor.visitTypeInsn(Opcodes.CHECKCAST, fields[i].getTypeName().replace('.', '/'));
                }
                if (fields[i] instanceof PropertyMetaData) {
                    // Persistent properties so use dnSetXXX(...)
                    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getClassEnhancer().getASMClassName(), getNamer().getSetMethodPrefixMethodName() + fields[i].getName(), "(" + Type.getDescriptor(fields[i].getType()) + ")V");
                } else {
                    // Persistent field so use xxx = ...
                    visitor.visitFieldInsn(Opcodes.PUTFIELD, getClassEnhancer().getASMClassName(), fields[i].getName(), Type.getDescriptor(fields[i].getType()));
                }
                visitor.visitJumpInsn(Opcodes.GOTO, endSwitchLabel);
            }
            // default:
            visitor.visitLabel(defaultLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/IllegalArgumentException");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuffer");
            visitor.visitInsn(Opcodes.DUP);
            visitor.visitLdcInsn("out of field index :");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "(Ljava/lang/String;)V");
            visitor.visitVarInsn(Opcodes.ILOAD, 1);
            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(I)Ljava/lang/StringBuffer;");
            visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
            visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V");
            visitor.visitInsn(Opcodes.ATHROW);
            // End of switch
            visitor.visitLabel(endSwitchLabel);
            visitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(5, 2);
        } else {
            visitor.visitInsn(Opcodes.RETURN);
            Label endLabel = new Label();
            visitor.visitLabel(endLabel);
            visitor.visitLocalVariable("this", getClassEnhancer().getClassDescriptor(), null, startLabel, endLabel, 0);
            visitor.visitLocalVariable(argNames[0], "I", null, startLabel, endLabel, 1);
            visitor.visitMaxs(0, 2);
        }
    }
    visitor.visitEnd();
}
Also used : Label(org.datanucleus.enhancer.asm.Label) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)267 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)89 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)84 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)82 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)59 ClassMetaData (org.datanucleus.metadata.ClassMetaData)55 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)50 NucleusException (org.datanucleus.exceptions.NucleusException)41 MetaDataManager (org.datanucleus.metadata.MetaDataManager)40 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)38 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)35 RelationType (org.datanucleus.metadata.RelationType)33 NucleusContext (org.datanucleus.NucleusContext)32 PersistenceNucleusContextImpl (org.datanucleus.PersistenceNucleusContextImpl)32 JPAMetaDataManager (org.datanucleus.api.jpa.metadata.JPAMetaDataManager)29 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)28 ColumnMetaData (org.datanucleus.metadata.ColumnMetaData)27 ExecutionContext (org.datanucleus.ExecutionContext)26 ObjectProvider (org.datanucleus.state.ObjectProvider)25 ArrayList (java.util.ArrayList)24