The previous sections have extensively used the CND notation to illustrate the examples. Now that the most important concepts have been demonstrated, this section will give an in-depth overview of the CND. JSR 283 further defines an XML-based format for defining node type definitions, however, it has not been finalized yet at the time of writing. A CND file contains a series of namespace declarations, node type definitions, as well as comments which are denoted with a double slash (//).

The prefix and URI of a namespace need to be defined for custom as well as built-in namespaces used in the CND file:

// syntax

// custom namespace

// map built-in namespace to jcr prefix

The syntax of node type definitions seems peculiar at first, but proves to be quite easy and powerful once understood. A node type including advanced options and properties can essentially be defined in one line. The type itself, prefixed by the namespace prefix, is specified within square brackets, followed by a “>” sign and supertypes and mixins it inherits from. Notice that the JCR allows for multiple inheritance, i.e. it provides the possibility to inherit from any number of parent node types. However, certain implementations may not provide this feature.

Node Type Declaration

All node definitions must contains a supertype, such as nt:base, the root node type.

In a JSR 283 compliant repository, if no supertype is specified, a new nodetype automatically inherits from the abstract base type nt:base.

// defines the new node type formattedText in the samples namespace
// which inherits from samples:contentModule

[samples:formattedText] > samples:contentModule, mix:versionable

The declaration is then followed by a number of options:

Option

Summary

abstract*

Denotes an abstract node type, i.e. a type that cannot be directly instantiated.

orderable

When this keyword is present, the child nodes of this node type become orderable, meaning the sequence in which they are inserted is maintained when they are retrieved via the API call Node.getNodes.

If it is not present, the ordering is either random or implementation specific.

mixin

When present, this keyword defines the node type to be a mixin. When missing, the node type is automatically defined to be a primary node type.

JSR283 *Denotes JSR-283 specific properties

// defines the new node type formattedText in the samples namespace
// which inherits from samples:contentModule

[samples:formattedText] > samples:contentModule, mix:versionable

// followed by options

abstract

orderable

mixin

Property Declaration

The next section of the CND defines the properties of a node type. Note that these properties are defined in addition to those already inherited from any base node types and mixin types. Node type definitions cannot over overwritten, i.e. declaring a node type by a name which already exists in a super type will lead to an error.

A property definition is marked by a leading “-” (minus) followed by the property name, type, default values, attributes, and value constraints.

// property declaration of namespace, propertyname and the property
// type in brackets

- samples:name (String) 

// followed by default values, denoted by a “=” (equals) sign,
// as a comma separated list (for multi-valued properties)

= "default value 1", "default value 2"

// attributes (see below)

primary autocreated mandatory protected multiple copy version
initialize compute ignore abort

// value constraints, denoted by a "<" (less than)

< “value constraint”

Property Constraints

Property constraints can be used to limit the allowed values of a given property. They are specified in a comma-separated list, all criteria are exclusive, meaning that one of the constraints have to be true in order for the node to be considered valid (not all). The repository will automatically validate against these rules and reject any nodes which don’t adhere to these constraints.

For multi-valued properties, all values individually must adhere to the constraints. Notice that the JCR currently does not provide a way to limit the number of items in a multi-valued property, such as, for example, only allowing zero to three values in a multi-valued property.

The following table outlines the various constraints given the pre-defined property types:

Type

Constraints

String

Value constraint defines as a standard Java regular expression. For example “*” denotes any arbitrary string.

Long

A range in the form of inclusive of exclusive ranges, where square brackets (“[“,”]) indicate inclusive values and regular brackets (“(”,”)”) exclusive values. A missing value indicates there there is no bound in a particular direction. Examples:

From 0 inclusive to five inclusive:[0,5]

From 0 inclusive to five exclusive:[0,5)

From no minimum to fire inclusive: [,5] or (,5]

Binary

Identical to the min,max notation outlined for the Long type. The minimum and maximum values indicate the size of the file allowed.

JCR does not provide a native way of only allowing certain mime types in a binary property. It is up to the content applications to enforce any further limit aside blob size.

Double

Identical to Long

Boolean

No constrains supported

Date

Identical to Long, the minimum and maximum values however indicate dates in ISO 8601:2000-compliant format: sYYYY-MM-DDThh:mm:ss.sssTZD.

Name

A fully namespace qualified name. This cannot include wildcards. For example “samples:teaser”.

Path

A path terminating with either no final “/”, a single “/”, or the substring “/*”. “*” in this case denotes matching all descendants.

Examples:

Exactly the path /myapp:products/myapp:television:

“/myapp:products/myapp:television”

The path including all directly descending nodes:

“/myapp:products/myapp:television/*”

Relative paths are interpreted relative to the current node the property is defined for. This could, for example, be utilized to constrain all image references of a node to go to binary nodes in an “images” folder.

“../myapp:television/*”

“myapp:television/*”

Reference

A fully namespace qualified name of a node type. References constrained to a particular node type will be able to only point to nodes of that particular type (as well as any subtypes).

No pattern matching of wildcards are supported.

WeakReference*

A fully namespace qualified name of a node type. Weak references constrained to a particular node type will be able to only point to nodes of that particular type (as well as any subtypes).

No pattern matching of wildcards are supported.

URI*

Value constraint defines as a standard Java regular expression. For example “*” denotes any arbitrary string.

Undefined

No constraints can be defined

JSR283 *Denotes JSR-283 specific properties

Default Property Values

Default values of a property can also be defined in the node type definition notation. They are denoted by a prepending “=” (equal) sign and a comma-separated list of strings. While single-valued properties only require one default value, a multi-valued property may have multiple default values. Specifying a default value is an imperative for autocreated properties (see property type options).

Note that default values naturally must validate against any defined property constraints.

The following table outlines the various default value option given the pre-defined property types:

Type

Default Values

String

Arbitrary string

Long

A long number

Binary

A UTF-8 encoded string

Double

A double number

Boolean

Any string that can be converted via java.lang.Boolean. valueOf(String), such as “true”, “false”, “0”, “1”

Date

A valid date in ISO 8601:2000-compliant format: sYYYY-MM-DDThh:mm:ss.sssTZD.

Name

A valid JCR name, fully qualified with namespace prefix

Path

A valid JCR path whose namespace prefixes are all registered correctly. Notice that the path does not have to point to an existing node.

Reference

A valid identifier (i.e. the jcr:uuid property of a node)

WeakReference*

A valid identifier (i.e. the jcr:uuid property of a node)

URI*

Any URI string

Undefined

Any string. The value is automatically converted to the appropriate type of the property when created.

JSR283 *Denotes JSR-283 specific properties

Property Options

A property can be given numerous options as outlined in this table. The JCR further exposes these properties via the javax.jcr.ItemDefinition class.

Option

Summary

primary

 

A node may specify one item as a primary item, which the API method Node.getPrimaryItem() returns. This primary item may be a child node or a property.

To make a property the primary item, the primary keyword needs to be present as part of the property type’s declaration.

It may appear on a maximum of one property or child node definition within a node type definition.

The short-hand notation for multiple is “!”.

autocreated

When set, the property is automatically created when the parent node is created. It mandates that a default value is set.

If not set, the property is either not created or, in case of a mandatory property, the caller has to call the Node.setProperty method in order to save the node.

mandatory

When set, the property is mandatory, meaning it must be present in order to save the node.

protected

Protected properties cannot be removed from their parent node unless the parent node is deleted.

multiple

When set, the property is multi-valued, accepting a list of values.

When the keyword is not present, the property only accept one value.

The short-hand notation for multiple is “*”.

The following set of options constitute the on-parent version (OPV) attribute. Only one of these can be present for a given property at a time. These properties determine what happens to the properties when a new version of the parent node is created. The node type declaration must hence be verisionable, i.e. inherit from the mixin mix:versionable or mix:simpleVersionable. Also refer to the chapter on versioning for details.

copy

Upon check-in, the value of the property will be copied to the new version.

version

Has the same semantics as copy for properties.

initialize

Upon check-in, a new property with the same name will be created and re-initialized with any default values specified or as empty. Essentially, the property is re-set when a new version of the node is created.

compute

Upon check-in, the new version will contain this property. However, when the node is restored from a previous node, the value of this property is NOT being restored.

ignore

Upon check-in, the version entry will not contain this property, i.e. it is not versioned.

abort

Upon check-in, a VersionException will be thrown as the creation of a version is prohibited.

This should not be used under normal circumstances.

Child Node Definition

A node may have any number of child nodes. In our previous example, the folder node was able to accept any node of type samples:content as a child node. The child node definition is denoted by a “+” (plus) sign.

+  ([required types]) =[default type] [attributes]

The node name may be restricted to child nodes of a specific name or a “*” (wildcard) for child nodes with arbitrary names.

The type of the child nodes can be restricted to specific types (and their sub-types) using a comma-separated list of node types in brackets (“(“,”)”).

Example:

[samples:folder] > samples:content, samples:configurable

// accept any subnodes of type samples:content

+ * (samples:content) multiple

Further, the following attributes can be specified as part of the child node definition:

Attributes

Summary

multiple

When present, the node type may have any number of child nodes. If absent, there can be at most one child node.

mandatory

When present, nodes of the defined type must have child nodes.

autocreated

When present, the JCR automatically creates the specified child nodes.

protected

When present, the JCR will protect the child nodes from being deleted though the APIs. This may be used in combination with the autocreated property, keeping the API-caller from deleting this child nodes.

primary

A node may specify one item as a primary item, which the API method Node.getPrimaryItem() returns. This primary item may be a child node or a property.

To make a sub node the primary item, the primary keyword needs to be present as part of the child node declaration.

It may appear on a maximum of one property or child node definition within a node type definition.

The short-hand notation for multiple is “!”.

multiple

If present, this will allow child nodes having the same name. If not present, the names of the child nodes have to be unique.

The following set of options constitute the on-parent version (OPV) attribute, they are similar to the OPV attributes specified at a property-level. However, the semantics are slightly different on a child node level, only one of these can be present. These properties determine what happens to the properties when a new version of the parent node is created.

copy

When this keyword is present, the child nodes and all descending items (down the leaves of the tree) of the node are copied into the version storage. When the root node is being restored from a version, the entire sub tree is restored also.

version

Honors the versioning attributes of particular child nodes, not copying the subgraph of versionable nodes but rather pointing to the individual version histories.

initialize

Upon check-in, new child nodes will be created and re-initialized with any default values specified or as empty. Essentially, the child nodes are re-set when a new version of the node is created.

compute

Upon check-in, the semantics are identical to the copy option: The subtree of children is recursively copied into the version.

When a node is restored, the child nodes are not restored with it but remain.

ignore

Upon check-in, the new version will not contain any child nodes, i.e. they are not versioned.

abort

Upon check-in, a VersionException will be thrown as the creation of a version is prohibited.

This should not be used under normal circumstances.