Introduction to the Mapping Strategies

We are calling "Mapping strategy" the algorithm used by the Persistence Manager to map a bean into JCR nodes and/or properties.

In order to explain the basic mapping strategies, we will use the following simple object model :

  • A page contains a path (of course), a pageInfo and a collection of paragraphs.
  • The PageInfo class contains the title and the page description. We are using the pageInfo here to see all mapping features (see the bean-descriptors). In real application, this class is not necessary :-)
  • Each paragraph contains a path and a text field.

This object model could be too simple for real applications and it is used here just to simplify the description of the different mapping strategies.

Based on that object model, we can define the following java classes :

public class Page
{
	String path;
	PageInfo pageInfo;
	Collection paragraphs;
	
	/*  Add here the getter and setter methods */

	public void addParagraph(Paragraph paragraph)
	{
		if (paragraphs == null)
		{
			paragraphs = new ArrayList();
		}
				
		paragraphs.add(paragraph);
	}
}	

public class PageInfo
{
	String path;
	String title;
	String description;

	/*  Add here the getter and setter methods */

}

public class Paragraph
{
	private String path;
	private String text;
				
	/* Add here the getter and setter methods */
				
}
			

The Class descriptor

When you decide to map a bean class, you have to create a new class descriptor entry in the Persistence Manager descriptor file.

Here are the class-descriptors required to map the classes Page, PageInfo and Paragraph :

 				
<class-descriptor className="org.apache.portals.graffito.jcr.testmodel.Page" jcrNodeType="graffito:page">
	<field-descriptor fieldName="path" path="true" />
	<bean-descriptor fieldName="pageInfo" jcrName="pageInfo" />
	<collection-descriptor fieldName="paragraphs" jcrName="paragraphs" elementClassName="org.apache.portals.graffito.jcr.testmodel.Paragraph" />
</class-descriptor>
									
<class-descriptor className="org.apache.portals.graffito.jcr.testmodel.PageInfo" jcrNodeType="graffito:PageInfo">
	<field-descriptor fieldName="path" path="true" />
	<field-descriptor fieldName="title" jcrName="graffito:title"/>
	<field-descriptor fieldName="description" jcrName="graffito:description"/>
</class-descriptor>

<class-descriptor className="org.apache.portals.graffito.jcr.testmodel.Paragraph" jcrNodeType="graffito:paragraph">
	<field-descriptor fieldName="path" path="true" />
	<field-descriptor fieldName="text" jcrName="graffito:text"/>
</class-descriptor>
			

We will explain in more details each descriptors in the following sections (Mapping Atomic Fields,Mapping Bean Fields and Mapping Collection Fields. If the page is stored on the path "/mysite/mypage1" and contains 2 paragraphs, here is the resulting jcr structure :

 
/mysite/page1	
	/mysite/page1/pageInfo
		graffito:title = "This is my page title"
		graffito:description = "This is my page description"
	/mysite/page1/paragraphs
		/mysite/page1/paragraphs/paragraph1
			graffito:text = "This is the content of para1"
		/mysite/page1/paragraphs/paragraph2
			graffito:text = ""This is the content of para2"
			

It is possible to have another kind of jcr structure by using other mapping strategies. You can see the section "Advance Mapping strategies" to get more information on that.

Now, let's go back to the class-descriptor.

 
<class-descriptor className="org.apache.portals.graffito.jcr.testmodel.Paragraph" jcrNodeType="nt:unstructured">
	<field-descriptor fieldName="path" path="true" />
	<field-descriptor fieldName="text" jcrName="graffito:text"/>
</class-descriptor>
				

This class descriptor maps the class "org.apache.portals.graffito.jcr.testmodel.Paragraph" to the JCR type "nt:unstructured". Each field-descriptors maps one bean attribute to a JCR property. You can find more information on the field-descriptors in the page Mapping Atomic fields.

It is also possible to map a bean class to a specific JCR node type. The following class-descriptor map the class "org.apache.portals.graffito.jcr.testmodel.Paragraph" to the node type "graffito:paragraph".

 				
<class-descriptor className="org.apache.portals.graffito.jcr.testmodel.Paragraph" jcrNodeType="graffito:paragraph">
	<field-descriptor fieldName="path" path="true" />
	<field-descriptor fieldName="text" jcrName="graffito:text"/>
</class-descriptor>
				

In order to use correclty our example class with Jackrabbit, you should add the following node type definition in its custom_nodetypes.xml file or import the node type definition with the Jackrabbit API

 				
<nodeType name="graffito:paragraph" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
	<supertypes>
		<supertype>mix:versionable</supertype>
		<supertype>nt:base</supertype>
	</supertypes>
	<propertyDefinition name="*" requiredType="undefined" autoCreated="false" 
			    mandatory="false" onParentVersion="COPY" protected="false" multiple="false" />
	<propertyDefinition name="graffito:text" requiredType="String" autoCreated="false" 
			    mandatory="true" onParentVersion="COPY" protected="false" multiple="false" />
</nodeType>
				

Of course, node types "Graffito:Page" and "Graffito:PageInfo" are alse required. We are currently building a node type management tools which can import the node types from the class-descriptors.

The path Field

Each mapped class contains a mandatory field called the "path field". It simply contains the JCR path associated to the object. For example, the following descriptor specify the bean field "myPath" as the path field.

 
<field-descriptor fieldName="myPath" path="true" />