Search in sources :

Example 56 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-core by datanucleus.

the class MetaDataManagerImpl method loadJar.

/* (non-Javadoc)
     * @see org.datanucleus.metadata.MetaDataManager#loadJar(java.lang.String, java.lang.ClassLoader)
     */
@Override
public FileMetaData[] loadJar(String jarFileName, ClassLoader loader) {
    if (!allowMetaDataLoad) {
        return null;
    }
    boolean originatingLoadCall = false;
    if (listenersLoadedMetaData == null && listeners != null) {
        originatingLoadCall = true;
        listenersLoadedMetaData = new ArrayList<AbstractClassMetaData>();
    }
    try {
        if (originatingLoadCall) {
            updateLock.lock();
        }
        if (NucleusLogger.METADATA.isDebugEnabled()) {
            NucleusLogger.METADATA.debug(Localiser.msg("044009", jarFileName));
        }
        ClassLoaderResolver clr = nucleusContext.getClassLoaderResolver(loader);
        List<FileMetaData> fileMetaData = new ArrayList<>();
        // Generate list of package.jdo and classes present in the jar
        Set<String> mappingFileNames = new HashSet<>();
        if (allowXML) {
            String[] packageJdoFiles = ClassUtils.getPackageJdoFilesForJarFile(jarFileName);
            if (packageJdoFiles != null) {
                for (String packageJdoFile : packageJdoFiles) {
                    mappingFileNames.add(packageJdoFile);
                }
            }
        }
        Set<String> classNames = new HashSet<>();
        if (allowAnnotations) {
            String[] jarClassNames = ClassUtils.getClassNamesForJarFile(jarFileName);
            if (jarClassNames != null) {
                for (String jarClassName : jarClassNames) {
                    classNames.add(jarClassName);
                }
            }
        }
        Set<Throwable> exceptions = new HashSet<>();
        if (allowXML && !mappingFileNames.isEmpty()) {
            // Load XML metadata
            for (String mappingFileName : mappingFileNames) {
                try {
                    Enumeration files = clr.getResources(mappingFileName, Thread.currentThread().getContextClassLoader());
                    while (files.hasMoreElements()) {
                        URL url = (URL) files.nextElement();
                        if (url != null && fileMetaDataByURLString.get(url.toString()) == null) {
                            FileMetaData filemd = parseFile(url);
                            if (filemd != null) {
                                // Register the file
                                registerFile(url.toString(), filemd, clr);
                                fileMetaData.add(filemd);
                            }
                        }
                    }
                } catch (InvalidMetaDataException imde) {
                    // Error in the metadata for this file
                    NucleusLogger.METADATA.error(StringUtils.getStringFromStackTrace(imde));
                    exceptions.add(imde);
                } catch (IOException ioe) {
                    NucleusLogger.METADATA.error(Localiser.msg("044027", jarFileName, mappingFileName, ioe.getMessage()), ioe);
                }
            }
        }
        if (allowAnnotations && !classNames.isEmpty()) {
            // Load annotation metadata for all classes
            for (String className : classNames) {
                // Check for MetaData for this class (take precedence over annotations if they exist)
                AbstractClassMetaData cmd = classMetaDataByClass.get(className);
                if (cmd == null) {
                    // No MetaData so try annotations
                    try {
                        Class cls = clr.classForName(className);
                        FileMetaData filemd = loadAnnotationsForClass(cls, clr, true, false);
                        if (filemd != null) {
                            fileMetaData.add(filemd);
                        }
                    } catch (ClassNotResolvedException e) {
                        // log and ignore this exception
                        NucleusLogger.METADATA.error(StringUtils.getStringFromStackTrace(e));
                    } catch (Throwable e) {
                        exceptions.add(e);
                    }
                } else {
                // We have MetaData, and any annotations will be merged in during the populate process
                }
            }
        }
        if (!exceptions.isEmpty()) {
            throw new NucleusUserException(Localiser.msg("044024", jarFileName), exceptions.toArray(new Throwable[exceptions.size()]));
        }
        if (!fileMetaData.isEmpty()) {
            // Populate/Initialise all loaded FileMetaData
            initialiseFileMetaDataForUse(fileMetaData, clr);
        }
        if (NucleusLogger.METADATA.isDebugEnabled()) {
            NucleusLogger.METADATA.debug(Localiser.msg("044010"));
        }
        if (originatingLoadCall) {
            processListenerLoadingCall();
        }
        return fileMetaData.toArray(new FileMetaData[fileMetaData.size()]);
    } finally {
        if (originatingLoadCall) {
            updateLock.unlock();
        }
    }
}
Also used : Enumeration(java.util.Enumeration) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ClassNotResolvedException(org.datanucleus.exceptions.ClassNotResolvedException) URL(java.net.URL) HashSet(java.util.HashSet)

Example 57 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-core by datanucleus.

the class MetaDataManagerImpl method loadUserMetaData.

/* (non-Javadoc)
     * @see org.datanucleus.metadata.MetaDataManager#loadUserMetaData(org.datanucleus.metadata.FileMetaData, java.lang.ClassLoader)
     */
@Override
public void loadUserMetaData(FileMetaData fileMetaData, ClassLoader loader) {
    if (fileMetaData == null) {
        return;
    }
    if (!allowMetaDataLoad) {
        return;
    }
    boolean originatingLoadCall = false;
    if (listenersLoadedMetaData == null && listeners != null) {
        originatingLoadCall = true;
        listenersLoadedMetaData = new ArrayList<AbstractClassMetaData>();
    }
    try {
        if (originatingLoadCall) {
            updateLock.lock();
        }
        if (NucleusLogger.METADATA.isDebugEnabled()) {
            NucleusLogger.METADATA.debug(Localiser.msg("044008"));
        }
        ClassLoaderResolver clr = nucleusContext.getClassLoaderResolver(loader);
        fileMetaData.setFilename("User_Metadata_" + userMetaDataNumber);
        userMetaDataNumber++;
        registerFile(fileMetaData.getFilename(), fileMetaData, clr);
        Collection filemds = new ArrayList<>();
        filemds.add(fileMetaData);
        initialiseFileMetaDataForUse(filemds, clr);
        if (NucleusLogger.METADATA.isDebugEnabled()) {
            NucleusLogger.METADATA.debug(Localiser.msg("044010"));
        }
        if (originatingLoadCall) {
            processListenerLoadingCall();
        }
    } finally {
        if (originatingLoadCall) {
            updateLock.unlock();
        }
    }
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ArrayList(java.util.ArrayList) Collection(java.util.Collection)

Example 58 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-core by datanucleus.

the class MetaDataUtils method getMetaDataForCandidates.

/**
 * Convenience method to return the class metadata for the candidate and optionally its subclasses.
 * Caters for the class being a persistent interface.
 * @param cls The class
 * @param subclasses Include subclasses?
 * @param ec ExecutionContext
 * @return The metadata, starting with the candidate
 * @throws NucleusUserException if candidate is an interface with no metadata (i.e not persistent)
 */
public static List<AbstractClassMetaData> getMetaDataForCandidates(Class cls, boolean subclasses, ExecutionContext ec) {
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    List<AbstractClassMetaData> cmds = new ArrayList<>();
    if (cls.isInterface()) {
        // Query of interface(+subclasses)
        AbstractClassMetaData icmd = ec.getMetaDataManager().getMetaDataForInterface(cls, clr);
        if (icmd == null) {
            throw new NucleusUserException("Attempting to query an interface yet it is not declared 'persistent'." + " Define the interface in metadata as being persistent to perform this operation, and make sure" + " any implementations use the same identity and identity member(s)");
        }
        String[] impls = ec.getMetaDataManager().getClassesImplementingInterface(cls.getName(), clr);
        for (String implName : impls) {
            AbstractClassMetaData implCmd = ec.getMetaDataManager().getMetaDataForClass(implName, clr);
            cmds.add(implCmd);
            if (subclasses) {
                String[] subclassNames = ec.getMetaDataManager().getSubclassesForClass(implCmd.getFullClassName(), true);
                if (subclassNames != null && subclassNames.length > 0) {
                    for (String subclassName : subclassNames) {
                        cmds.add(ec.getMetaDataManager().getMetaDataForClass(subclassName, clr));
                    }
                }
            }
        }
    } else {
        // Query of candidate(+subclasses)
        AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(cls, clr);
        cmds.add(cmd);
        if (subclasses) {
            String[] subclassNames = ec.getMetaDataManager().getSubclassesForClass(cls.getName(), true);
            if (subclassNames != null && subclassNames.length > 0) {
                for (int j = 0; j < subclassNames.length; j++) {
                    AbstractClassMetaData subcmd = ec.getMetaDataManager().getMetaDataForClass(subclassNames[j], clr);
                    cmds.add(subcmd);
                }
            }
        }
    }
    return cmds;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) ArrayList(java.util.ArrayList)

Example 59 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-core by datanucleus.

the class MetaDataUtils method storesPersistable.

/**
 * Convenience method that returns if a field stores a persistable object.
 * Doesn't care if the persistable object is serialised or embedded, just that it is persistable.
 * @param fmd MetaData for the field
 * @param ec ExecutionContext
 * @return Whether it stores a persistable object
 */
public boolean storesPersistable(AbstractMemberMetaData fmd, ExecutionContext ec) {
    if (fmd == null) {
        return false;
    }
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    MetaDataManager mmgr = ec.getMetaDataManager();
    if (fmd.hasCollection()) {
        if (fmd.getCollection().elementIsPersistent()) {
            // Collection of PC elements
            return true;
        }
        String elementType = fmd.getCollection().getElementType();
        Class elementCls = clr.classForName(elementType);
        if (mmgr.getMetaDataForImplementationOfReference(elementCls, null, clr) != null) {
            // Collection of reference type for FCOs
            return true;
        }
        if (elementCls != null && ClassUtils.isReferenceType(elementCls)) {
            try {
                String[] impls = getImplementationNamesForReferenceField(fmd, FieldRole.ROLE_COLLECTION_ELEMENT, clr, mmgr);
                if (impls != null) {
                    elementCls = clr.classForName(impls[0]);
                    if (ec.getApiAdapter().isPersistable(elementCls)) {
                        // Collection of reference type for FCOs
                        return true;
                    }
                }
            } catch (NucleusUserException nue) {
            // No implementations found so not persistable
            }
        }
    } else if (fmd.hasMap()) {
        if (fmd.getMap().keyIsPersistent()) {
            // Map of PC keys
            return true;
        }
        String keyType = fmd.getMap().getKeyType();
        Class keyCls = clr.classForName(keyType);
        if (mmgr.getMetaDataForImplementationOfReference(keyCls, null, clr) != null) {
            // Map with keys of reference type for FCOs
            return true;
        }
        if (keyCls != null && ClassUtils.isReferenceType(keyCls)) {
            try {
                String[] impls = getImplementationNamesForReferenceField(fmd, FieldRole.ROLE_MAP_KEY, clr, mmgr);
                if (impls != null) {
                    keyCls = clr.classForName(impls[0]);
                    if (ec.getApiAdapter().isPersistable(keyCls)) {
                        // Map with keys of reference type for FCOs
                        return true;
                    }
                }
            } catch (NucleusUserException nue) {
            // No implementations found so not persistable
            }
        }
        if (fmd.getMap().valueIsPersistent()) {
            // Map of PC values
            return true;
        }
        String valueType = fmd.getMap().getValueType();
        Class valueCls = clr.classForName(valueType);
        if (mmgr.getMetaDataForImplementationOfReference(valueCls, null, clr) != null) {
            // Map with values of reference type for FCOs
            return true;
        }
        if (valueCls != null && ClassUtils.isReferenceType(valueCls)) {
            try {
                String[] impls = getImplementationNamesForReferenceField(fmd, FieldRole.ROLE_MAP_VALUE, clr, mmgr);
                if (impls != null) {
                    valueCls = clr.classForName(impls[0]);
                    if (ec.getApiAdapter().isPersistable(valueCls)) {
                        // Map with values of reference type for FCOs
                        return true;
                    }
                }
            } catch (NucleusUserException nue) {
            // No implementations found so not persistable
            }
        }
    } else if (fmd.hasArray()) {
        if (mmgr.getApiAdapter().isPersistable(fmd.getType().getComponentType())) {
            // persistable[]
            return true;
        }
        String elementType = fmd.getArray().getElementType();
        Class elementCls = clr.classForName(elementType);
        if (mmgr.getApiAdapter().isPersistable(elementCls)) {
            // Array of reference type for FCOs
            return true;
        } else if (mmgr.getMetaDataForImplementationOfReference(elementCls, null, clr) != null) {
            // Array of reference type for FCOs
            return true;
        } else if (elementCls != null && ClassUtils.isReferenceType(elementCls)) {
            try {
                String[] impls = getImplementationNamesForReferenceField(fmd, FieldRole.ROLE_ARRAY_ELEMENT, clr, mmgr);
                if (impls != null) {
                    elementCls = clr.classForName(impls[0]);
                    if (ec.getApiAdapter().isPersistable(elementCls)) {
                        // Array of reference type for FCOs
                        return true;
                    }
                }
            } catch (NucleusUserException nue) {
            // No implementations found so not persistable
            }
        }
    } else {
        // 1-1 relation with PC
        if (ClassUtils.isReferenceType(fmd.getType()) && mmgr.getMetaDataForImplementationOfReference(fmd.getType(), null, clr) != null) {
            // Reference type for an FCO
            return true;
        }
        if (mmgr.getMetaDataForClass(fmd.getType(), clr) != null) {
            return true;
        }
    }
    return false;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver)

Example 60 with ClassLoaderResolver

use of org.datanucleus.ClassLoaderResolver in project datanucleus-core by datanucleus.

the class IdentityUtils method getObjectFromIdString.

/**
 * Convenience method to find an object given a string form of its identity, and the metadata for the member.
 * @param idStr The id string
 * @param mmd Metadata for the member
 * @param fieldRole Role of this field (see org.datanucleus.metadata.FieldRole)
 * @param ec Execution Context
 * @param checkInheritance Whether to check the inheritance level of this object
 * @return The object
 */
public static Object getObjectFromIdString(String idStr, AbstractMemberMetaData mmd, FieldRole fieldRole, ExecutionContext ec, boolean checkInheritance) {
    ClassLoaderResolver clr = ec.getClassLoaderResolver();
    if (fieldRole == FieldRole.ROLE_FIELD && mmd.getType().isInterface()) {
        // Interface field, so use information about possible implementation types
        String[] implNames = MetaDataUtils.getInstance().getImplementationNamesForReferenceField(mmd, fieldRole, clr, ec.getMetaDataManager());
        if (implNames == null || implNames.length == 0) {
            // No known implementations so no way of knowing the type
            return null;
        }
        AbstractClassMetaData cmd = ec.getMetaDataManager().getMetaDataForClass(implNames[0], clr);
        if (cmd.getIdentityType() == IdentityType.DATASTORE) {
            Object id = ec.getNucleusContext().getIdentityManager().getDatastoreId(idStr);
            return ec.findObject(id, true, checkInheritance, null);
        } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
            Object id = null;
            for (int i = 0; i < implNames.length; i++) {
                if (i != 0) {
                    cmd = ec.getMetaDataManager().getMetaDataForClass(implNames[i], clr);
                }
                if (cmd.usesSingleFieldIdentityClass()) {
                    id = ec.getNucleusContext().getIdentityManager().getApplicationId(clr, cmd, idStr);
                } else {
                    id = ec.newObjectId(clr.classForName(cmd.getFullClassName()), idStr);
                }
                try {
                    return ec.findObject(id, true, checkInheritance, null);
                } catch (NucleusObjectNotFoundException nonfe) {
                // Presumably not this implementation
                }
            }
        }
    } else // TODO Allow for collection<interface>, map<interface, ?>, map<?, interface>, interface[]
    {
        AbstractClassMetaData cmd = null;
        if (fieldRole == FieldRole.ROLE_COLLECTION_ELEMENT) {
            cmd = mmd.getCollection().getElementClassMetaData(clr);
        } else if (fieldRole == FieldRole.ROLE_ARRAY_ELEMENT) {
            cmd = mmd.getArray().getElementClassMetaData(clr);
        } else if (fieldRole == FieldRole.ROLE_MAP_KEY) {
            cmd = mmd.getMap().getKeyClassMetaData(clr);
        } else if (fieldRole == FieldRole.ROLE_MAP_KEY) {
            cmd = mmd.getMap().getKeyClassMetaData(clr);
        } else {
            cmd = ec.getMetaDataManager().getMetaDataForClass(mmd.getType(), clr);
        }
        Object id = null;
        if (cmd.getIdentityType() == IdentityType.DATASTORE) {
            id = ec.getNucleusContext().getIdentityManager().getDatastoreId(idStr);
        } else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
            if (cmd.usesSingleFieldIdentityClass()) {
                // Single-Field identity doesn't have the class name in the string, so cater for the root being abstract
                Class cls = clr.classForName(cmd.getFullClassName());
                if (Modifier.isAbstract(cls.getModifiers())) {
                    // Try to find a non-abstract subclass candidate
                    // TODO Allow for all possibilities rather than just first non-abstract branch
                    String[] subclasses = ec.getMetaDataManager().getSubclassesForClass(cmd.getFullClassName(), false);
                    if (subclasses != null) {
                        for (int i = 0; i < subclasses.length; i++) {
                            cls = clr.classForName(subclasses[i]);
                            if (!Modifier.isAbstract(cls.getModifiers())) {
                                cmd = ec.getMetaDataManager().getMetaDataForClass(cls, clr);
                                break;
                            }
                        }
                    }
                }
                id = ec.getNucleusContext().getIdentityManager().getApplicationId(clr, cmd, idStr);
            } else {
                Class cls = clr.classForName(cmd.getFullClassName());
                id = ec.newObjectId(cls, idStr);
            }
        }
        return ec.findObject(id, true, checkInheritance, null);
    }
    return null;
}
Also used : ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NucleusObjectNotFoundException(org.datanucleus.exceptions.NucleusObjectNotFoundException) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData)

Aggregations

ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)242 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)94 MetaDataManager (org.datanucleus.metadata.MetaDataManager)72 NucleusContext (org.datanucleus.NucleusContext)68 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)65 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)65 PersistenceNucleusContextImpl (org.datanucleus.PersistenceNucleusContextImpl)56 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)56 ClassMetaData (org.datanucleus.metadata.ClassMetaData)54 JPAMetaDataManager (org.datanucleus.api.jpa.metadata.JPAMetaDataManager)51 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)44 NucleusException (org.datanucleus.exceptions.NucleusException)42 PersistenceUnitMetaData (org.datanucleus.metadata.PersistenceUnitMetaData)40 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)40 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)39 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)37 ArrayList (java.util.ArrayList)36 ExecutionContext (org.datanucleus.ExecutionContext)32 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)30 HashMap (java.util.HashMap)28