Search in sources :

Example 56 with AbstractClassMetaData

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

the class PersistenceNucleusContextImpl method initialise.

public synchronized void initialise() {
    final ClassLoaderResolver clr = getClassLoaderResolver(null);
    clr.registerUserClassLoader((ClassLoader) config.getProperty(PropertyNames.PROPERTY_CLASSLOADER_PRIMARY));
    boolean generateSchema = false;
    boolean generateScripts = false;
    String generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_DATABASE_MODE);
    if (generateModeStr == null || generateModeStr.equalsIgnoreCase("none")) {
        // Try scripts instead of database since that wasn't set
        generateModeStr = config.getStringProperty(PropertyNames.PROPERTY_SCHEMA_GENERATE_SCRIPTS_MODE);
        generateScripts = true;
    }
    if (generateModeStr != null && !generateModeStr.equalsIgnoreCase("none")) {
        generateSchema = true;
        // Add any properties that are needed by schema generation (before we create StoreManager)
        if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL)) {
            config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "true");
        }
        if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES)) {
            config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true");
        }
        if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS)) {
            config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
        }
        if (!config.getBooleanProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS)) {
            config.setProperty(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
        }
        if (!config.getBooleanProperty(PropertyNames.PROPERTY_DATASTORE_READONLY)) {
            config.setProperty(PropertyNames.PROPERTY_DATASTORE_READONLY, "false");
        }
    }
    // Create the StoreManager
    try {
        Set<String> propNamesWithDatastore = config.getPropertyNamesWithPrefix("datanucleus.datastore.");
        if (propNamesWithDatastore == null) {
            // Find the StoreManager using the persistence property if specified
            NucleusLogger.DATASTORE.debug("Creating StoreManager for datastore");
            Map<String, Object> datastoreProps = config.getDatastoreProperties();
            this.storeMgr = NucleusContextHelper.createStoreManagerForProperties(config.getPersistenceProperties(), datastoreProps, clr, this);
            // Make sure the isolation level is valid for this StoreManager and correct if necessary
            String transactionIsolation = config.getStringProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION);
            if (transactionIsolation != null) {
                String reqdIsolation = NucleusContextHelper.getTransactionIsolationForStoreManager(storeMgr, transactionIsolation);
                if (!transactionIsolation.equalsIgnoreCase(reqdIsolation)) {
                    config.setProperty(PropertyNames.PROPERTY_TRANSACTION_ISOLATION, reqdIsolation);
                }
            }
        } else {
            NucleusLogger.DATASTORE.debug("Creating FederatedStoreManager to handle federation of primary StoreManager and " + propNamesWithDatastore.size() + " secondary datastores");
            this.storeMgr = new FederatedStoreManager(clr, this);
            this.federated = true;
        }
    } catch (NucleusException ne) {
        NucleusLogger.DATASTORE.error("Exception thrown creating StoreManager : " + StringUtils.getMessageFromRootCauseOfThrowable(ne));
        throw ne;
    }
    NucleusLogger.DATASTORE.debug("StoreManager now created");
    // Make sure MetaDataManager is initialised
    MetaDataManager mmgr = getMetaDataManager();
    final Level2Cache cache = getLevel2Cache();
    if (cache != null) {
        // Add listener for metadata loading so we can pin any classes in the L2 cache that are marked for that
        mmgr.registerListener(new MetaDataListener() {

            @Override
            public void loaded(AbstractClassMetaData cmd) {
                if (cmd.hasExtension("cache-pin") && cmd.getValueForExtension("cache-pin").equalsIgnoreCase("true")) {
                    // Register as auto-pinned in the L2 cache
                    Class cls = clr.classForName(cmd.getFullClassName());
                    cache.pinAll(cls, false);
                }
            }
        });
    }
    // ========== Initialise the StoreManager contents ==========
    // A). Load any classes specified by auto-start
    String autoStartMechanism = config.getStringProperty(PropertyNames.PROPERTY_AUTOSTART_MECHANISM);
    if (autoStartMechanism != null && !autoStartMechanism.equals("None")) {
        initialiseAutoStart(clr);
    }
    // B). Schema Generation
    if (generateSchema) {
        initialiseSchema(generateModeStr, generateScripts);
    }
    // C). Load up internal representations of all persistence-unit classes
    if (config.getStringProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_NAME) != null && config.getBooleanProperty(PropertyNames.PROPERTY_PERSISTENCE_UNIT_LOAD_CLASSES)) {
        // User is using a persistence-unit, so load up its persistence-unit classes into StoreManager
        Collection<String> loadedClasses = getMetaDataManager().getClassesWithMetaData();
        this.storeMgr.manageClasses(clr, loadedClasses.toArray(new String[loadedClasses.size()]));
    }
    if (config.getBooleanProperty(PropertyNames.PROPERTY_QUERY_COMPILE_NAMED_QUERIES_AT_STARTUP)) {
        initialiseNamedQueries(clr);
    }
    if (ecPool == null) {
        ecPool = new ExecutionContextPool(this);
    }
    if (opFactory == null) {
        opFactory = new ObjectProviderFactoryImpl(this);
    }
    if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER)) {
        try {
            multiTenancyProvider = (MultiTenancyProvider) config.getProperty(PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER);
        } catch (Throwable thr) {
            NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_TENANT_PROVIDER + "; should be an instance of MultiTenancyProvider but isnt! Ignored");
        }
    }
    if (config.hasProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER)) {
        try {
            currentUserProvider = (CurrentUserProvider) config.getProperty(PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER);
        } catch (Throwable thr) {
            NucleusLogger.PERSISTENCE.warn("Error accessing property " + PropertyNames.PROPERTY_MAPPING_CURRENT_USER_PROVIDER + "; should be an instance of CurrentUserProvider but isnt! Ignored");
        }
    }
    super.initialise();
}
Also used : FederatedStoreManager(org.datanucleus.store.federation.FederatedStoreManager) JavaxCacheLevel2Cache(org.datanucleus.cache.JavaxCacheLevel2Cache) WeakLevel2Cache(org.datanucleus.cache.WeakLevel2Cache) NullLevel2Cache(org.datanucleus.cache.NullLevel2Cache) SoftLevel2Cache(org.datanucleus.cache.SoftLevel2Cache) Level2Cache(org.datanucleus.cache.Level2Cache) MetaDataManager(org.datanucleus.metadata.MetaDataManager) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) ObjectProviderFactoryImpl(org.datanucleus.state.ObjectProviderFactoryImpl) MetaDataListener(org.datanucleus.metadata.MetaDataListener) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 57 with AbstractClassMetaData

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

the class EnhancerClassAdapter method visitEnd.

/**
 * Method called at the end of the class.
 */
public void visitEnd() {
    AbstractClassMetaData cmd = enhancer.getClassMetaData();
    if (cmd.getPersistenceModifier() == ClassPersistenceModifier.PERSISTENCE_CAPABLE) {
        // Add any new fields
        List fields = enhancer.getFieldsList();
        Iterator fieldsIter = fields.iterator();
        while (fieldsIter.hasNext()) {
            ClassField field = (ClassField) fieldsIter.next();
            if (field.getName().equals(enhancer.getNamer().getDetachedStateFieldName()) && hasDetachedState) {
                // No need to add this field since exists
                continue;
            }
            if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
                DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005021", ((Class) field.getType()).getName() + " " + field.getName()));
            }
            cv.visitField(field.getAccess(), field.getName(), Type.getDescriptor((Class) field.getType()), null, null);
        }
        if (!hasStaticInitialisation) {
            // Add a static initialisation block for the class since nothing added yet
            InitClass method = InitClass.getInstance(enhancer);
            method.initialise(cv);
            method.execute();
            method.close();
        }
        if (!hasDefaultConstructor && enhancer.hasOption(ClassEnhancer.OPTION_GENERATE_DEFAULT_CONSTRUCTOR)) {
            // Add a default constructor
            DefaultConstructor ctr = DefaultConstructor.getInstance(enhancer);
            ctr.initialise(cv);
            ctr.execute();
            ctr.close();
        }
        // Add any new methods
        List methods = enhancer.getMethodsList();
        Iterator<ClassMethod> methodsIter = methods.iterator();
        while (methodsIter.hasNext()) {
            ClassMethod method = methodsIter.next();
            method.initialise(cv);
            method.execute();
            method.close();
        }
        if (Serializable.class.isAssignableFrom(enhancer.getClassBeingEnhanced())) {
            // Class is Serializable
            if (!hasSerialVersionUID) {
                // Needs "serialVersionUID" field
                Long uid = null;
                try {
                    uid = (Long) AccessController.doPrivileged(new PrivilegedAction() {

                        public Object run() {
                            return Long.valueOf(ObjectStreamClass.lookup(enhancer.getClassBeingEnhanced()).getSerialVersionUID());
                        }
                    });
                } catch (Throwable e) {
                    DataNucleusEnhancer.LOGGER.warn(StringUtils.getStringFromStackTrace(e));
                }
                ClassField cf = new ClassField(enhancer, enhancer.getNamer().getSerialVersionUidFieldName(), Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, long.class, uid);
                if (DataNucleusEnhancer.LOGGER.isDebugEnabled()) {
                    DataNucleusEnhancer.LOGGER.debug(Localiser.msg("005021", ((Class) cf.getType()).getName() + " " + cf.getName()));
                }
                cv.visitField(cf.getAccess(), cf.getName(), Type.getDescriptor((Class) cf.getType()), null, cf.getInitialValue());
            }
            // pc class that implements Serializable in the inheritance hierarchy needs to be modified or generated to call it.
            if (cmd.getSuperAbstractClassMetaData() == null && !hasWriteObject) {
                // User hasn't provided their own writeObject, so provide the default but with a call to dnPreSerialize first
                ClassMethod method = WriteObject.getInstance(enhancer);
                method.initialise(cv);
                method.execute();
                method.close();
            }
        }
        // Add dnGetXXX, dnSetXXX for each of the (managed) fields/properties
        for (AbstractMemberMetaData mmd : cmd.getManagedMembers()) {
            if (mmd.getPersistenceModifier() == FieldPersistenceModifier.NONE) {
                // Field/Property is not persistent so ignore
                continue;
            }
            ClassMethod getMethod = null;
            ClassMethod setMethod = null;
            if (mmd instanceof PropertyMetaData) {
            // dnGetXXX, dnSetXXX for property are typically generated when processing existing getXXX, setXXX methods
            // TODO What if the user overrode the getter and not the setter? or vice-versa?
            } else {
                // Generate dnGetXXX, dnSetXXX for field
                byte persistenceFlags = mmd.getPersistenceFlags();
                if ((persistenceFlags & Persistable.MEDIATE_READ) == Persistable.MEDIATE_READ) {
                    getMethod = new GetViaMediate(enhancer, mmd);
                } else if ((persistenceFlags & Persistable.CHECK_READ) == Persistable.CHECK_READ) {
                    getMethod = new GetViaCheck(enhancer, mmd);
                } else {
                    getMethod = new GetNormal(enhancer, mmd);
                }
                if ((persistenceFlags & Persistable.MEDIATE_WRITE) == Persistable.MEDIATE_WRITE) {
                    setMethod = new SetViaMediate(enhancer, mmd);
                } else if ((persistenceFlags & Persistable.CHECK_WRITE) == Persistable.CHECK_WRITE) {
                    setMethod = new SetViaCheck(enhancer, mmd);
                } else {
                    setMethod = new SetNormal(enhancer, mmd);
                }
            }
            if (getMethod != null) {
                getMethod.initialise(cv);
                getMethod.execute();
                getMethod.close();
            }
            if (setMethod != null) {
                setMethod.initialise(cv);
                setMethod.execute();
                setMethod.close();
            }
        }
    }
    cv.visitEnd();
}
Also used : InitClass(org.datanucleus.enhancer.methods.InitClass) SetViaCheck(org.datanucleus.enhancer.methods.SetViaCheck) SetViaMediate(org.datanucleus.enhancer.methods.SetViaMediate) PropertyMetaData(org.datanucleus.metadata.PropertyMetaData) SetNormal(org.datanucleus.enhancer.methods.SetNormal) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) GetNormal(org.datanucleus.enhancer.methods.GetNormal) GetViaCheck(org.datanucleus.enhancer.methods.GetViaCheck) GetViaMediate(org.datanucleus.enhancer.methods.GetViaMediate) PrivilegedAction(java.security.PrivilegedAction) Iterator(java.util.Iterator) List(java.util.List) ObjectStreamClass(java.io.ObjectStreamClass) InitClass(org.datanucleus.enhancer.methods.InitClass) WriteObject(org.datanucleus.enhancer.methods.WriteObject) DefaultConstructor(org.datanucleus.enhancer.methods.DefaultConstructor) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 58 with AbstractClassMetaData

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

the class FetchGroupManager method createFetchGroup.

/**
 * Method to create a new FetchGroup for the class and name.
 * <b>Doesn't add it to the internally managed groups.</b>
 * @param cls The class
 * @param name Name of the group
 * @return The FetchGroup
 * @param <T> Type that the FetchGroup is for
 */
public <T> FetchGroup<T> createFetchGroup(Class<T> cls, String name) {
    // Not present so create a new FetchGroup and add it
    FetchGroup<T> fg = new FetchGroup(nucleusCtx, name, cls);
    if (name.equals(FetchGroup.DEFAULT)) {
        // Special case of wanting to create a group to override the DFG
        fg.addCategory(FetchGroup.DEFAULT);
    } else {
        // Check if this class has a named FetchGroup of this name, so we start from the same members
        ClassLoaderResolver clr = nucleusCtx.getClassLoaderResolver(cls.getClassLoader());
        AbstractClassMetaData cmd = nucleusCtx.getMetaDataManager().getMetaDataForClass(cls, clr);
        if (cmd != null) {
            FetchGroupMetaData fgmd = cmd.getFetchGroupMetaData(name);
            if (fgmd != null) {
                Set<FetchGroupMemberMetaData> fgmmds = fgmd.getMembers();
                for (FetchGroupMemberMetaData fgmmd : fgmmds) {
                    fg.addMember(fgmmd.getName());
                    if (fgmmd.getRecursionDepth() != 1) {
                        fg.setRecursionDepth(fgmmd.getName(), fgmmd.getRecursionDepth());
                    }
                }
            }
        }
    }
    return fg;
}
Also used : FetchGroupMemberMetaData(org.datanucleus.metadata.FetchGroupMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) FetchGroupMetaData(org.datanucleus.metadata.FetchGroupMetaData)

Example 59 with AbstractClassMetaData

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

the class FetchPlanForClass method getMemberNumbersByBitSet.

/**
 * Get all members in the fetch plan for this class and superclasses.
 * @param cmd metadata for the class
 * @return an BitSet with the bits set in the absolute position of the members
 */
private BitSet getMemberNumbersByBitSet(AbstractClassMetaData cmd) {
    FetchPlanForClass fpc = plan.getFetchPlanForClass(cmd);
    BitSet bitSet = fpc.getMemberNumbersForFetchGroups(cmd.getFetchGroupMetaData());
    if (cmd.getPersistableSuperclass() != null) {
        // Recurse to superclass
        AbstractClassMetaData superCmd = cmd.getSuperAbstractClassMetaData();
        FetchPlanForClass superFpc = plan.getFetchPlanForClass(superCmd);
        bitSet.or(superFpc.getMemberNumbersByBitSet(superCmd));
    } else {
        // Make sure that we always have the PK fields in the fetch plan = FetchPlanImpl.NONE
        fpc.setAsNone(bitSet);
    }
    if (plan.dynamicGroups != null) {
        // dynamic fetch groups
        Iterator<FetchGroup> iter = plan.dynamicGroups.iterator();
        while (iter.hasNext()) {
            FetchGroup grp = iter.next();
            if (grp.getType().getName().equals(cmd.getFullClassName())) {
                // Dynamic fetch group applies
                Set<String> members = grp.getMembers();
                Iterator<String> membersIter = members.iterator();
                while (membersIter.hasNext()) {
                    String memberName = membersIter.next();
                    int fieldPos = cmd.getAbsolutePositionOfMember(memberName);
                    if (fieldPos >= 0) {
                        bitSet.set(fieldPos);
                    }
                }
            }
        }
    }
    return bitSet;
}
Also used : BitSet(java.util.BitSet) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Example 60 with AbstractClassMetaData

use of org.datanucleus.metadata.AbstractClassMetaData 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)

Aggregations

AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)204 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)90 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)69 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)59 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)55 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)42 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)42 NucleusException (org.datanucleus.exceptions.NucleusException)37 MetaDataManager (org.datanucleus.metadata.MetaDataManager)37 ArrayList (java.util.ArrayList)31 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)26 SQLTable (org.datanucleus.store.rdbms.sql.SQLTable)23 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)22 ClassLoaderResolverImpl (org.datanucleus.ClassLoaderResolverImpl)19 MapTable (org.datanucleus.store.rdbms.table.MapTable)18 List (java.util.List)16 ObjectProvider (org.datanucleus.state.ObjectProvider)16 PersistableMapping (org.datanucleus.store.rdbms.mapping.java.PersistableMapping)16 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)16 Iterator (java.util.Iterator)15