Here is a brief tutorial on how to setup and object content mapping with Jackrabbit (1.5) and Spring.
First things first, download this zip and import the source into your project. As mentioned in this post support for Jackrabbit OCM in Spring still hasn’t found a home. Thus you have to download the zip from the JIRA.
The source includes an updated JackrabbitSessionFactory that we are going to reference in our Spring configuration.
I’ve realized that JAX-RS can be used to build a web applications based on the MVC pattern just like any other framework (Wicket, Stripes, etc). Typically I use JAX-RS to build services that return XML and/or JSON, but there is no reason I can’t return HTML as well. I feel that the hierarchal nature of RESTful services makes them perfect for delivering website pages too. The only thing that was missing for me was an HTML provider. I’m used to using the JAXB and JSON providers, and I didn’t see a built in one for rendering HTML. So, I decided to build a custom JAX-RS Freemarker provider.
A couple of weeks ago one of our clients asked me to prepare some documentation on the CQ/JCR RESTful services I had created for them.
I had previously came across this post on TSS about the latest release of enunciate. Unfortunately, I quickly forgot. Then Bill reminded me about it a couple days ago. He is working on a REST/Flex project and he too came across it. Its all coming together now.
While enunciate can do a variety of things, I was only interested in the generated JAX-RS/JAXB documentation (HTML). My personal opinion is that the generated documentation is not only useful but also well designed. As a colleague commented, it is pretty. Here is a screenshot of the documentation for JC-Rest.
I’m happy to announce the initial release of JC-Rest. This is an application that provides a set of RESTful services for accessing content in a JCR repository. These services can return XML, JSON, ATOM, or even HTML via custom FreeMarker templates.
http://code.google.com/p/jc-rest/
Back in June I wrote a post that talked about building RESTful services using CXF (JAX-RS), Spring, Spring Modules (JCR), and the JCR API. To sum it up, I was working with a client who was using CQ. It didn’t take long before several other applications all required access to the CQ content. Since CQ doesn’t provide an easy means to do this, I wrote a set of highly customized services to return the content. The services were written to meet the requirements of each individual client application that required specific content.
When all was said and done, I realized there was quite a bit of redundancy. Not only technically, but logically as well. I came to the conclusion that it would have been better to build a smaller set of abstract, generalized services. And then perhaps allow for some customization on top them. That is what led me to build JC-Rest.
InfoQ posted another article that caught my interest today. In short, it is a case study on the NASDAQ Market Replay application. It is built using Adobe AIR/Flex and Amazon S3. This happens to be very similar to the direction I’ve been wanting to take. I wanted to bring myself up to speed with Flex and I was currently working with a Day Communique (CQ) web site. So, I decided to build a small Flex front end to this web site. In this case, I did choose to add a few new selectors to existing templates and back them up with Servlets to expose the content as XML. I didn’t go with anything fancy here. It was just plain XML over HTTP. While I discussed using a separate Spring/JCR based application to do this for low level integration previously, I do think this is a fine approach if you just want to extend your web front end. I like Flex because of its native XML support. It is simply top notch. However, in this case my content was retrieved from CQ as opposed to S3. As a side note, I am currently working on a project that will use the Spring/JCR approach with Mule to copy content from the CQ media library to Amazon S3. To top it off, we’ll use a custom LinkChecker (com.day.cq.delivery.linkchecker) to rewrite the URLs that point to media library assets now in S3.
I have known for some time that the Spring Modules project has support for JCR integration. As it so happens, InfoQ has a nice introductory article on this very module. I have recommended to clients that future integration with CQ should revolve around direct communication with the repository itself. Well, I finally came across an opportunity to practice what I preach.
So I was asked to refine an existing piece of functionality where a separate application needed access to the content from CQ as XML. Naturally the CQ approach is to create a Servlet to start at a particular page and iterate through its children building the necessary XML. Then add a new selector to an existing template that uses this Servlet. The result was as follows.
/content/mysite/products.html (existing)
/content/mysite/products.data.xml (new)
One has to keep in mind that this products page does not contain the content for all of the products. Rather it acts like a placeholder for many nested product pages. So, this is why the Servlet would end up iterating through children of its starting page. Of course, the CQ search API could also have been used to retrieve the products. This would be much more efficient. However, this XML would contain much more than just the product content. It would contain additional content related to products that resides in referenced pages. So, even if you used to the CQ search API you would still have to then retrieve the ‘Page’ instance for each handle returned. Then for each ‘Page’ instance you would have to fetch the related ‘Page’ instances too. The search API is a little awkward though. While it may be more efficient, I can see that it was more natural to simply iterate through the children.
Within the Servlet, it would appear that the CQ approach is to use the PageToXML class provided by Day. So, each ‘Page’ was converted to XML. The resulting string was then written directly to the Servlet response.
The problem with this approach is that it is inefficient, difficult to maintain as the code is quite convoluted, and if the CQ Publish application is down the content is not available.
To refine this functionality I came up with a small list of goals.
1. Retrieve the content directly from the repository and bypass CQ.
2. Provide a true RESTful service, and not a ‘mock’ one.
3. Use a Java/XML binding framework.
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Oct | ||||||
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | |||