use of org.datanucleus.metadata.FileMetaData in project datanucleus-api-jdo by datanucleus.
the class JDOMetaDataManager method loadMetaDataForClass.
/**
* Load the metadata for the specified class (if available).
* With JDO we check for XML metadata for the class (in one of the standard locations), or annotations on the class itself.
* @param c The class
* @param clr ClassLoader resolver
* @return The metadata for this class (if found)
*/
protected AbstractClassMetaData loadMetaDataForClass(Class c, ClassLoaderResolver clr) {
if (!allowMetaDataLoad) {
// Not allowing further metadata load so just return
return null;
}
String className = c.getName();
try {
// TODO What if a different thread starts loading this class just before we do? it will load then we do too
updateLock.lock();
if (allowXML) {
// Search valid location for a JDO XML definition (package.jdo etc) for this class and load all classes specified in the file
FileMetaData filemd = loadXMLMetaDataForClass(c, clr, null, getJDOFileSuffix(), MetadataFileType.JDO_FILE, true);
if (filemd != null) {
// Class has had its metadata loaded
utilisedFileMetaData.add(filemd);
// If not MetaData complete will also merge in annotations in populate()
// Retrieve the MetaData for the requested class
AbstractClassMetaData the_md = classMetaDataByClass.get(className);
return the_md;
}
}
if (allowAnnotations) {
// No JDO XML definition (package.jdo), so check for annotations. Note package-{mapping}.orm will be added later in populate().
FileMetaData annFilemd = loadAnnotationsForClass(c, clr, true, true);
if (annFilemd != null) {
// No MetaData but annotations present so use that
if (c.isInterface()) {
return annFilemd.getPackage(0).getInterface(0);
}
return annFilemd.getPackage(0).getClass(0);
}
}
// Not found, so add to known classes/interfaces without MetaData
if (NucleusLogger.METADATA.isDebugEnabled()) {
NucleusLogger.METADATA.debug(Localiser.msg("044043", className));
}
classesWithoutPersistenceInfo.add(className);
return null;
} finally {
updateLock.unlock();
}
}
use of org.datanucleus.metadata.FileMetaData in project datanucleus-api-jdo by datanucleus.
the class JDOMetaDataManager method getMetaDataForSequence.
/**
* Accessor for the MetaData for a Sequence in a package.
* If the sequence is not yet known will search the valid locations for the passed name.
* @param clr the ClassLoaderResolver
* @param packageSequenceName Fully qualified name of the sequence (inc package name)
* @return The SequenceMetaData for this named sequence
*/
public SequenceMetaData getMetaDataForSequence(ClassLoaderResolver clr, String packageSequenceName) {
SequenceMetaData seqmd = super.getMetaDataForSequence(clr, packageSequenceName);
if (seqmd != null) {
return seqmd;
}
// MetaData not found so maybe just not yet loaded
String packageName = packageSequenceName;
if (packageSequenceName.lastIndexOf('.') >= 0) {
packageName = packageSequenceName.substring(0, packageSequenceName.lastIndexOf('.'));
}
// Search valid JDO file locations ("jdo" and "orm" files for the specified package)
List<String> locations = new ArrayList<>();
locations.addAll(getValidMetaDataLocationsForItem(getJDOFileSuffix(), null, packageName, false));
locations.addAll(getValidMetaDataLocationsForItem(getORMFileSuffix(), getORMMappingName(), packageName, false));
for (String location : locations) {
// Process all resources for this location
Enumeration resources;
try {
resources = clr.getResources(location, null);
} catch (IOException e) {
throw new NucleusException("Error loading resource", e).setFatal();
}
while (resources.hasMoreElements()) {
URL fileURL = (URL) resources.nextElement();
if (fileMetaDataByURLString.get(fileURL.toString()) == null) {
// File hasn't been loaded so load it
FileMetaData filemd = parseFile(fileURL);
registerFile(fileURL.toString(), filemd, clr);
// Populate all classes in this file we've just parsed
// TODO Populate the classes found in this file
}
}
if (sequenceMetaDataByPackageSequence != null) {
// Try lookup using package name
seqmd = sequenceMetaDataByPackageSequence.get(packageSequenceName);
}
if (seqmd != null) {
if (NucleusLogger.METADATA.isDebugEnabled()) {
NucleusLogger.METADATA.debug(Localiser.msg("044053", packageSequenceName, location));
}
return seqmd;
}
if (NucleusLogger.METADATA.isDebugEnabled()) {
NucleusLogger.METADATA.debug(Localiser.msg("044051", packageSequenceName, location));
}
}
return null;
}
use of org.datanucleus.metadata.FileMetaData in project datanucleus-api-jdo by datanucleus.
the class JDOMetaDataManager method addORMDataToClass.
/**
* Load up and add the O/R mapping info for the specified class to the stored JDO ClassMetaData.
* @param c The class
* @param clr the ClassLoaderResolver
*/
public void addORMDataToClass(Class c, ClassLoaderResolver clr) {
if (getNucleusContext() instanceof EnhancementNucleusContextImpl) {
// We don't need ORM data when enhancing
return;
}
if (!allowORM) {
// StoreManager doesn't "map" to the datastore so don't use ORM info
return;
}
// Get the JDO MetaData for this class/interface
AbstractClassMetaData cmd = classMetaDataByClass.get(c.getName());
// See if we already have a file registered with the ORM metadata for this class
AbstractClassMetaData ormCmd = ormClassMetaDataByClass.get(c.getName());
if (ormCmd != null) {
// Merge the ORM class into the JDO class
MetaDataMerger.mergeClassORMData(cmd, ormCmd, this);
// Remove it from the map since no longer needed
ormClassMetaDataByClass.remove(c.getName());
return;
}
if (allowXML) {
// No ORM loaded for this class, so find if there is any ORM metadata available
FileMetaData filemdORM = loadXMLMetaDataForClass(c, clr, getORMMappingName(), getORMFileSuffix(), MetadataFileType.JDO_ORM_FILE, false);
if (filemdORM != null) {
// The ORM file has now been registered, so find the class and merge it into the JDO definition
ormCmd = ormClassMetaDataByClass.get(c.getName());
if (ormCmd != null) {
// Merge the ORM file into the JDO file
MetaDataMerger.mergeFileORMData((FileMetaData) cmd.getPackageMetaData().getParent(), (FileMetaData) ormCmd.getPackageMetaData().getParent());
// Merge the ORM class into the JDO class
MetaDataMerger.mergeClassORMData(cmd, ormCmd, this);
// Remove it from the map since no longer needed
ormClassMetaDataByClass.remove(c.getName());
}
}
}
}
use of org.datanucleus.metadata.FileMetaData in project datanucleus-api-jdo by datanucleus.
the class JDOPersistenceManagerFactory method registerMetadata.
/**
* Method to register the supplied metadata with the persistence process managed by this
* <code>PersistenceManagerFactory</code>.
* Metadata can be created using the method {@link #newMetadata}.
* @param metadata The Metadata to register.
*/
public void registerMetadata(javax.jdo.metadata.JDOMetadata metadata) {
checkJDOPermission(JDOPermission.GET_METADATA);
MetaDataManager mmgr = nucleusContext.getMetaDataManager();
FileMetaData filemd = ((JDOMetadataImpl) metadata).getInternal();
// Check if already defined
for (int i = 0; i < filemd.getNoOfPackages(); i++) {
PackageMetaData pmd = filemd.getPackage(i);
for (int j = 0; j < pmd.getNoOfClasses(); j++) {
ClassMetaData cmd = pmd.getClass(j);
if (mmgr.hasMetaDataForClass(cmd.getFullClassName())) {
throw new JDOUserException("Cannot redefine metadata for " + cmd.getFullClassName());
}
}
for (int j = 0; j < pmd.getNoOfInterfaces(); j++) {
InterfaceMetaData imd = pmd.getInterface(j);
if (mmgr.hasMetaDataForClass(imd.getFullClassName())) {
throw new JDOUserException("Cannot redefine metadata for " + imd.getFullClassName());
}
}
}
mmgr.loadUserMetaData(filemd, null);
}
use of org.datanucleus.metadata.FileMetaData in project tests by datanucleus.
the class JDOTestBase method getEnhancedClassesFromFile.
/**
* Method to return a set of enhanced classes for all of those found in the specified JDO MetaData file.
* @param resourceName Name of the MetaData file (relative to the CLASSPATH).
* @return Set of enhanced classes
* @throws IllegalArgumentException if an error occurs reading the file resource
*/
public Class[] getEnhancedClassesFromFile(String resourceName) {
InputStream in = JDOTestBase.class.getClassLoader().getResourceAsStream(resourceName);
if (in == null) {
throw new IllegalArgumentException("Cannot load resource :" + resourceName);
}
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(in));
String buf = null;
while ((buf = br.readLine()) != null) {
sb.append(buf);
}
} catch (IOException e) {
throw new IllegalArgumentException("Error reading MetaData file " + resourceName + ": " + e.getMessage(), e);
} finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
String jdoXmlContents = sb.toString();
if (jdoXmlContents == null) {
throw new IllegalArgumentException("Contents of file is null");
}
NucleusContext context = new EnhancementNucleusContextImpl("JDO", null);
MetaDataManager mgr = new JDOMetaDataManager(context);
MetaDataParser parser = new MetaDataParser(mgr, context.getPluginManager(), true, true);
ClassLoaderResolverImpl clr = new ClassLoaderResolverImpl();
// Parse the MetaData
FileMetaData filemd = (FileMetaData) parser.parseMetaDataStream(new ByteArrayInputStream(jdoXmlContents.getBytes()), null, "JDO");
if (filemd == null) {
return null;
}
mgr.registerFile("EnhancerTestXMLFile", filemd, clr);
// Populate/Initialise the MetaData for the actual classes.
for (int i = 0; i < filemd.getNoOfPackages(); i++) {
PackageMetaData pmd = filemd.getPackage(i);
for (int j = 0; j < pmd.getNoOfClasses(); j++) {
ClassMetaData cmd = pmd.getClass(j);
cmd.populate(clr, null, mgr);
cmd.initialise(clr);
}
}
// Enhance the classes
TestClassLoader cl = new TestClassLoader();
Class[] result;
ArrayList<Class> resultList = new ArrayList<Class>();
for (int i = 0; i < filemd.getNoOfPackages(); i++) {
PackageMetaData pmd = filemd.getPackage(i);
for (int j = 0; j < pmd.getNoOfClasses(); j++) {
ClassMetaData cmd = (ClassMetaData) pmd.getClass(j);
// Enhance the class using the MetaData
ClassEnhancer enhancer = getClassEnhancer(cmd, mgr);
enhancer.enhance();
// Save the enhanced class
resultList.add(cl.getClass(cmd.getFullClassName(), enhancer.getClassBytes()));
}
}
result = (Class[]) resultList.toArray(new Class[resultList.size()]);
return result;
}
Aggregations