Begin by visiting the Downloads page and downloading a copy of DDMSence. The tutorials below will assume that you are working with the "bin"-flavored download, which comes with the DDMSence JAR files pre-compiled, and contains source code for the sample applications.
Unzip the downloaded archive in a directory of your choice. You can then run the samples from the command line by entering the commands below (or by pasting them into a batch/shell script and running that script):
REM Windows Commands cd <folderWhereDDMSenceIsUnzipped>\ddmsence-bin-2.1.0 set DDMSENCE_CLASSPATH=lib/saxon9he-22.214.171.124.jar;lib/xercesImpl-2.11.0.jar set DDMSENCE_CLASSPATH=%DDMSENCE_CLASSPATH%;lib/xml-apis-1.4.01.jar;lib/xom-1.2.8.jar set DDMSENCE_CLASSPATH=%DDMSENCE_CLASSPATH%;lib/ddmsence-2.1.0.jar set DDMSENCE_CLASSPATH=%DDMSENCE_CLASSPATH%;lib/ddmsence-samples-2.1.0.jar java -cp %DDMSENCE_CLASSPATH% buri.ddmsence.samples.Essentials
Figure 1. Running from a Windows/DOS Command Line
#!/bin/sh # Linux Commands cd <folderWhereDDMSenceIsUnzipped>/ddmsence-bin-2.1.0 ddmsence_classpath=lib/saxon9he-126.96.36.199.jar:lib/xercesImpl-2.11.0.jar ddmsence_classpath=$ddmsence_classpath:lib/xml-apis-1.4.01.jar:lib/xom-1.2.8.jar ddmsence_classpath=$ddmsence_classpath:lib/ddmsence-2.1.0.jar ddmsence_classpath=$ddmsence_classpath:lib/ddmsence-samples-2.1.0.jar java -cp $ddmsence_classpath buri.ddmsence.samples.Essentials
Figure 2. Running in Linux
Note: The syntax for setting a classpath in Linux may vary, depending on the shell you are using. If you are using an older version of DDMSence, make sure to change the version numbers in the classpath examples.
DDMSence comes with three sample applications. The intention of these applications is to highlight notable aspects of DDMSence, not to create real-world solutions.
Essentials is a simple reader application which loads an XML file containing a DDMS Resource and displays it in three different formats: the original XML, HTML, and Text. The source code for this application provides an example of how to create DDMS components from an XML file.
Escort is a step-by-step wizard for building a DDMS Resource from scratch, and then saving it to a file. The source code for this application shows an example of how the Java object model can be built with simple data types.
Escape is a tool that traverses multiple DDMS Resource files and then exposes various statistics about them through the Google Visualization API. Charts in this sample application are non-interactive, but provide the foundation for more complex cases: for example, it would be possible to plot Temporal Coverage on an Annotated Timeline, or Geospatial Coverage on Google Maps.
The overview page contains a quick reference chart of all implemented DDMS components. You should also be aware of the following sections, which appear on every DDMS component's page:
validate()method description lists the specific rules used to validate a component. This section may be useful when building your own components from scratch.
validateWarnings()method description lists the specific conditions that trigger a warning.
This section describes common use cases that are a good fit for the DDMSence library.
As the tutorials show, it is trivially easy for DDMSence to load a DDMS metacard from an XML file, examine its contents in a Java way, and display it as XML, HTML or Text. If you have a search web service which queries a catalog of DDMS metacards, DDMSence could be used to process those metacards individually, or gather statistics about the catalog as a whole. You could also use DDMSence to quickly validate a collection of DDMS metacards, simply by loading them into a DDMSReader.
There are two ways to create DDMS metacards from scratch in DDMSence. The first way makes use of standard Java constructors to build up each component and then group them together into a complete DDMS metacard. The second way uses the Component Builder framework to model a top-down construction of a metacard, and provides more flexibility of implementation. The latter approach follows the pattern of a step-by-step wizard that builds the metacard over several steps, and then commits and validates the metacard at the very end.
The Component Builder framework also allows you to load an existing metacard, make changes to it, and then revalidate it. It might also be used to programmatically update or correct errors in a collection of DDMS metacards. For example, if your assets have moved to a different web server, you could programmatically update all of your DDMS Identifiers to point to the new location. Alternately, you could change all occurences of a producer's last name after a marriage.
As a specialized example of editing, you could transform older metacards to the latest version of DDMS. With the Component Builder framework, you could load a DDMS 2.0 metacard, add all of the fields required for DDMS 4.1, and then save it as a DDMS 4.1 metacard. Example code for this use case can be found in the Component Builder Power Tip.
In many cases, schema validation is not sufficient to truly show conformance. The Intelligence Community codifies constraints on ISM attributes with a set of Schematron files. DDMSence requires just a few lines of code to validate your DDMS metacards against these Schematron files. You could also validate against Schematron files developed by your Community of Interest. Additional details can be found in the Schematron Validation Power Tip.
This section identifies a few basic design principles of DDMSence which might affect you as incorporate it into your own projects.
Not all of the elements defined in the DDMS schema are implemented as Java Objects. Many elements are defined globally but only used once, or exist merely as wrappers for other components. I have followed these rules to determine which components are important enough to deserve a full-fledged Object:
xs:string-based components, DDMSence treats the absence of some element/attribute in the same manner as it would treat that element/attribute if it were
present but had an empty string as a value. The DDMS schema generally uses
xs:string without length restrictions, so an empty string is syntactically correct, even if the
resulting data is not logical. To provide some consistency in this library, I have tried to follow these rules:
nullentity. This means that a missing element and an element with no value in an XML file are treated identically.
In some instances, the DDMS specification supports multiple string values, either by multiple elements (
ddms:name elements on a
or by supporting the
xsd:list datatype (the
ISM:ownerProducer security attribute). The accessor methods for these fields in DDMSence will always deal with
a List of String values, rather than a space-separated String containing multiple values. However, because list management can be tedious, there is a shortcut utility method available:
// These two approaches to generating ownerProducers are equivalent. List<String> ownerProducers = new ArrayList<String>(); ownerProducers.add("AUS"); ownerProducers.add("USA"); List<String> ownerProducers = Util.getXsListAsList("AUS USA");
Figure 3. Conveniently creating a list of Strings from a space-delimited String
All DDMS components are implemented as immutable objects, which means that their values cannot be changed after instantiation. Because the components are validated during instantiation, this also means that it is impossible to have an invalid component at any given time: a component is either confirmed to be valid or does not exist. The Component Builder framework can be used to build DDMS Resources piece by piece, saving validation until the end.
Because DDMS components are built in single-step constructors to support immutability, parameter lists can sometimes exceed more than a handful of information. The following convention is used to provide some consistency:
Other than the immutability of objects, no special effort went into making DDMSence thread-safe, and no testing was done on its behavior in multithreaded environments.
Some non-string-based attributes, such as
ISM:resouceElement do not appear in earlier versions of DDMS. When the accessors for
these attributes are called on an older version, a null value will be returned. This decision allows DDMS records of varying versions to be
traversed and queried in the same manner, without requiring too much knowledge of when specific attributes were introduced.
Power Tips provide instructions and sample code to maximize the benefits of DDMSence, once you are comfortable with the basics of the library.
This section contains links to DDMS-related research and personal experimentation which may be useful to DDMSence in the future.
DDMSence is a benevolent dictatorship -- I am the sole committer on the project for the forseeable future. However, I welcome any suggestions you might have on ways to improve the project or correct deficiencies!
The source code for DDMSence can be found in the "src"-flavored download on the Downloads page. If you are interested in viewing the latest (unreleased and possibly unstable) source code, you can download it with any Subversion client:
svn checkout http://ddmsence.googlecode.com/svn/trunk/ ddmsence-read-only
An Atom feed of SVN commits is also available -- there are no email notifications at this time.
I would love to hear about your experiences working with DDMSence, or suggestions for future functionality. Did you find it to be useful? Are there requirements that I should consider supporting? Is the documentation clear and complete?
You can officially report a bug or enhancement suggestion on the Issue Tracking page, or use the Discussion area as a less formal method of discussion. Finally, you can contact me directly by email at