| Overview | Package | Class | Tree | Deprecated | Index | Help | |||
| PREV CLASS | NEXT CLASS | FRAMES | NO FRAMES | ||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||
java.lang.Object
|
+--java.util.Dictionary
|
+--java.util.Hashtable
|
+--ncsa.horizon.util.Metadata
Within the Horizon package, Metadata objects hold data that describe other data. For example, image data sets can have metadata associated with them that can describe things like the number of dimensions it has, the origin of the data, etc; this can information can usually be accessed through Viewable method, getMetadata(). CoordinateSystem objects also have metadata associated with them that provide the parameters that describe the system.
Users of this class should remember that metadata have an assumed type that is implicitly agreed upon by all classes that access it. For example, classes in ncsa.horizon.coordinates package assume that the metadatum named "naxes" to be of type Integer. If a class finds that a metadatum has an unexpected type, the class may throw a MetadataTypeException. (See CoordMetadata for more details about coordinate-related metadata.)
The only pre-defined metadata names are "schema" and "schemaVersion". The "schema" metadatum is a String that identifies the set of metadata names in use by this Metadata object, along with the types and logical meaning of those names. The "schemaVersion" is also a String to identify the version of the schema.
Accessing Hierarchical Metadata
Each piece of Metadata can be accessed through its name (often referred to as its keyword), represented as a String, using the getMetadatum(String) method. A metadatum value is set using the put method (from the super-class, Hashtable).
Special support is provided for hierarchical metadata. For example, a Metadata object can contain another Metadata object. It can also contain one or more Metavector objects, each one containing an array of metadata of the same type. The Metadata class supports this notion by allowing one to request "sub-metadata" directly with the getMetadatum(String key) method. If the key string contains a period ("."), the substring to the left of the period is taken to be the name of a metadatum of type Metadata; the substring to the left of the period is taken to be the name of a metadatum contained within that metadata object. For example, the following code,
Metadata md;
...
Metadata cmd = (Metadata) md.getMetadatum("coordinates");
String name = (String) cmd.getMetadatum("name");
is equivalent to:
String name = (String) md.getMetadatum("coordinates.name")
In fact, the latter is actually safer and more efficient.
Similarly, if a Metadata object contains a Metavector object as one of
its items, one can access an element of the Metavector by appending
"[n]" to the name of the Metavector, where
n is an integer specifying the desired array index. For example,
Object element = md.getMetadatum("Axes[1]");
returns the object at index 1 (the second element) of the Metavector
called "Axes". Use the "sub-metadata" syntax, one can directly access hierarhical metadata of arbitrary depth. For example, the following is the most efficient way (in terms of memory and time) of access the specified sub-metadatum:
String name = (String) md.getMetadatum("coordinates.Axes[1].name");
Note that one cannot use the "sub-metadata" syntax to update hierarchical metadata.
Default Metadata
Metadata objects can store two sets of data within themselves: primary data and default data. Calls to getMetadatum(String) will return requested data from the primary set; if it does not exist there, the value in the default searched for a value. (To prevent search of the default set, one should call getMetadatum(String, null).) The default data can only be set during construction. Primary data may be updated via the put and copyMetadata(Metadata) methods. The internally stored default metadata provides a way for managers of metadata to protect their data from updates by other objects. If a metadata manager has a Metadata it wants other objects to read from but not write into, it can create a new Metadata object that has the original as the default. The other users of the new Metadata can then read the elements and even override them without affecting the original Metadata object.
One other feature of the support for default values is that it allows the originator of Metadata (the object that has a reference to the default Metadata) to update the defaults after the Metadata has been created and passed on. Such changes would be seen by those objects that have not overriden the defaults. Client objects that prefer that their copy of the Metadata not be connected the originator in this way can "detach" it via the detach() method. Other methods are provided for obtaining "detached" copies of the data, detachedClone(), and cloneDefaults(). (Note that the standard clone() produces a Metavector whose defaults are "attached" to the same object as the original.)
One should note that the defaults protection only applies to the internal default Metadata container itself, not its elements. That is, the value returned by getMetadatum(String) is the original version of the datum and not a copy. Thus, there may be any number of references to the datum held by other objects. (The datum is protected only if it is of a type that is not internally editable. For example, the value of an Integer or String object cannot be updated; however, if the datum is of type Stack, the data internal to that Stack is not protected from updates.) An exception to this is when the value is obtained from the default list and is of type Metavector or Metadata; in this case, the meta-container is placed as the default list in a new meta-container before being passed on.
Dynamic Metadata Loading
Some metadata may be costly to load into memory, for example, if it needs to be downloaded from the network or it requires an expensive computation. The effort to load the data into a Metadata object may be wasted if the user never requests the data. The Metadata class provides a mechanism for one to store procedures, in the form of Metarunner objects, for obtaining metadata. When a user requests a metadatum object for which there exists a Metarunner object, the Metarunner is executed and the resulting value is returned to the user as well as loaded into the hashtable for future requests.
To make use of this capability, programmers should sub-class the Metarunner class, overridding the getDatum() method. The Metarunner object is then stored in the Metadata object using the name of metadatum appended with the String Metadata.METARUNNER_TAG. When the user later requests a named metadatum, the Metadata object first looks for a static value in its hashtable. If it does not exist, then the Metadata object looks for a Metarunner object that can obtain the value. Failing that, the default list is consulted (which might also engage a Metarunner object). If the Metarunner does exist and successfully returns a value, the value is stored in the primary hastable as a static value.
Support for Metarunner objects is meant by default to be transparent; the user is given some explicit control and access to the objects. To prevent the execution, one can set the public boolean field, executeRunners to false. The getRunnerNames() method returns the names of metadata (without the METARUNNER_TAG appended) that have Metarunners associated with them. In contrast, the MetadatumNames() returns the only the names for which there currently exists static values (including the modified names pointing to Metarunner objects). Since the latter method is expected to be used to step through each metadata value (say to copy it to another container), this behavior prevents the unintended execution of costly Metarunners.
| Field Summary | |
| Metadata | defaults
the default Metadata values |
| boolean | executeRunners
true if Runnable objects should be executed to obtain values for requested metadata when available. |
| static java.lang.String | METARUNNER_TAG
the suffix to be appended to a metadatum name to refer to a Metarunnable object that can fetch the value of that metadatum. |
| static java.lang.String | schema
|
| static java.lang.String | schemaVersion
|
| Constructor Summary | |
| Metadata()
Creates an empty metadatum list. |
|
| Metadata(Metadata defaults)
Creates an empty metadatum list with specified defaults. |
|
| Metadata(int initialCapacity)
Creates an empty metadatum list with an initial capacity |
|
| Metadata(int initialCapacity,
Metadata defaults)
Creates an empty metadatum list with an initial capacity and specified defaults. |
|
| Method Summary | |
| Metadata | cloneDefaults()
clone the defaults metadata. |
| java.lang.Object | clone()
Clones this metadata object. |
| void | copyMetadata(java.util.Hashtable from)
Copy all the data from a Hashtable whose keys are of type String into the primary data list. |
| void | copyMetadata(Metadata from)
Copy all the data from another Metadata object into the primary data list. |
| Metadata | deepClone()
create a semi-deep clone. |
| Metadata | detachedClone()
Like clone(), except that a copy of the defaults metadata is also made. |
| void | detach()
replace the internal default Metadata with a copy (via deepClone()), detaching control of the defaults from the originator of this Metadata. |
| java.lang.Object | fetchDatum(java.lang.String key,
Metarunner fetcher)
Execute a Metarunner that fetches the value of a specifed key and stores the result into this Metadata list |
| java.lang.Object | fetchMetadatum(java.lang.String key)
execute the runner (if it exists and is accessible) for the specified key, and return its value. |
| Metadata | getDefaults()
return a new Metadata object with the same default data but with no primary data |
| java.lang.Object | getMetadatum(java.lang.String key)
Gets a metadatum with the specified key. |
| java.lang.Object | getMetadatum(java.lang.String key,
boolean doRun)
Gets a metadatum with the specified key. |
| java.lang.Object | getMetadatum(java.lang.String key,
java.lang.Object defaultValue)
Gets a metadatum with the specified key and default. |
| java.lang.Object | getMetadatum(java.lang.String key,
java.lang.Object defaultValue,
boolean doRun)
Gets a metadatum with the specified key and default. |
| java.util.Enumeration | getRunnerNames()
Enumerate the keys having Metarunner objects associated with them |
| void | giveDefaults(Metadata to)
Copy the default metadata of this Metadata object to the defaults of another Metadata object. |
| java.util.Enumeration | metadatumNames()
Enumerates all the keys. |
| java.lang.Object | put(java.lang.Object key,
java.lang.Object value)
This method overrides the method put in Hashtable. |
| void | removeAllMetadata()
remove the primary key/value pairs from this Metadata object, leaving the defaults. |
| void | setDefaults(Metadata to)
Set the default Metadata of this Metadata object. |
| void | setSchema(java.lang.String in)
set the name of the schema used by this Metadata object |
| void | setSchemaVersion(java.lang.String in)
set the version of the schema used by this Metadata object |
| java.lang.String | toString()
attempt to convert contents to a multi-line String (useful for debugging |
| Methods inherited from class java.util.Hashtable | |
| clear, clone, contains, containsKey, containsValue, elements, entrySet, equals, get, hashCode, isEmpty, keySet, keys, putAll, put, rehash, remove, size, toString, values | |
| Methods inherited from class java.util.Dictionary | |
| elements, get, isEmpty, keys, put, remove, size | |
| Methods inherited from class java.lang.Object | |
| clone, equals, finalize, getClass, hashCode, notifyAll, notify, toString, wait, wait, wait | |
| Field Detail |
public static final java.lang.String schema
public static final java.lang.String schemaVersion
public static final java.lang.String METARUNNER_TAG
protected Metadata defaults
public boolean executeRunners
| Constructor Detail |
public Metadata()
public Metadata(Metadata defaults)
defaults
- the defaultspublic Metadata(int initialCapacity)
public Metadata(int initialCapacity,
Metadata defaults)
| Method Detail |
public void setSchema(java.lang.String in)
public void setSchemaVersion(java.lang.String in)
public java.lang.Object getMetadatum(java.lang.String key)
key
- the metadatum name
public java.lang.Object getMetadatum(java.lang.String key,
boolean doRun)
key
- the metadatum name
doRun
- if true, a Runnable object should be executed to
obtain the requested value when available; overrides
the value of executeRunners
public java.lang.Object getMetadatum(java.lang.String key,
java.lang.Object defaultValue)
public java.lang.Object getMetadatum(java.lang.String key,
java.lang.Object defaultValue,
boolean doRun)
protected java.lang.Object fetchDatum(java.lang.String key,
Metarunner fetcher)
key
- name of metadatum that the Metarunner will fetch.
fetcher
- the Metarunner object to executepublic java.util.Enumeration getRunnerNames()
public java.lang.Object fetchMetadatum(java.lang.String key)
public void copyMetadata(java.util.Hashtable from)
public void copyMetadata(Metadata from)
public void setDefaults(Metadata to)
public Metadata getDefaults()
public final void detach()
public void giveDefaults(Metadata to)
to
- the other Metadata object to copy defaults topublic void removeAllMetadata()
public java.util.Enumeration metadatumNames()
public java.lang.String toString()
public java.lang.Object clone()
public Metadata detachedClone()
public Metadata cloneDefaults()
public Metadata deepClone()
public java.lang.Object put(java.lang.Object key,
java.lang.Object value)
| Overview | Package | Class | Tree | Deprecated | Index | Help | |||
| PREV CLASS | NEXT CLASS | FRAMES | NO FRAMES | ||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||