Content Loading and Nodetype Support
Apache Sling provides support for initial content loading into a repository and for registering node types. The sling-jcr-contentloader bundle provides loading of content from a bundle into the repository and the sling-jcr-base bundle provides node type registration.
Declared Node Type Registration
The sling-jcr-base bundle provides low-level repository operations which are at the heart of the functionality of Sling:
- Node Type Definitions - The class org.apache.sling.content.jcr.base.NodeTypeLoader provides methods to register custom node types with a repository given a repository session and a node type definition file in CND format. This class is also used by this bundle to register node types on behalf of other bundles.
Bundles may list node type definition files in CND format in the Sling-Nodetypes bundle header. This header is a comma-separated list of resources in the respective bundle. Each resource is taken and fed to the NodeTypeLoader to define the node types.
After a bundle has entered the resolved state, the node types listed in the Sling-Nodetypes bundle header are registered with the repository.
Node types installed by this mechanism will never be removed again by the sling-jcr-base bundle. Likewise, registered node types cannot currently be modified using this feature. The NodeTypeLoader will try to load nodes defined and fail with a log message if a node type has already been defined. To update existing node type definitions, native repository functionality has to be used.
Nodetype management is currently a problematic issue, as the only API available is contained in the Jackrabbit Core library, which is generally not available to client applications - unless running in the same VM and class loader hierarchy as the Repository. Version 2 of the JCR Specification currently being developped as JSR-283 should fix this issue by providing an official node type management API. Until then, this approach is about the only solution we have.
Initial Content Loading
Bundles can provide initial content, which is loaded into the repository when the bundle has entered the started state. Such content is expected to be contained in the bundles accessible through the Bundle entry API methods. Content to be loaded is declared in the Sling-Initial-Content bundle manifest header. This header takes a comma-separated list of bundle entry paths. Each entry and all its child entries are accessed and entered into starting with the child entries of the listed entries.
Adding this content preserves the paths of the entries as show in this table, which assumes a Sling-Initial-Content header entry of SLING-INF/content:
Entry | Repository Path |
---|---|
SLING-INF/content/home | /home |
SLING-INF/content/content/playground/en/home | /content/playground/en/home |
Bundle entries are installed as follows:
Entry Type | Installation method |
---|---|
Directory | Created as a node of type nt:folder unless a content definition file of the same name exists in the same directory as the directory to be installed. Example: A directory SLING-INF/content/dir is installed as node /dir of type nt:folder unless a SLING-INF/content/dir.xml or SLING-INF/content/dir.json file exists which defines the content for the /dir node. |
File | Unless the file is a content definition file (see below) an nt:file node is created for the file and an nt:resource node is created as its jcr:content child node to take the contents of the bundle file. The properties of the nt:resource node are set from file information as available. If the file is a content definition file, the content is created as defined in the file. See below for the content definition file specification. |
It is possible to modify the intial content loading default behaviour by using certain optional directives. Directives should be specified separated by semicolon. They are defined as follows:
Directive | Definition | Default value | Description |
---|---|---|---|
overwrite | overwrite:=(true|false) | false | The overwrite directive specifies if content should be overwritten or just initially added. |
uninstall | uninstall:=(true|false) | overwrite | The uninstall directive specifies if content should be uninstalled when bundle is unregistered. This value defaults to the value of the overwrite directive. |
path | path:=/target/location | / | The path directive specifies the target node where initial content will be loaded. If the path does not exist yet in the repository, it is created by the content loader. The intermediate nodes are of type nt:folder. |
checkin | checkin:=(true|false) | false | The checkin directive specifies whether versionable nodes should be checked in. |
ignoreImportProviders | ignoreImportProviders:=list of extensions | empty | This directive can be used to not run one of the configured extractors (see below). |
Examples of these directives uses could be (assumes a Sling-Initial-Content header entry of SLING-INF/content):
Entry | Behaviour |
---|---|
SLING-INF/content/home;overwrite:=true;uninstall:=true | Overwrites already existing content in /home and uninstalls the content when the bundle is unregistered. |
SLING-INF/content/home;path:=/sites/sling_website | if /sites/sling_website exists it loads the content into it. Otherwise, it loads the content into root node /. |
SLING-INF/content/home;checkin:=true | After content loading, versionable nodes are checked in. |
Extractors
By default, the sling-jcr-contentloader bundle tries to extract certain file types during content loading. These include json, xml, zip, and jar files. Therefore all available extractors are used for content processing. However if some files should be put into the repository unextracted, the ignoreImportProviders directive can be used with a comma separated list of extensions that should not be extracted, like ignoreImportProviders:=jar,zip.
Content Definition File Specification
Structured content may be specified in content specification file in JSON or XML format which define subtrees of content. A content definition file contains the definition of a single node with optional properties and child nodes. Each child node may again have its properties and child nodes. The definition of a node is as follows:
JSON
... *TODO* ...
XML
... *TODO* ...
Automated tests
The initial content found in the sling-test folder of the launchpad initial content is verified by the InitialContentTest when running the launchpad/testing integration tests.
Those tests can be used as verified examples of initial content loading. Contributions are welcome to improve the coverage of those tests.