The JCR 2.0 specification organizes the various features of the specification into several categories. The first are the mandatory features:
-
Repository acquisition, authentication and authorization - Obtaining a Repository instance and connecting to the repository to obtain multiple Session objects.
-
Reading and browsing content - Navigating and finding nodes by path and by identifier, and reading properties of nodes.
-
Querying content - Using the two query languages defined by JCR 2.0, including the SQL-like JCR-SQL2 and the programmatic JCR-JQOM languages.
-
Exporting content - Exporting all or part of a workspace to one of two XML formats: the system document format results in "sv:node", "sv:property", and "sv:value" XML elements, and a document view format that results in XML elements that correspond to nodes and XML attributes that correspond to properties.
-
Discovering node types - Using the built-in NodeTypeManager and related JCR interfaces to find and list all the node types, property type definitions, and child node definitions that are registered with the repository.
-
Checking permissions and capabilities - Checking whether any session has the ability to read, set properties, add nodes, or remove nodes at particular locations within the workspace. This also includes allowing any session to determine a priori whether certain operations cannot be performed, although this basically is a best-effort mechanism.
The specification then outlines some of the optional features:
-
Writing to the repository - Creating, modifying, or removing content using the Session-related methods.
-
Importing content - Importing the information in an XML file (in either the system document format or the document view format) into the repository, prescribing the behavior when there are clashes in identities.
-
Observing changes - Allowing users to register listeners with various criteria that will be notified when changes are made in the repository content that satisfy the listener's criteria.
-
Managing workspaces - Programmatically creating new workspaces and deleting existing workspaces.
-
Shareable nodes - A feature that allows certain nodes to be "shared" at multiple locations within the same or different workspaces.
-
Versioning - A mechanism that allows the user to mark content as versionable (by adding a "mix:versionable" mixin), and then use methods to signal to the repository that the current state of that content be captured in the repository's version history. Users can also navigate the version history, and merge or restore the content from older versions.
-
Locking content - A simple mechanism by which a user can lock (for a short period of time) content to prevent other users from modifying or removing that same content.
-
Managing node types - Allowing users to register new node types, re-register node types with alternative definitions, and unregister node types that are no longer used.
-
Transactions - Defines how repositories and sessions behave when used within a JTA environment.
-
Same name siblings - Defines the semantics and behaviors for allowing children of a single node to have the same name yet be individually addressable.
-
Ordering children - Defines how nodes (and in particular node types) can specify that the ordering of their children is to be maintained or changed.
-
Managing access controls - An advanced mechanism for allowing users to discover and manage fine-grained access control privileges. Much of this feature relies upon implementation-specific policy definitions.
-
Managing content lifecycles - Allow content to be associated with various lifecycles, and allow users to transition the state of content through the appropriate lifecycle. The names and semantics of the lifecycle states and transitions are implementation-specific.
-
Retention and hold - Allows a repository to integrate with an external retention and hold facility to place a hold on certain content, effectively making that content appear as if it were read-only, while tracking information about the hold and the hold policy that applies to various content.
ModeShape 5.x supports all of these JCR features except: content lifecycles and retention and hold.
Discovering support
The JCR API also provides a way for a user to dynamically discover which of these features a repository supports. Each Repository instance exposes descriptors for each of these behavioral features. The descriptor keys for a repository instance are accessible as are the individual values for each descriptor. Standard descriptor keys are defined by constants on the javax.jcr.Repository interface.
Here's a small sample of code that gets the various descriptors for a repository:
javax.jcr.Repository repository = ...
String[] keys = repository.getDescriptorKeys();
for ( String key : keys ) {
boolean std = repository.isStandardDescriptor(key);
boolean singleValued = repository.isSingleValueDescriptor(key);
if ( singleValued ) {
Value value = repository.getDescriptorValue(key);
} else {
Value[] values = repository.getDescriptorValues(key);
}
}
Note that the Value object is the same as what's used for property values, and the Value class has methods to obtain the value in the form of a String, boolean, long, double, java.util.Calendar, java.match.BigDecimal, java.io.InputStream, and javax.jcr.Binary objects.
Here's another example that shows how to determine the languages that are supported by a repository:
javax.jcr.Repository repository = ...
Value[] languages = repository.getDescriptorValues(Repository.QUERY_LANGUAGES);