JSF Central - Alfresco Chooses JSF for Enterprise Content Management System
JSF Central

 
 Home 
 
 Products 
 
 Articles & Books 
 
 Resources 
In the Trenches
 
Alfresco Chooses JSF for Enterprise Content Management System
by Gavin Cornwell, Kevin Roast
27 Jul 2005 18:00 EDT

In the Trenches is a series about real world projects that use JavaServer Faces (JSF). In this article, two developers of the new open-source content management system, Alfresco, discuss how JSF is used in their architecture.

If you've completed a JSF project, or you're substantially into a new project, we'd love to hear from you! Send an e-mail to trenches@jsfcentral.com describing your experiences -- the good and the bad -- and we may include your story in a future In the Trenches article.

When we began work on Alfresco, our Open Source Enterprise Content Management System, we had two requirements. Firstly, to build a web-based client that would run as a portlet from within a JSR 168 Portal environment, and secondly run as a standard web application (see figure 1). Further, the application needed to be easily customizable and extendable by developers. Java Server Faces appeared to be the natural choice due its event-based architecture, standardized component model and the promise of rich tool support. The majority of our development team had previously worked on defining the architecture for Documentum's Web Development Kit, which takes a very similar approach to JSF. In fact, some of the representatives of the team were members of the JSF expert group, so we knew we were taking the correct architectural approach.

  Figure 1. Alfresco utilizes JSF to provide an attractive, easy-to-use, web-based interface.
Figure 1. Alfresco utilizes JSF to provide an attractive, easy-to-use, web-based interface.

The Alfresco repository uses the latest open source technologies at its core, including Spring, Hibernate and Lucene. Repository capabilities are exposed as a set of services, and to inject behavior, aspects such as transaction management, security, versioning and auditing are employed. Each service is exposed as a Spring bean with a well defined interface, allowing the web client to use standard JSF support to bind and communicate with the repository (see figure 2). Because of the modular architecture of the repository, it is possible to upgrade, replace and extend its capabilities for the particular business requirement at hand. By default, the repository supports a wide range of content management services such as content and meta-data storage, powerful search, categorization, versioning, workflow and rules. The implementations have been designed with performance in mind, with services lending themselves to a more stateless approach, ideal for any client that needs to scale the application.

The Alfresco client development team consisted of Gavin Cornwell, Kevin Roast, Paul Holmes-Higgin (as project lead), and Linton Baddeley, a graphical designer and user interface specialist. Using JSF, we were able to build the first client from scratch in three months - much faster than it would have taken using other web-based frameworks. Due to the flexibility of the JSF framework, the client runs seamlessly as both a JSR-168 portlet inside JBoss Portal 2.0 and as a plain JSP/servlet based web application inside Tomcat 5,. Our development environment is Eclipse and Ant on MS Windows, using JBoss Portal 2.0 and Tomcat, both with MySQL. We also provide and test deployments on Linux.

  Figure 2. Alfresco's architecture takes a layered approach to integrating JSF, Spring, JBoss Portal, Hibernate, and Lucene.
Figure 2. Alfresco's architecture takes a layered approach to integrating JSF, Spring, JBoss Portal, Hibernate, and Lucene.

Foundation: MyFaces

We chose to use the Apache MyFaces implementation due to its large user community . We started with Sun's reference implementation, but we found several problems including issues with the browser back button and the lack of a file upload component.

Our switch to MyFaces was painless and required no code changes, proving the advantage of using a standards-based framework. However, even with this move we are still experiencing some minor issues with the back button, requiring users to click an action twice after performing a browser back action. We also found we could not use the MyFaces upload component as it doesn't fit into the constrained JSR 168 portal architecture. This is due to the fact that MyFaces relies on a servlet filter to process the multipart form data, but servlet filters are not executed in a portal environment. Overall, however, we are pleased with the quality of the MyFaces implementation.

So far, we have avoided using any custom components that are specific to MyFaces because we were unclear about how well they would work with other JSF implementations (it has since become clear that the components are not tied to the MyFaces implementation). However, we have written several custom components to provide advanced navigation and presentation functionality for the Alfresco repository. For example, we have built a clipboard component for copying and pasting files and folders, a folder selector component, and a property sheet component for displaying meta-data of content objects.

We have also written a growing library of custom components that are completely independent of the repository. For example, we have written a data-list component that greatly extends the basic UIData concepts and allows multiple list rendering views onto the same dataset. We have also added a breadcrumb navigation component, a popup menu component, and a collapsible/expandable panel component. As they are independent from the repository, these components are all usable by anyone building a JSF application. They are in the source download of Alfresco, but still need documentation. We also intend to participate in JSR 276 to ensure that we expose these components to a wider audience. You can see the technology preview release of Alfresco for examples of all these components in use.

The Early Days: JSF Hell

In the early part of our development, we found ourselves entering what we termed "JSF Hell." We had believed we were well versed in JSF and at the top of the learning curve, only to find we were suddenly slipping back down into confusion as we hit another snag with the subtle nature and complicated lifecycle of the framework. This was caused by the somewhat confusing terminology and the sometimes overly flexible nature of JSF. We could build pages using standard components quickly, but we when we started creating custom components we were surprised to hit a fairly steep learning curve.

As with many flexible frameworks there can be more than one way to implement a solution, and it may be difficult to know what the "correct" approach is. For instance, since a component is also capable of implementing the rendering methods and managing the data-flow and processing events, even the renderer concept is optional. When implementing a new JSF class, you need to have a deep knowledge of the JSF component tree to know which standard component to use as a base class. It is not always clear whether you should create a new tag, a new component, or a new renderer. If you extend any of the existing classes you may find that you do not get the functionality you are looking for. You may also find that they apply unforeseen constraints on the way you work with your components.

There are many details about writing components that are not immediately obvious. For example, when using the component or renderer decode() method you should examine the submitted value before setting the components' value. You must then apply the submitted value if it has been set, the previous value if it exists, or a default value if there is no previous value. This level of knowledge can be confusing for the uninitiated.

Some of the JSF terminology caused confusion in the early days. One would expect component-type to be a class name, but it is actually an identifier that looks similar to a class name. We believe component-id would have been a better choice of name. The broadcast() method does not broadcast an event, it consumes an event. The renderer classes do not encapsulate pure rendering functionality; they render with additional responsibility of managing data-flow between the client response and the component instance that supports the renderer.

Success upon Mastery

Fortunately, once we reached the top of the learning curve, development progressed rapidly and it was a quick and easy process to add new pages to the application. The component model with its automatic state persistence, the friendly JSF navigation mechanism, powerful bean data-binding language and the relatively straightforward way of adding new custom components all helped this rapid development. The absence of multiple code lines supporting portal servers and servlet engine based web clients is a significant benefit. We envisage that JSF will be at the centre of our architecture for client applications in the future.

We found that the Command, Strategy and Singleton patterns fit nicely with our architecture. The Command style pattern, used throughout JSF for binding component action handlers, is a powerful means of separating the resulting action implementation from the component. We either extended or duplicated this same style of processing for our custom components. We often used the Strategy pattern, particularly in our custom components. For example, our UIRichList component interfaces use delegates to de-couple optional rendering mechanism from our core components. We plan to continue with this pattern by modularizing our client-side business code into a non-web-specific client-side service layer. This is useful where we make multiple granular calls to our repository for building complex client objects, such as a fully-fledged content document with attached rules and actions. Hopefully, this kind of approach will mean writing future clients is as painless as possible, with very little code duplication.

The feedback from people that have tried the technology preview of Alfresco has been very positive. It looks good, response is snappy and it is robust, thanks in part to the quality, flexibility and performance of JSF and the MyFaces implementation. Rather than complaining about what does not work, users provide us with feed back on new functionality they would like to see. Our experience with JSF makes us think we can deliver this functionality faster and more effectively than we have been able to in the past.




RSS feed(all feeds)

The Editor's Desk
Podcasts
Inside Facelets
In the Trenches

Site version 1.83  Report web site problems

Copyright (C) 2003-2014 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all Java-based marks are trademarks or registered trademarks of Oracle Corporation. in the United States and other countries. Virtua, Inc. is independent of Oracle Corporation. All other trademarks are the sole property of their respective owners.