To help set-up a simple, out-of-the-box repository pre-populated with some content, ModeShape provides a way to configure such content using a simple xml format. This content can be imported either in a specific workspace, or imported by default in all predefined or new workspaces.
Initial content is imported only the first time a repository starts up into the predefined workspaces or when a new workspace is created, if that workspace was configured as such.
The initial content feature is intended to allow the import of a simple structure and is not intended for large volumes of data or complex data structures. There are other, more powerful mechanisms like backup & restore or JCR XML import/export that may be better suited to those cases.
XML Format
Each initial content XML must define a single root node called jcr:root under the namespace http://www.jcp.org/jcr/1.0. This represents the root node of a workspace and all content is imported below it.
Example
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0">
<folder jcr:mixinTypes="mix:created, mix:lastModified" jcr:primaryType="nt:folder">
<file1 jcr:primaryType="nt:file">
<jcr:content/>
</file1>
<file2 jcr:primaryType="nt:file">
<jcr:content/>
</file2>
</folder>
</jcr:root>
Each node has by default, the same name as the XML element which defines it and the properties the attributes of the XML element. Beside any number of custom properties, the JCR properties: jcr:name, jcr:primaryType and jcr:mixinTypes are supported, allowing for a node to have custom name, type and/or mixins. If not specified, the default node type of the created node will be nt:unstructured.
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0">
<Cars>
<Hybrid>
<car jcr:name="Toyota Prius" maker="Toyota" model="Prius"/>
<car jcr:name="Toyota Highlander" maker="Toyota" model="Highlander"/>
<car jcr:name="Nissan Altima" maker="Nissan" model="Altima"/>
</Hybrid>
<Sports>
<car jcr:name="Aston Martin DB9" maker="Aston Martin" model="DB9"/>
<car jcr:name="Infiniti G37" maker="Infiniti" model="G37"/>
</Sports>
</Cars>
</jcr:root>
It is also possible to override the name of the nodes by defining the jcr:name attribute, which will then be used instead of the XML element's name.
Custom Property Types
By default, all the properties defined in an XML file are stored as string properties on the corresponding node. However, it is possible to define a custom property type for any given property, using any of the types defined via JCR's javax.jcr.PropertyType.
To specify a custom type for a property, one needs to define the property as a nested XML child element of the parent node:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0">
<node1>
<string_prop type="string">string</string_prop>
<boolean_prop type="boolean">true</boolean_prop>
<long_prop type="long">123456</long_prop>
<decimal_prop type="decimal">12.3</decimal_prop>
<date_prop type="date">1994-11-05T13:15:30Z</date_prop>
<double_prop type="double">12.3</double_prop>
<name_prop type="name">nt:undefined</name_prop>
<path_prop type="path">/a/b/c</path_prop>
<uri_prop type="uri">http://www.google.com</uri_prop>
<binary_prop type="binary">io/file1.txt</binary_prop>
<reference_prop type="reference">/node2</reference_prop>
<weakreference_prop type="weakreference">/node2</weakreference_prop>
<simplereference_prop type="simplereference">/node2</simplereference_prop>
</node1>
<node2 jcr:mixinTypes="mix:referenceable"/>
</jcr:root>
Certain types have special requirements:
-
date properties must be defined using the ISO 8601 format
-
reference, weakreference and simplereference properties must use the absolute path of the node they refer to, which in turn must have the mix:referenceable mixin
-
binary properties must define a path to a resource resolvable via java.io.File or via the ModeShape default classloader. If none of these 2 conditions is met, the actual UTF-8 bytes of the string value will be treated & stored as the binary.
Configuring Initial Content
The configuration necessary for a standalone repository to make use of the initial content is the following:
{
"name" : "Repository with initial content",
"workspaces" : {
"predefined" : ["ws1", "ws2"],
"default" : "default",
"allowCreation" : true,
"initialContent" : {
"ws1" : "xmlImport/docWithMixins.xml",
"ws2" : "xmlImport/docWithCustomType.xml",
"default" : "xmlImport/docWithoutNamespaces.xml",
"ws4" : "",
"ws5" : "xmlImport/docWithCustomType.xml",
"*" : "xmlImport/docWithMixins.xml"
}
}
}
One needs to define an initialContent object inside the workspaces object, with the following content:
-
each attribute name inside the initialContent object, with the exception of the * string, will be treated as the name of a workspace and will have precedence over anything else. This includes the empty string, which can be used to explicitly configure workspace without any initial content, when a default is defined (see below)
-
the * character is interpreted as "default content" which means that any predefined or newly created workspaces, that aren't configured explicitly, will make use of this content
-
the value of each attribute must be a simple string (including the empty string) which represents the URL of an XML file located in the runtime classpath
When using the Wildfly kit, initial content can be configured like so:
<workspaces>
<workspace name="default"/>
<workspace name="other"/>
<workspace name="extra">
<initial-content>initial-content-custom.xml</initial-content>
</workspace>
<workspace name="empty">
<initial-content/>
</workspace>
<!--Defines a default initial content which will be imported in all the workspaces which don't have smth configured-->
<initial-content>initial-content-default.xml</initial-content>
</workspaces>