Table of Contents

Getting Started

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.6.0
set DDMSENCE_CLASSPATH=lib/saxon9he-;lib/xercesImpl-2.11.0.jar
set DDMSENCE_CLASSPATH=%DDMSENCE_CLASSPATH%;lib/xml-apis-1.4.01.jar;lib/xom-1.2.10.jar
set DDMSENCE_CLASSPATH=%DDMSENCE_CLASSPATH%;lib/ddmsence-samples-2.6.0.jar
java -cp %DDMSENCE_CLASSPATH% buri.ddmsence.samples.Essentials

Figure 1. Running from a Windows/DOS Command Line

# Linux Commands
cd <folderWhereDDMSenceIsUnzipped>/ddmsence-bin-2.6.0
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.

Sample Applications

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 four different formats: the original XML, HTML, Text, and JSON. 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.

JavaDoc API Documentation

The API documentation is also bundled with the "bin"-flavored download on the Downloads page, and can be generated from source code in the "src"-flavored download. Classes which represent DDMS elements are grouped into packages based on which of the five core sets they belong to. In some cases, packages are further divided to identify any components which originate from other XML namespaces, such as GML or XLink. If a component is reused across multiple sets, it will be found in the package of the set where it was first introduced.

The overview page contains a quick reference chart of all implemented DDMS components. Drill down to a specific component class to find the following information in a standard format:

Suggested Use Cases

This section describes common use cases that are a good fit for the DDMSence library. The term, "metacard", refers to DDMS 2.0 through 4.1 resources. The term, "assertion", refers to DDMS 5.0 resources. For the purposes of these use cases, the terms are interchangeable.

Reading existing metacards

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.

Creating new metacards

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.

Editing or transforming existing metacards

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 5.0, and then save it as a DDMS 5.0 assertion. Example code for this use case can be found in the Component Builder Power Tip.

Applying custom constraints with Schematron

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.

Design Decisions

This section identifies a few basic design principles of DDMSence which might affect you as incorporate it into your own projects.

Components Deserving an Object

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:


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.

Empty String vs. No Value

When analyzing 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. A string-based accessor will always return an empty string instead of a null entity.

Accessor Consistency Across Versions

Some non-string-based attributes, such as ism:excludeFromRollup and ism:resouceElement do not appear in all 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.

Lists of Strings

In some instances, the DDMS specification supports multiple string values, either by multiple elements (ddms:name elements on a ddms:person) 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>();

List<String> ownerProducers = Util.getXsListAsList("AUS USA");

Figure 3. Conveniently creating a list of Strings from a space-delimited String

Power Tips

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 ddmsence-read-only


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