Search in sources :

Example 66 with AbstractMemberMetaData

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

the class EnhancerMethodAdapter method visitFieldInsn.

/**
 * Method to intercept any calls to fields.
 * @param opcode Operation
 * @param owner Owner class
 * @param name Name of the field
 * @param desc Descriptor for the field
 */
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
    String ownerName = owner.replace('/', '.');
    if (enhancer.isPersistable(ownerName)) {
        AbstractClassMetaData cmd = null;
        boolean fieldInThisClass = true;
        if (enhancer.getClassMetaData().getFullClassName().equals(ownerName)) {
            // Same class so use the input MetaData
            cmd = enhancer.getClassMetaData();
        } else {
            fieldInThisClass = false;
            cmd = enhancer.getMetaDataManager().getMetaDataForClass(ownerName, enhancer.getClassLoaderResolver());
        }
        // enhancing here would cause issues
        if (!fieldInThisClass || !(methodName.equals("<init>"))) {
            AbstractMemberMetaData fmd = cmd.getMetaDataForMember(name);
            if (fmd != null && !fmd.isStatic() && !fmd.isFinal() && fmd.getPersistenceModifier() != FieldPersistenceModifier.NONE && fmd.getPersistenceFlags() != 0 && fmd instanceof FieldMetaData) {
                // Field being accessed has its access mediated by the enhancer, so intercept it
                // Make sure we address the field being in the class it is actually in
                String fieldOwner = fmd.getClassName(true).replace('.', '/');
                if (opcode == Opcodes.GETFIELD) {
                    // Read of a field of a PC class, so replace with dnGetXXX() call
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, fieldOwner, enhancer.getNamer().getGetMethodPrefixMethodName() + name, "(L" + fieldOwner + ";)" + desc);
                    if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
                        DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005023", enhancer.getClassName() + "." + methodName, fmd.getClassName(true) + "." + name, enhancer.getNamer().getGetMethodPrefixMethodName() + name + "()"));
                    }
                    return;
                } else if (opcode == Opcodes.PUTFIELD) {
                    // Write of a field of a PC class, so replace with dnSetXXX() call
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, fieldOwner, enhancer.getNamer().getSetMethodPrefixMethodName() + name, "(L" + fieldOwner + ";" + desc + ")V");
                    if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
                        DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005023", enhancer.getClassName() + "." + methodName, fmd.getClassName(true) + "." + name, enhancer.getNamer().getSetMethodPrefixMethodName() + name + "()"));
                    }
                    return;
                }
            }
        } else {
            DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005024", enhancer.getClassName() + "." + methodName, opcode == Opcodes.GETFIELD ? "get" : "set", ownerName + "." + name));
        }
    }
    super.visitFieldInsn(opcode, owner, name, desc);
}
Also used : FieldMetaData(org.datanucleus.metadata.FieldMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 67 with AbstractMemberMetaData

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

the class EnhancerPropertyGetterAdapter method visitMethodInsn.

public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
    if (mmd instanceof PropertyMetaData) {
        // Check for any calls to getters/setters of properties that are from superclass(es)
        String ownerClassName = owner.replace('/', '.');
        AbstractClassMetaData cmd = enhancer.getClassMetaData();
        if (!enhancer.getASMClassName().equals(owner)) {
            String propName = ClassUtils.getFieldNameForJavaBeanGetter(name);
            if (propName != null) {
                boolean callingOverriddenSuperclassMethod = false;
                while (cmd.getSuperAbstractClassMetaData() != null) {
                    cmd = cmd.getSuperAbstractClassMetaData();
                    if (cmd.getFullClassName().equals(ownerClassName)) {
                        AbstractMemberMetaData theMmd = cmd.getMetaDataForMember(mmd.getName());
                        if (theMmd != null) {
                            callingOverriddenSuperclassMethod = true;
                            break;
                        }
                    }
                }
                if (callingOverriddenSuperclassMethod) {
                    // Call dnGet{propName} in owner instead of "get{propName}"
                    String redirectMethodName = enhancer.getNamer().getGetMethodPrefixMethodName() + propName;
                    visitor.visitMethodInsn(opcode, owner, redirectMethodName, desc, itf);
                    return;
                }
            }
        }
    }
    visitor.visitMethodInsn(opcode, owner, name, desc, itf);
}
Also used : PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 68 with AbstractMemberMetaData

use of org.datanucleus.metadata.AbstractMemberMetaData 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 69 with AbstractMemberMetaData

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

the class L2CachePopulateFieldManager method storeObjectField.

/* (non-Javadoc)
     * @see org.datanucleus.store.fieldmanager.AbstractFieldManager#storeObjectField(int, java.lang.Object)
     */
@Override
public void storeObjectField(int fieldNumber, Object value) {
    AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    if (mmd.getPersistenceModifier() == FieldPersistenceModifier.TRANSACTIONAL) {
        // Cannot cache transactional fields
        cachedPC.setLoadedField(fieldNumber, false);
        return;
    }
    if (!mmd.isCacheable()) {
        // Field is marked as not cacheable so unset its loaded flag and return null
        cachedPC.setLoadedField(fieldNumber, false);
        return;
    }
    // Overridden later if necessary
    cachedPC.setLoadedField(fieldNumber, true);
    if (value == null) {
        cachedPC.setFieldValue(fieldNumber, null);
    } else if (mmd.hasContainer()) {
        // 1-N, M-N Container
        processContainer(fieldNumber, value, mmd);
    } else {
        processField(fieldNumber, value, mmd);
    }
}
Also used : AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 70 with AbstractMemberMetaData

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

the class L2CachePopulateFieldManager method storeIntField.

/* (non-Javadoc)
     * @see org.datanucleus.store.fieldmanager.AbstractFieldManager#storeIntField(int, int)
     */
@Override
public void storeIntField(int fieldNumber, int value) {
    AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);
    if (mmd.getPersistenceModifier() == FieldPersistenceModifier.TRANSACTIONAL) {
        // Cannot cache transactional fields
        cachedPC.setLoadedField(fieldNumber, false);
        return;
    }
    if (!mmd.isCacheable()) {
        // Field is marked as not cacheable so unset its loaded flag and return null
        cachedPC.setLoadedField(fieldNumber, false);
        return;
    }
    cachedPC.setLoadedField(fieldNumber, true);
    cachedPC.setFieldValue(fieldNumber, value);
}
Also used : 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