Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

org.greenstone.gatherer.msm
Class GDMManager  view GDMManager download GDMManager.java

java.lang.Object
  extended byjava.util.AbstractMap
      extended byjava.util.HashMap
          extended byjava.util.LinkedHashMap
              extended byorg.greenstone.gatherer.msm.GDMManager
All Implemented Interfaces:
java.lang.Cloneable, java.util.Map, MSMListener, java.io.Serializable

public class GDMManager
extends java.util.LinkedHashMap
implements MSMListener

This object manages the metadata attached to file records. By storing all of the metadata in one place you garner several advantages. Firstly only one copy of each metadata object is retained, all actual entries are converted to references. Next you can immediately determine what metadata is assigned to an entire directory, thus the metadata.xml files can be built more effeciently (whereas the current 'optimal' method uses recursion through the tree contents). Finally, and perhaps most importantly, it allows for dynamic 'on demand' lookup of metadata. This is especially necessary with large collections, where the raw, unconnected metadata files could range into the tens of megabytes of memory and require hundreds of megabytes to read by in using serialization. Dynamic loading allows you to connect the metadata objects on load, reducing value node paths (possibly of hundreds of characters) down to a single reference pointer! At the very worst this object uses far less memory than the current method, and given that the current method is completely incapable of handling large collections, is necessary. The trade off of course is in time needed to load metadata.xml on demand, the worst possible case being the user selecting the root node of the collection tree of a large collection immediately after opening the collection. The subsequent attempt to build the metadata table will result in the metadata being loaded for every single file. But since this process is sequential and a small cache of metadata.xml files is implemented, and given that the table will actually be build on a separate thread, the wait should not be too arduous.
As for the size of the GDMParser cache, I was at first tempted to put around five. However after analysis of cache usage, I determined that no gain occured because of caching (in fact if everythings working as it should there should only ever be one call for a certain metadata.xml).


Nested Class Summary
private  class GDMManager.MetadataXMLFileSearch
           
 
Nested classes inherited from class java.util.LinkedHashMap
 
Nested classes inherited from class java.util.HashMap
 
Nested classes inherited from class java.util.AbstractMap
 
Nested classes inherited from class java.util.Map
java.util.Map.Entry
 
Field Summary
private static int MAX_DOCUMENTS
          The maximum number of GDMDocuments to load at any one time
static org.greenstone.gatherer.util.HashMap3D metadata_cache
          A list of the known metadata instances, thus we only store one of each unique metadata, and reference the rest.
private  javax.swing.tree.TreeNode root
          The root file node.
 
Fields inherited from class java.util.LinkedHashMap
 
Fields inherited from class java.util.HashMap
 
Fields inherited from class java.util.AbstractMap
 
Constructor Summary
GDMManager()
          Constructor.
 
Method Summary
 void addMetadata(org.greenstone.gatherer.file.FileNode node, java.util.ArrayList metadatum)
          This may seem a little odd but this method doesn't add the given metadata directly, instead calling fireMetadataChanged in MetadataSetManager so as to recursively add metadata if necessary, and to ensure that all listeners who are interested in data change (such as the Metadata Table and Save listeners) can be up to date.
private  Metadata checkCache(Metadata metadata)
           
 void destroy()
          Destructor necessary for clean exit, subsequent to saving of metadata.xml files.
 void elementChanged(MSMEvent event)
          Method that is called whenever an element within a set is changed or modified.
 java.util.ArrayList getAllMetadata(java.io.File file)
           
 GDMDocument getDocument(java.io.File file)
          Retrieve the GreenstoneMetadataDocument that is associated with a certain file.
 java.util.ArrayList getMetadata(java.io.File file)
          Recover the metadata associated with a particular file.
private  java.util.ArrayList getMetadata(java.io.File file, boolean remove, boolean append_folder_level)
           
 java.util.ArrayList getMetadata(java.io.File file, ElementWrapper element)
           
 java.util.ArrayList getMetadataOnly(java.io.File file)
          Recover the metadata associated with a particular file excluding folder level metadata.
 void metadataChanged(MSMEvent event)
          Called whenever the metadata value changes in some way, such as the addition of a new value.
protected  boolean removeEldestEntry(java.util.Map.Entry eldest)
          A separately threaded class to load all of the current metadata.xml files.
 java.util.ArrayList removeMetadata(java.io.File file)
           
 void save()
          Causes all currently loaded GDMDocuments to write themselves out.
 void save(java.io.File file, GDMDocument document)
          Write out the latest copy of a certain document.
 void save(org.greenstone.gatherer.file.FileNode node)
          Used to cause the document associated with a particular file to write the latest copy of itself to disk.
 void setChanged(MSMEvent event)
          Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets.
 java.lang.String toString(java.util.ArrayList list)
           
 void valueChanged(MSMEvent event)
          Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value.
 void waitUntilComplete()
           
 
Methods inherited from class java.util.LinkedHashMap
clear, containsValue, get
 
Methods inherited from class java.util.HashMap
clone, containsKey, entrySet, isEmpty, keySet, put, putAll, remove, size, values
 
Methods inherited from class java.util.AbstractMap
equals, hashCode, toString
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.util.Map
equals, hashCode
 

Field Detail

metadata_cache

public static org.greenstone.gatherer.util.HashMap3D metadata_cache
A list of the known metadata instances, thus we only store one of each unique metadata, and reference the rest.


root

private javax.swing.tree.TreeNode root
The root file node.


MAX_DOCUMENTS

private static final int MAX_DOCUMENTS
The maximum number of GDMDocuments to load at any one time

See Also:
Constant Field Values
Constructor Detail

GDMManager

public GDMManager()
Constructor.

Method Detail

addMetadata

public void addMetadata(org.greenstone.gatherer.file.FileNode node,
                        java.util.ArrayList metadatum)
This may seem a little odd but this method doesn't add the given metadata directly, instead calling fireMetadataChanged in MetadataSetManager so as to recursively add metadata if necessary, and to ensure that all listeners who are interested in data change (such as the Metadata Table and Save listeners) can be up to date.


destroy

public void destroy()
Destructor necessary for clean exit, subsequent to saving of metadata.xml files.


elementChanged

public void elementChanged(MSMEvent event)
Method that is called whenever an element within a set is changed or modified. Ensure all cached GDMDocuments are marked as stale.

Specified by:
elementChanged in interface MSMListener

getDocument

public GDMDocument getDocument(java.io.File file)
Retrieve the GreenstoneMetadataDocument that is associated with a certain file. If the document is in cache returns it. If the document exists but isn't in cache loads, caches, then returns it. Otherwise it creates a brand new document, caches it, then returns it.


getMetadata

public java.util.ArrayList getMetadata(java.io.File file)
Recover the metadata associated with a particular file. Note that this call is synchronized, so that all of the data holders don't need to be.


getMetadataOnly

public java.util.ArrayList getMetadataOnly(java.io.File file)
Recover the metadata associated with a particular file excluding folder level metadata. Note that this call is synchronized, so that all of the data holders don't need to be.


getMetadata

public java.util.ArrayList getMetadata(java.io.File file,
                                       ElementWrapper element)

getMetadata

private java.util.ArrayList getMetadata(java.io.File file,
                                        boolean remove,
                                        boolean append_folder_level)

getAllMetadata

public java.util.ArrayList getAllMetadata(java.io.File file)

toString

public java.lang.String toString(java.util.ArrayList list)

metadataChanged

public void metadataChanged(MSMEvent event)
Called whenever the metadata value changes in some way, such as the addition of a new value. This is the only event type we care about, but we care about it a lot. It tells us what metadata to add, remove, etc from the cached metadata.xml files. Note that this method is synchronized so that the data objects don't need to be.

Specified by:
metadataChanged in interface MSMListener

removeMetadata

public java.util.ArrayList removeMetadata(java.io.File file)

save

public void save()
Causes all currently loaded GDMDocuments to write themselves out.


save

public void save(org.greenstone.gatherer.file.FileNode node)
Used to cause the document associated with a particular file to write the latest copy of itself to disk.


save

public void save(java.io.File file,
                 GDMDocument document)
Write out the latest copy of a certain document.


setChanged

public void setChanged(MSMEvent event)
Method that is called whenever the metadata set collection changes in some way, such as the addition of a new set or the merging of two sets. If a set changes, mark all cached GDMDocuments as being stale.

Specified by:
setChanged in interface MSMListener

valueChanged

public void valueChanged(MSMEvent event)
Called whenever the value tree of an metadata element changes in some way, such as the addition of a new value. --While the comments below are now obsolete, I'll keep them just to remind me of how easy it is to back yourself into a corner with issues such as caching and persisitant references--. Such an action would require us to painstakingly reload every metadata.xml file using the value model prior to the change, then painstakingly write out each metadata.xml file again using the modified model, but I'm a glutton for punishment so thats ok. The alternative is to not do this and watch in horror as heirarchy references quickly fall into disarray, pointing to the wrong place. This task gets even more complicated by three facts:
1. We want to do this is a seperate thread, as we don't want the program to come to a screaming halt while we're updating metadata.xml files.
2. We have to prevent any metadata.xml files being removed from cache while we're doing this, as if we encounter these more recently written files their heirarchy references will already be correct and that will balls up our little process. Note that this means the saving process may have to block while pending metadata heirarchy updates are in progress.
3. Regarding (2) we don't have to rewrite any metadata.xml files already in cache as they will be correctly written out whenever they happen to be dumped from cache.
4. We need the ability to pre-empt the general update to load a user demanded metadata.xml and store it in cache, using the old value tree model as per usual, and
5. We have to store a cue of these events, and process them one at a time. Perhaps one day when I'm feeling masacistic I'll figure out someway to merge several updates into one, but for now we have to change the tree one node at a time in order for references to remain correct.
Ok, so thats five facts, but you get the gist. Not an easy task, but crucial for accurate storage and recall of metadata heirarchies.

Specified by:
valueChanged in interface MSMListener

waitUntilComplete

public void waitUntilComplete()

checkCache

private Metadata checkCache(Metadata metadata)

removeEldestEntry

protected boolean removeEldestEntry(java.util.Map.Entry eldest)
A separately threaded class to load all of the current metadata.xml files. Note that files can still be loaded on demand if they're not already in the cache. Also provides the functionality to block any other thread until the loading is complete, such as is necessary when moving values about in the value tree hierarchy.