Note: This Power Tip only applies to DDMS 2.0 through 4.1. DDMS 5.0 no longer has an Extensible Layer, and extensions are stored elsewhere in the IC Trusted Data Format (TDF).
DDMS is composed of five Core Sets (Metacard Info, Security, Resource, Summary Content, and Format) and the Extensible Layer. This layer supports extensibility
by providing space for custom attributes and elements within a ddms:resource
. Specifically, custom attributes can be added to any producer
(Organization, Person, Service, and Unknown), a Keyword, a Category, and the Resource itself. A Resource can also have an unlimited number of custom
elements after the ddms:security
element. These extensions are identified by the xs:any
and xs:anyAttribute
definitions in the schema. The main restriction on content is that custom elements and attributes must belong to an XML namespace other than the
DDMS namespace.
Because any manner of content could appear in the Extensible Layer, DDMSence merely provides a consistent interface to access to the underlying XOM Elements and Attributes. Any business logic to be performed on this Layer is left up to the implementation, so some knowledge of XOM will be useful.
The relevant code can be found in the buri.ddmsence.ddms.extensible
package. It may also be useful to load the sample file,
3.0-extensibleLayerExample.xml
into the Essentials application, because it has an example of each extension.
Starting in DDMSence 2.6.0, you can register additional XML namespaces and associated external schemas in the DDMSReader so that custom content in the Extensible Layer can be validated against third-party schemas. Only XML namespaces that are not already known to the DDMSReader can be registered. It is not possible to overwrite the core DDMS schemas with this approach.
DDMSReader reader = new DDMSReader(DDMSVersion.getVersionFor("2.0")); reader.addExternalSchemaLocation("http://xmlNamespace.for.extensible.content/", "extensibleSchema.xsd"); System.out.println(reader.getExternalSchemaLocations()); Resource resource = reader.getDDMSResource(new FileReader(new File("metacardWithExtensibleLayer.xml"));
Figure 7. Registering additional schemas in a DDMSReader instance
An unlimited number of elements from any XML namespace other than the DDMS namespace can appear at the end of a ddms:resource
. (In DDMS 2.0,
only 1 can appear). These elements are implemented with the ExtensibleElement class,
which acts like any other IDDMSComponent and exposes getXOMElementCopy()
to return a copy of the underlying XOM Element. Below is an
example of an extensible element as it might appear in an XML file.
[...] </ddms:subjectCoverage> <ddms:security ISM:ownerProducer="USA" ISM:classification="U" ISM:excludeFromRollup="true"/> <ddmsence:extension xmlns:ddmsence="https://ddmsence.urizone.net/"> This is an extensible element. </ddmsence:extension> </ddms:resource>
Figure 1. An extensible element as it would appear in a ddms:resource
Unlike most DDMS components, which have a constructor for XOM elements and a constructor for raw data, ExtensibleElement only has one constructor
(since the raw data is, itself, a XOM element). If you are using a DDMSReader instance to load data from an XML file, the ExtensibleElements will be created automatically,
and can be accessed with Resource.getExtensibleElements()
. Here is an example of how you might build a simple one from scratch:
Element element = new Element("ddmsence:extension", "https://ddmsence.urizone.net/"); element.appendChild("This is an extensible element."); ExtensibleElement component = new ExtensibleElement(element);
Figure 2. Creating a simple ExtensibleElement from scratch
Once you have an ExtensibleElement, you can add it to a list of top-level components (like any other IDDMSComponent), and pass it into a Resource constructor. Creating more complex Elements from scratch requires XOM knowledge, and is outside the scope of this documentation.
The ExtensibleAttributes class follows the same implementation
pattern as SecurityAttributes and SRSAttributes. The accessor, getAttributes()
will return a read-only list of all the underlying XOM Attributes.
Below is an example of an extensible attribute as it might appear in an XML file, and how it could be created from scratch:
<ddms:keyword xmlns:ddmsence="https://ddmsence.urizone.net/" ddms:value="XML" ddmsence:relevance="99" />
Figure 3. An XML element with extensible attributes
List<Attribute> extAttributes = new ArrayList<Attribute>(); extAttributes.add(new Attribute("ddmsence:relevance", "https://ddmsence.urizone.net/", "99")); ExtensibleAttributes extensions = new ExtensibleAttributes(extAttributes); Keyword keyword = new Keyword("XML", extensions);
Figure 4. Creating the extensible attribute from scratch
The ddms:resource
element has additional (ISM) attributes that might conflict with your extensible
attributes. The situation is trickier in DDMS 2.0, where the ISM attributes are not explicitly defined in the schema, but can exist nonetheless because
of the leeway provided with xs:anyAttribute
.
When creating an ExtensibleAttributes instance based upon a ddms:resource
XOM Element:
ISM:DESVersion
will be "claimed", if present.ISM:noticeType
will be converted into a NoticeAttributes instance.ISM:classification
will be converted into a SecurityAttributes instance.When building an ExtensibleAttributes instance from scratch and placing it on a Resource:
ISM:DESVersion
are processed first, if present.ISM:noticeType
are processed.ISM:classification
are processed.In DDMS 2.0, it is perfectly legal to implement one of the resource attributes or security attributes as an extensible attribute:
DDMSVersion.setCurrentVersion("2.0"); // DESVersion as a resource attribute Resource resource1 = new Resource(myComponents, null, null, new Integer(2), null); // DESVersion as an extensible attribute String icNamespace = DDMSVersion.getCurrentVersion().getIcismNamespace(); List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("ISM:DESVersion", icNamespace, "2")); ExtensibleAttributes extensions = new ExtensibleAttributes(attributes); Resource resource2 = new Resource(myComponents, null, null, null, null, extensions);
Figure 5. These two approaches for a resource attribute are both legal in DDMS 2.0
DDMSVersion.setCurrentVersion("2.0"); // classification and ownerProducer as security attributes List<String> ownerProducers = new ArrayList<String>(); ownerProducers.add("USA"); SecurityAttributes secAttributes = new SecurityAttributes("U", ownerProducers, null); Resource resource = new Resource(myComponents, null, null, null, secAttributes); // classification and ownerProducer as extensible attributes String icNamespace = DDMSVersion.getCurrentVersion().getIcismNamespace(); List<Attribute> attributes = new ArrayList<Attribute>(); attributes.add(new Attribute("ISM:classification", icNamespace, "U")); attributes.add(new Attribute("ISM:ownerProducer", icNamespace, "USA")); ExtensibleAttributes extensions = new ExtensibleAttributes(attributes); Resource resource = new Resource(myComponents, null, null, null, null, extensions);
Figure 6. These two approaches for security attributes are both legal in DDMS 2.0
As a best practice, it is recommended that you create these attributes as explicitly as possible: if an attribute can be defined with constructor parameters or inside of a SecurityAttributes instance, it should. This will make DDMS 2.0 metacards more consistent with their newer counterparts.
Starting with DDMS 4.0.1, ddms:keyword
and ddms:category
can have both extensible and security attributes, just like a Resource. The same guidelines apply in this
situation -- define your security attributes as explicitly as possible to avoid confusion.