<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gridshore &#187; cms</title>
	<atom:link href="http://www.gridshore.nl/tag/cms/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridshore.nl</link>
	<description>A weblog about software engineering, Architecture, Technology an other things we like.</description>
	<lastBuildDate>Tue, 13 Dec 2011 15:36:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>A perspective on content management</title>
		<link>http://www.gridshore.nl/2009/05/19/a-perspective-on-content-management/</link>
		<comments>http://www.gridshore.nl/2009/05/19/a-perspective-on-content-management/#comments</comments>
		<pubDate>Tue, 19 May 2009 21:14:04 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[cms]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=768</guid>
		<description><![CDATA[<p>This is a very short post. Actually it is just a reference to a blog post I have written on another blog. Yes, again another blog. This time it is a blog at my employers website.</p> <p>The blog post is about my perspective on content management. A white paper that can help you to [...]]]></description>
			<content:encoded><![CDATA[<p>This is a very short post. Actually it is just a reference to a blog post I have written on another blog. Yes, again another blog. This time it is a blog at my <a href="http://blog.jteam.nl">employers website</a>.</p>
<p>The blog post is about my perspective on content management. A white paper that can help you to start looking for a CMS that suits your needs. </p>
<p><strong><a href="http://blog.jteam.nl/2009/05/19/a-perspective-on-content-management/">A perspective on content management</a></strong></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F05%2F19%2Fa-perspective-on-content-management%2F&amp;title=A%20perspective%20on%20content%20management&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/05/19/a-perspective-on-content-management/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hippo cms workflow with events</title>
		<link>http://www.gridshore.nl/2009/03/13/hippo-cms-workflow-with-events/</link>
		<comments>http://www.gridshore.nl/2009/03/13/hippo-cms-workflow-with-events/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 14:15:41 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[hippo]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=670</guid>
		<description><![CDATA[<p>Hippo is an opensource content management system. Hippo has created a cms on top of the Jackrabbit repository. Hippo is not the only cms that does this trick, but it is a big one. With version 7 out there, you can now use some nice features that they have created. This post discusses one [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/hippoworkflowevents-small.png" alt="HippoWorkflowEvents-small.png" border="0" width="150" height="117" align="left" />Hippo is an opensource content management system. <a href="http://www.onehippo.org/">Hippo</a> has created a cms on top of the Jackrabbit repository. Hippo is not the only cms that does this trick, but it is a big one. With version 7 out there, you can now use some nice features that they have created. This post discusses one of these features in detail, <strong>Workflow</strong>. I&#8217;ll explain what it is, what is can be used for and how you can extend it with business events.</p>
<p>I do want to stress that this is an idea I have about how this can be implemented. I did try it out, but do not consider this as a best practise (yet). See it as inspiration to your own extensions and maybe Hippo will contain something like this in the future.</p>
<p>The idea behind this post came from talks with Allard and Jeroen Reijn, who will write a blog post about a specific part of the solution as I will describe in the post later on.</p>
<p><span id="more-670"></span><br />
<h2>The problem</h2>
<p>Let me start by describing the reason why I wanted a solution like this. For a project we are doing, we want the content of the repository to be available in a <a href="http://lucene.apache.org/solr/">Solr</a> instance. Yes I know Hippo comes with Lucene out of the box, but we have have chosen to use solr. The reason behind this is not important for the scope of this blog post. Because of this we need to have information about content in the repository. Of course there are multiple mechanisms available to do this. I have blogged before about repository listeners. There is a big disadvantage with these listeners, they are not part of the repository. They are part of a client that connect to the repository. These listeners are also very low level, they respond to nodes being added or changed. We are more interested in the business events that take place. An example would be the publication of a document. We want to integrate with the workflow in the cms/repository.</p>
<p><a href="http://blog.jeroenreijn.com/2009/03/using-daemon-modules-with-hippo-cms-7.html">Jeroen showed me a way</a> this could be done with hippo 7 using a Daemon module.</p>
<h2>The design</h2>
<p>The following image gives an overview of the design for the solution.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/hippoworkflowevents1.png" alt="HippoWorkflowEvents.png" border="0" width="611" height="443" /></p>
<p>Let&#8217;s start with the WorkflowEventDaemon, this is a class that get&#8217;s instantiated by hippo during initialization of the repository. This daemon queries the repository for nodes of type <em>cust:workflowevent</em>. These nodes contain a reference to the implemented EventListeners. The daemon uses these nodes to register event listeners with the EventManager. Next up are the workflow implementations. Currently the provided workflows do not raise events. Luckily it is fairly easy to extend these workflows so they do create the events. The workflow implementations use EventDispatcher instances to actually send an event to the EventManager. Using these events, the EventManager will call the listeners.</p>
<p>That is the basic idea about the solution, let&#8217;s focus on the implementation now.</p>
<h2>The implementation</h2>
<h3>Node type defintion</h3>
<p>First we need to tell the repository about the new type. This is done using CND file. The file looks like this.</p>
<pre class="brush: plain; title: ; notranslate">
&lt;'cust'='http://www.gridshore.nl/cust/1.0'&gt;
&lt;'hippostd'='http://www.hippoecm.org/hippostd/nt/1.2'&gt;
&lt;'hippo'='http://www.hippoecm.org/nt/1.2'&gt;
[cust:workflowevent]
- cust:class (String)
</pre>
<p>Hippo has created a mechanism to load nodes into the repository during startup. If you provide a file with the name <em>hippoecm-extension.xml</em>, hippo picks it up and puts these nodes in the repository. To load the CND file we add the following configuration</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;sv:node xmlns:sv=&quot;http://www.jcp.org/jcr/sv/1.0&quot; sv:name=&quot;hippo:initialize&quot;&gt;
    &lt;sv:property sv:name=&quot;jcr:primaryType&quot; sv:type=&quot;Name&quot;&gt;
        &lt;sv:value&gt;hippo:initializefolder&lt;/sv:value&gt;
    &lt;/sv:property&gt;

    &lt;sv:node sv:name=&quot;cust&quot;&gt;
        &lt;sv:property sv:name=&quot;jcr:primaryType&quot; sv:type=&quot;Name&quot;&gt;
            &lt;sv:value&gt;hippo:initializeitem&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:sequence&quot; sv:type=&quot;Double&quot;&gt;
            &lt;sv:value&gt;10009&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:namespace&quot; sv:type=&quot;String&quot;&gt;
            &lt;sv:value&gt;http://www.gridshore.nl/cust/1.0&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:nodetypesresource&quot; sv:type=&quot;String&quot;&gt;
            &lt;sv:value&gt;cust-types.cnd&lt;/sv:value&gt;
        &lt;/sv:property&gt;
    &lt;/sv:node&gt;
&lt;/sv:node&gt;
</pre>
<h3>WorkflowEventListener</h3>
<p>If you are interested in WorkflowEvents, you need to register a listener. Configuration of these listeners is done in the repository. We can add a node during startup. This is done by adding the following configuration to the hippo-extension.xml file.</p>
<pre class="brush: xml; title: ; notranslate">
    &lt;sv:node sv:name=&quot;content-workflowevents&quot;&gt;
        &lt;sv:property sv:name=&quot;jcr:primaryType&quot; sv:type=&quot;Name&quot;&gt;
            &lt;sv:value&gt;hippo:initializeitem&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:sequence&quot; sv:type=&quot;Double&quot;&gt;
            &lt;sv:value&gt;10500&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:contentresource&quot; sv:type=&quot;String&quot;&gt;
            &lt;sv:value&gt;workflowevents.xml&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;hippo:contentroot&quot; sv:type=&quot;String&quot;&gt;
            &lt;sv:value&gt;/content&lt;/sv:value&gt;
        &lt;/sv:property&gt;
    &lt;/sv:node&gt;
</pre>
<p>This references the workflowsevents.xml file. The following code shows this file that actually contains a node of type <em>cust:workflowevent</em> containing a reference to a very easy Logging implementation of the WorkflowEventListener interface</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;sv:node sv:name=&quot;workflowevents&quot; xmlns:sv=&quot;http://www.jcp.org/jcr/sv/1.0&quot;&gt;
    &lt;sv:property sv:name=&quot;jcr:primaryType&quot; sv:type=&quot;Name&quot;&gt;
        &lt;sv:value&gt;hippostd:folder&lt;/sv:value&gt;
    &lt;/sv:property&gt;
    &lt;sv:property sv:name=&quot;jcr:mixinTypes&quot; sv:type=&quot;Name&quot;&gt;
        &lt;sv:value&gt;hippo:harddocument&lt;/sv:value&gt;
    &lt;/sv:property&gt;

    &lt;sv:node sv:name=&quot;Logging Listener&quot;&gt;
        &lt;sv:property sv:name=&quot;jcr:primaryType&quot; sv:type=&quot;Name&quot;&gt;
            &lt;sv:value&gt;cust:workflowevent&lt;/sv:value&gt;
        &lt;/sv:property&gt;
        &lt;sv:property sv:name=&quot;cust:class&quot; sv:type=&quot;String&quot;&gt;
            &lt;sv:value&gt;nl.gridshore.addons.events.impl.LoggerWorkflowEventListener&lt;/sv:value&gt;
        &lt;/sv:property&gt;
    &lt;/sv:node&gt;
&lt;/sv:node&gt;
</pre>
<p>Now we have the nodes in the repository that daemon queries for. So let&#8217;s have a look at the daemon.</p>
<h3>The daemon</h3>
<p>Now we have come to the part where Jeroen helped me out. It turns out that hippo looks on it&#8217;s classpath for all MANIFEST.MF files. If such a file contains an entry for the property <strong>Hippo-Modules</strong>, hippo expects a space delimited number of classes that are implementations of the <strong>DeamonModule</strong> interface. If you are using maven, this is very easy to accomplish using the jar plugin.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
    &lt;configuration&gt;
        &lt;archive&gt;
            &lt;manifestEntries&gt;
                &lt;Hippo-Modules&gt;nl.gridshore.hippo.addons.deamon.WorkflowEventDeamon&lt;/Hippo-Modules&gt;
            &lt;/manifestEntries&gt;
        &lt;/archive&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<p>The daemon itself contains three parts</p>
<ul>
<li>Query the repository for registered WorkflowEventListeners</li>
<li>Instantiate each listener using reflection</li>
<li>Register each listener with the EventManager</li>
</ul>
<p>The following code block shows the complete implementation of the daemon. I hope the code is clear enough.</p>
<pre class="brush: java; title: ; notranslate">
public class WorkflowEventDeamon implements DaemonModule {
    private Session session;

    public void initialize(Session session) throws RepositoryException {
        this.session = session;

        NodeIterator nodes = obtainRegisteredWorkflowEventListeners(session);
        while (nodes.hasNext()) {
            Node node = nodes.nextNode();
            Property property = node.getProperty(&quot;cust:class&quot;);

            WorkflowEventListener listener = constructListener(property.getString());
            if (listener != null) {
                EventManager.getInstance().addWorkflowEventListener(listener);
            }
        }
    }

    private NodeIterator obtainRegisteredWorkflowEventListeners(Session session) throws RepositoryException {
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        Query query = queryManager.createQuery(&quot;select * from cust:workflowevent&quot;, Query.SQL);
        QueryResult queryResult = query.execute();
        return queryResult.getNodes();
    }

    private WorkflowEventListener constructListener(String className) {
        WorkflowEventListener listener = null;
        try {
            Class clazz = this.getClass().getClassLoader().loadClass(className);
            listener = (WorkflowEventListener) clazz.getConstructor().newInstance();
        } catch (ClassNotFoundException e) {
            logger.error(&quot;FATAL error when loading listener class : class not found&quot;,e);
        } catch (NoSuchMethodException e) {
            logger.error(&quot;FATAL error when loading listener class : no such method&quot;,e);
        } catch (IllegalAccessException e) {
            logger.error(&quot;FATAL error when loading listener class : illegal access&quot;,e);
        } catch (InvocationTargetException e) {
            logger.error(&quot;FATAL error when loading listener class : invocation target&quot;,e);
        } catch (InstantiationException e) {
            logger.error(&quot;FATAL error when loading listener class : instantiation&quot;,e);
        }
        return listener;
    }

    public void shutdown() {
        session.logout();
    }
}
</pre>
<h3>The EventManager</h3>
<p>The implementation of the EventManager is pretty straightforward. It contains a method to register listeners and a method to add an event. The following code block shows the implementation.</p>
<pre class="brush: java; title: ; notranslate">
public class EventManager {
    private final static EventManager eventManager = new EventManager();
    private final Set&lt;WorkflowEventListener&gt; eventListeners = Collections.synchronizedSet(new HashSet&lt;WorkflowEventListener&gt;());

    private EventManager() {}

    public void addEvent(WorkflowEvent workflowEvent) {
        for (WorkflowEventListener workflowEventListener : eventListeners) {
            workflowEventListener.handleEvent(workflowEvent);
        }
    }

    public void addWorkflowEventListener(WorkflowEventListener workflowEventListener) {
        eventListeners.add(workflowEventListener);
    }

    public static EventManager getInstance() {
        return eventManager;
    }
}
</pre>
<h3>Dispatching events</h3>
<p>I already mentioned I want to dispatch events from workflow components. It is a bit out of scope of this blog item to discuss workflows in Hippo very detailed. To be honest, I would not be the right person to do that. Still I want to give you a very short introduction.</p>
<p>The default workflow for promoting content from draft into publication is the <strong>Reviewed actions workflow</strong>. This workflow is provided in the default installation. Workflow items in here define what needs to happen when an author opens a document in edit mode or when an editor can do. These kind of workflow items are initiated by the frontend plugins. These plugins are wicket components that put a save and cancel button on the screen. In this blog item I&#8217;ll describe the way to extend such a workflow and how to configure the repository/cms to use our custom workflow item.</p>
<p>Let&#8217;s start with the custom workflow item</p>
<pre class="brush: java; title: ; notranslate">
public class CustomBasicReviewedActionsWorkflowImpl extends BasicReviewedActionsWorkflowImpl
        implements BasicReviewedActionsWorkflow {
    public CustomBasicReviewedActionsWorkflowImpl() throws RemoteException {
        super();
    }

    public void publish(Date date) throws WorkflowException, MappingException, RepositoryException, RemoteException {
        super.publish(date);
        EventManager.getInstance().addEvent(new WorkflowEvent(&quot;This is my first workflow event from the publish&quot;));
    }

    public void commitEditableInstance() throws WorkflowException {
        super.commitEditableInstance();
        EventManager.getInstance().addEvent(new WorkflowEvent(&quot;This is my first workflow event from the commit editable instance&quot;));
    }
}
</pre>
<p>The workflow items are configured in the repository in the following path<br/><em>/hippo:configuration/hippo:workflows/</em>. For the specific BasicReviewedActionsWorkflow we need to change two locations. In the following two locations we need to change the property <strong>hippo:classname</strong>:</p>
<ul>
<li>/hippo:configuration/hippo:workflows/default/authorreviewedactions</li>
<li>/hippo:configuration/hippo:workflows/editing/reviewedactions</li>
</ul>
<p>There is one thing left to do, hippo uses jpox to enrich the worklfow. This enriching needs to be done using the jpox maven plugin. The following code block gives an example:</p>
<pre class="brush: xml; title: ; notranslate">
            &lt;plugin&gt;
                &lt;groupId&gt;jpox&lt;/groupId&gt;
                &lt;artifactId&gt;jpox-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;1.2.0-beta-2&lt;/version&gt;
                &lt;configuration&gt;
                    &lt;verbose&gt;false&lt;/verbose&gt;
                &lt;/configuration&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;phase&gt;compile&lt;/phase&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;enhance&lt;/goal&gt;
                        &lt;/goals&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;
</pre>
<p>That is about it, if you fire up your repository and cms, and you change the properties as mentioned above, the workflow items should be sending events when someone saves and closes a document.</p>
<p>Hope this helped in you exploration of hippo workflows.</p>
<h2>References</h2>
<ul>
<li>http://www.onehippo.org/cms7//delve_into/custom/reference/repository/workflow.html</li>
<li><a href="http://blog.jeroenreijn.com/2009/03/using-daemon-modules-with-hippo-cms-7.html">Blog Jeroen for more information about the DaemonModule</a></li>
</ul>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2009%2F03%2F13%2Fhippo-cms-workflow-with-events%2F&amp;title=Hippo%20cms%20workflow%20with%20events&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2009/03/13/hippo-cms-workflow-with-events/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integrate hippo cms into a spring application</title>
		<link>http://www.gridshore.nl/2008/07/06/integrate-hippo-cms-into-a-spring-application/</link>
		<comments>http://www.gridshore.nl/2008/07/06/integrate-hippo-cms-into-a-spring-application/#comments</comments>
		<pubDate>Sun, 06 Jul 2008 21:48:52 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[hippo]]></category>
		<category><![CDATA[spring framework]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=153</guid>
		<description><![CDATA[<p>This article is about integrating the hippo cms with a spring framework application. To be honest, the amount of integration is very easy if you know how to configure the api that is provided by hippo. So what are we going to do? In this article I am going to describe the high level [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/hippo-logo.gif" alt="hippo_logo.gif" border="0" width="56" height="46" align="left"/>This article is about integrating the hippo cms with a spring framework application. To be honest, the amount of integration is very easy if you know how to configure the api that is provided by hippo. So what are we going to do? In this article I am going to describe the high level architecture of a normal spring-mvc application that makes use of the hippo api to store and obtain content from the hippo content repository.</p>
<p>For this article I have made use of the hippo 6 version. Things might change a lot when you are dealing with hippo 7. Starting release 7, hippo is fully compliant with the Java Content Repository API.</p>
<p>Continue reading if you want to learn about how to integrate hippo 6 with springframework.</p>
<p><span id="more-153"></span></p>
<p>Before jumping into the code, let&#8217;s have a look at the general architecture  of the application:</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/hippo-integration.png" alt="hippo-integration.png" border="0" width="522" height="299" /></p>
<p>There are two front end applications. You can use the hippo cms to create content and configure your repository. This is usually not a front end normal visitors will see. For Hippo 7, the cms is completely rewritten. And to be honest, they did that for a good reason. But that is not what this article is about, so that is the last thing I have said about it.</p>
<p>The other front end application is the &#8220;frontend application&#8221; <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . This is the actual spring framework application. Here you can find the base architecture for a pretty standard spring mvc application. For completeness, I&#8217;ll give you an overview for that as well.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/hippo-integration-highleveldesign.png" alt="hippo-integration-highleveldesign.png" border="0" width="570" height="570" /></p>
<p>The design contains the usual layers: interaction (web and import), business, dao, domain and common. To completely separate the hippo stuff, I have moved them into an extra integration layer. This layer embeds the hippo api. This is also the module I&#8217;ll focus on. Next to that I will also show some samples of a HippoDao class and most of all the abstract parent for all hippo data access classes.</p>
<p>Let&#8217;s start with the integration module, there is one class that is the interface to the hippo repository. Let&#8217;s call the interface the content connector and the the actual implementation the HippoContentConnector. To be able to connect to the repository, we have the availability of the hippo api. There are some components that we need to use to connect to hippo.</p>
<ul>
<li><em>nl.hippo.client.webdav.service.WebdavServiceImpl</em> &#8211; implementation that actually does the communication with the repository using the webdav functionality.</li>
<li><em>nl.hippo.client.event.service.UpdateNotificationServiceImpl</em> &#8211; This service is used by the api to invalidate it&#8217;s cache. It gets messages via jms with information about updated repository items.</li>
<li><em>nl.hippo.client.caching.service.CachingServiceImpl</em> &#8211; As the name says, this is all about caching. It is used by the webdav service to determine if an item should be obtained from the repository or not.</li>
<li><em>nl.hippo.client.api.event.EventAwareManager</em> &#8211; The relationship between the update service and the caching service. The event manager receives the events and notifies the caching service.</li>
</ul>
<p>The following image clarifies the relations that are available and that we need to create spring beans for. A few of the beans are not yet discussed. They are used to configure the other beans. In the image all the greens beans are hippo provided classes, the yellow ones come from the project. They are just factory beans to provided the appropriate configuration.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/onsoranje-hippospringconfig.png" alt="onsoranje-hippospringconfig.png" border="0" width="449" height="457" /></p>
<p>Next step is to have a look at the actual spring configuration:</p>
<pre class="brush: xml; title: ; notranslate">
&lt; ?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&quot;&gt;
    &lt;bean id=&quot;connectionProps&quot; class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;&gt;
        &lt;property name=&quot;locations&quot; value=&quot;file:${config.dir}/connection.properties&quot;/&gt;
        &lt;property name=&quot;placeholderPrefix&quot; value=&quot;$con{&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;contentConnector&quot; class=&quot;nl.jteam.knvb.integration.hippo.HippoContentConnector&quot;&gt;
        &lt;property name=&quot;webdavService&quot; ref=&quot;webdavService&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;hippoCachingService&quot; class=&quot;nl.hippo.client.caching.service.CachingServiceImpl&quot;&gt;
        &lt;constructor -arg index=&quot;0&quot;&gt;
            &lt;bean class=&quot;nl.hippo.client.caching.JCSDefaultCache&quot;&gt;
                &lt;constructor -arg value=&quot;default&quot;/&gt;
            &lt;/bean&gt;
        &lt;/constructor&gt;
        &lt;constructor-arg index=&quot;1&quot; ref=&quot;hippoEventAwareManager&quot;/&gt;
        &lt;constructor-arg index=&quot;2&quot; value=&quot;default&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;hippoEventAwareManager&quot; factory-bean=&quot;updateNotificationService&quot; factory-method=&quot;getEventAwareManager&quot;/&gt;
    &lt;/bean&gt;&lt;bean id=&quot;updateNotificationService&quot; class=&quot;nl.hippo.client.event.service.UpdateNotificationServiceImpl&quot;
          init-method=&quot;start&quot;&gt;
        &lt;constructor -arg index=&quot;0&quot; ref=&quot;updateNotificationConfigFactory&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;webdavService&quot; class=&quot;nl.hippo.client.webdav.service.WebdavServiceImpl&quot;&gt;
        &lt;constructor -arg index=&quot;0&quot; ref=&quot;webdavConfig&quot;/&gt;
        &lt;constructor -arg index=&quot;1&quot; ref=&quot;hippoCachingService&quot;/&gt;
        &lt;constructor -arg index=&quot;2&quot; value=&quot;true&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;webdavConfig&quot; class=&quot;nl.hippo.client.webdav.WebdavConfig&quot;&gt;
        &lt;constructor -arg index=&quot;0&quot; ref=&quot;webdavConfigFactory&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;webdavConfigFactory&quot; class=&quot;nl.jteam.knvb.integration.hippo.WebdavConfigFactorybean&quot;&gt;
        &lt;property name=&quot;webdavFilesPath&quot; value=&quot;$con{webdav.filesPath}&quot;/&gt;
        &lt;property name=&quot;webdavHost&quot; value=&quot;$con{webdav.host}&quot;/&gt;
        &lt;property name=&quot;webdavNamespace&quot; value=&quot;$con{webdav.namespace}&quot;/&gt;
        &lt;property name=&quot;webdavPassword&quot; value=&quot;$con{webdav.password}&quot;/&gt;
        &lt;property name=&quot;webdavPort&quot; value=&quot;$con{webdav.port}&quot;/&gt;
        &lt;property name=&quot;webdavProtocol&quot; value=&quot;$con{webdav.protocol}&quot;/&gt;
        &lt;property name=&quot;webdavRealm&quot; value=&quot;$con{webdav.realm}&quot;/&gt;
        &lt;property name=&quot;webdavUsername&quot; value=&quot;$con{webdav.username}&quot;/&gt;
    &lt;/bean&gt;
    &lt;bean id=&quot;&lt;strong&gt;updateNotificationConfigFactory&quot;class=&quot;nl.jteam.knvb.integration.hippo.UpdateNotificationConfigFactorybean&quot;&gt;
        &lt;property name=&quot;jndiInitialContextFactory&quot; value=&quot;$con{jndi.initialContextFactory}&quot;/&gt;
        &lt;property name=&quot;jndiProviderURL&quot; value=&quot;$con{jndi.providerURL}&quot;/&gt;
        &lt;property name=&quot;jmsConnectionFactory&quot; value=&quot;$con{jms.connectionFactory}&quot;/&gt;
        &lt;property name=&quot;jmsPassword&quot; value=&quot;$con{jms.password}&quot;/&gt;
        &lt;property name=&quot;jmsUsername&quot; value=&quot;$con{jms.username}&quot;/&gt;
        &lt;property name=&quot;jmsTopic&quot; value=&quot;$con{jms.topic}&quot;/&gt;
        &lt;property name=&quot;jmsReconnectDelay&quot; value=&quot;$con{jms.reconnectDelay}&quot;/&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p>You can see from the config we make use of factory beans (webdavConfigFactory) and factory methods (hippoEventAwareManager). That is the most important part of the spring configuration. We now have a fully configured ContentConnector that knows how to do stuff with the hippo repository. Some of the methods that are implemented are the following:</p>
<pre class="brush: java; title: ; notranslate">
DomDocument obtainDocumentByPath(String path);
DomDocument obtainDocumentByUUID(String uuid);
&lt;t extends BaseDasl&gt; CollectionResults obtainDocumentCollection(
    T dasl, boolean completeDocument);
void deleteDocument(String path);
void createDocument(String relativePath, InputStream content);
void updateMetadataForDocument(String relativePath, Property[] props);
</pre>
<p>The last part is using the content connector to actually obtain items from the repository. There are some things you need to take care of, one of them being obtaining data from the returned data. You probably need to do some marshalling and unmarshalling. We used an abstract class to make it easier to create dao classes. The next piece of code is a method from the abstract class, just to give an indication.</p>
<pre class="brush: java; title: ; notranslate">
protected T findItem(String path) {
    DomDocument foundDoc = getContentConnector().obtainDocumentByPath(path);
    if (foundDoc == null) {
        throw new ResourceNotFoundException(&quot;Request not found: &quot; + path);
    }
    return unmarshalHippoDoc(foundDoc);
}
</pre>
<p>That is about it for this blog item. The source is not available online like usual, if you have additional questions, please use the comments.</p>
<p></t></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2008%2F07%2F06%2Fintegrate-hippo-cms-into-a-spring-application%2F&amp;title=Integrate%20hippo%20cms%20into%20a%20spring%20application&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2008/07/06/integrate-hippo-cms-into-a-spring-application/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

