martes, 27 de febrero de 2007

RoundCube vs SquirrelMail

I've been thinking for a couple of weeks about revamping the website (Internna). It was done a couple of years back and I really think it needs an upgrade for multiple reasons. I'm quite aware that it doesn't really fit the company anymore (if it ever did) and it's too static to be worth of visiting. Being just in Spanish is another reason, of course.

For those of you that don't know it already, Alfresco has released version 2.0 of their Content Management Suite. It finally includes a production ready WCM (Web Content Management) module. JBoss Portal was another tool I had the pleasure to work with some months ago. And both of them can work side by side quite well (or so they say). I think they can become a powerful backend for what I'm looking for.

Yesterday, when browsing the web a little I noticed one thing more. If I am revamping the web I should be revamping the webmail client as well, shouldn't I? That got me in the SquirrelMail site. Squirrelmail is a nice webmail client written in PHP. It relies on an IMAP server and offers a good looking frontend (see some screenshots). I have been using it for years now. My last installation was on Nov 2005.

Doing a quick search through the Squirrelmail website I noticed that nothing had changed in the last year or so. I could download an updated package but the visuals where quite the same. Too little to consider it worth something.

As I wanted something more, I started to look for options on the LAMP (Linux, Apache, MySQL, PHP) camp. I quickly found Horde and Zibra. Both are good but the one that got me hooked was RoundCube!

RoundCube is an AJAX frontend to your mail server. And a nice looking one! There's a demo available here. The only thing that got me worried was the beta status (but we are in the google days so...). Dont' be fooled by that, it works :-)

The installation was simple and clear (well, it is if you have already installed Apache/PHP, MySQL and a mail server, Qmail it is). I just needed to create a new database and some tables, rename two files, edit the server location and that was all. In less than 30 minutes I had it working.

Only one thing was missing, user approval. Nothing to worry really. It was love at first sight...

If you have a working Squirrelmail installation today my advice is to try RoundCube. It can even work side by side with Squirrelmail, just install to another dir. Demo it to some users and ask for feedback. You'll be surprised.

miércoles, 21 de febrero de 2007

Generic queries with JPA

Chances are that if a project is developed with Java EE 5 the persistence API is handled with JPA. JPA has clearly been a step forward from entity beans, moving to a POJO model. It leverages a lot of the new Java 5 language features as well, in particular it makes use of annotations and generics. I would like to focus a little on generics today.

Peeking at the EntityManager API shows some a handful of functions that return a generic type, in particular those that work with just one entity of the persistence layer.

Method Summary
   <T> T   find(Class<T> entityClass, Object primaryKey)
                    Find by primary key.
   <T> T   getReference(Class<T> entityClass, Object primaryKey)
                    Get an instance, whose state may be lazily fetched.
   <T> T   merge(T entity)
                    Merge the state of the given entity into the current persistence context.
   void     persist(Object entity)
                    Make an entity instance managed and persistent.

When working with collections everything is transparent to the developer as everything is being managed by JPA itself. It works with generics equally well.

There is one API that doesn't show this behaviour though and it is the Query API. Taking a look at the Javadocs it shows that the involved functions return a List and not a List<?>.

Method Summary
   List     getResultList()
                    Execute a SELECT query and return the query results as a List.

The reason behind this is simple. The function takes no arguments and returns a collection of something that is just unknown. It could be anything really. But, in practice, this not always holds true as many times the return type is known, as is collection of one of the defined entities.

When using JPA entities in a EE environmet is usual to create a facade or proxy to access them and hide the details. You can take advantage of this, adding new functionalities and generifying your collections there. To do it just create a new interface to handle undefined (any) classes:

public interface Facade {

   public final int minOffset = 0;
   public final int maxResults = 50;

   public <T> List<T> findAll(Class<T> entityClass);
   public <T> List<T> findByQuery(String query, Class<T> entityClass);
   ...
}

And wrap the EntityManager functionality with the implementation:


@Stateless
@Local(Facade.class)
public class GenericImpl implements Facade, Serializable {

   @PersistenceContext private EntityManager em;

   private List find(Query query, int offset, int maxResults) {
      if (offset > 0) query.setFirstResult(offset);
      if (maxResults > 0) query.setMaxResults(maxResults);
      return query.getResultList();
   }

   public <T> List<T> findAll(Class<T> entityClass) {
      String queryName = this.getQueryName(entityClass, "all");
      return findByQuery(query, entityClass);
   }

   @SuppressWarnings("unchecked")
   public <T> List<T> findByQuery(String queryName, Class<T> entityClass) {
      Query query = em.createNamedQuery(queryName);
      return (List<T>) find(query, minOffset, maxResults);
   }

   ...

}

domingo, 18 de febrero de 2007

Transparent client-side validation with DWR & Spring MVC

Update:The approach and the code available here is a little bit outdated (although still very usable). A newer entry, involving also how to create a generic Validator, is available here

Last week I read an article at java.net about Ajax Form Validation Using Spring and DWR written by Eric Spiegelberg (you should have read it before continuing). I thought the approach was really interesting, exposing your Spring MVC Validators with DWR so they would handle the client side validations as well.

This would be achieved by formatting your validators adequately, creating a function for each field to be validated and then adding some special invocation code that could be called by DWR.

I didn't like the implementation offered though for two reasons mainly, it was very intrusive (a lot of code was added to the Validator) and it forced to configure each Validator in DWR (a lot of work if the number of entities is huge). I thought a more generic style could be managed.

Explaining how it works can get somehow complicated so I will start providing an example. Remember that the full source code and a working example can be downloaded from Internna - Google Code. These are the steps needed to expose your validator:
  • Add the library to your project. Alternatively, just add the needed classes (just a few)
  • Create a Validator. It should implement ClassAwareValidator and follow the format already explained (in the beforementioned article at java.net).
  • Add the following line to your Spring XML:
    <import resource="classpath:dwr/mvc-dwr.xml" />
  • Add the validation function to your JSP
And that's all. Here's an example:

public class TrivialValidator extends AbstractClassAwareValidator {

   public Class getSupportedClass() {
      return TrivialObject.class;
   }

   public void validate(Object object, Errors errors) {
      validateTrivialField(errors);
   }

   public void validateTrivialField(Errors errors) {
      ValidationUtils.rejectIfEmptyOrWhitespace(errors,
                     "trivialField", "Trivial field is requiered");
   }
}

I'll try to explain how the entrails work now. There's a class (DWRValidator) that handles 90% of the work. It has a function validate(fieldname, fieldvalue) that will be exposed to DWR. This function mimics the work Eric Spiegelberg defined but in a more generic way. It will handle all the validators in the system at once (see AbstractValidatorHolder). The trick is done parsing the fieldName. In your JSP your form fields should indicate the class and field they represent!

The rest of the work is done by AnnotationUrlHandlerMapping class. There's a function configureValidators(applicationContext) that will automatically search for all the validators in the context and add them to the DWRValidator so it can manage the calls correctly.

private void configureValidators(ApplicationContext context) {
   Map beans = context.getBeansOfType(ValidatorHolder.class);
   if (beans != null) {
      for (Object beanName : beans.keySet()) {
         ValidatorHolder holder = (ValidatorHolder) beans.get(beanName);
         Map validatorBeans = context.getBeansOfType(Validator.class);
         for (Object validatorBeanName : validatorBeans.keySet())
            holder.addValidator(validatorBeans.get(validatorBeanName));
      }
   }
}

The last step involved is adding the validator to the context. Two files are provided (mvc-dwr.xml and simple-mvc-dwr.xml), use one or the other depending on if you have already define a dwrController and the mappings or not.


jueves, 15 de febrero de 2007

A faster and easier approach to the @Bean annotation

If you know or have worked with the Spring Annotations project, you would agree with me that one of the most interesting features, at least at first glance, is the @Bean annotation. This annotation allows a developer to declare Spring beans directly in the source code and let them work side by side with the ones declared in XML files.

Some people argue about this mix of configuration and even I don't use it in profusion. But there are some beans that are perfect candidates for this kind of use. Interceptors for example. Or those beans that are just defined without been wired to anything. Or basic dependencies. On the other hand there are many complex situations where using the XML definition format is just clearer (Spring 2.0 helped aswell), as it offers one common repository to study in case of problems.

Up until now, the @Bean annotation implementation code was quite complex. It needed a propietary XSD schema and took some very obscure and scarcely documented paths. It was difficult to understand and to maintain. To put it bluntly, it needed an update.

To understand how the new code (everything is packed in just one class) works you need a grasp of the following concepts:
  • ApplicationContext (Reference, API): The application context is the holder of everything constructed in Spring. The base of the IoC concept.
  • ApplicationContextAware (API): Everytime a bean that implement this interface is deployed in a context, Spring will automatically inject a reference to the context itself. Although useful, it breaks one of the Spring principles (being non-invasive), so do not abuse
  • BeanFactoryPostProcessor (Reference, API): Extension point for the framework. It provides callback methods that will be invoked once the bean definitions have been loaded but before the beans are instantiated.
  • ConfigurableListableBeanFactory(API): The only parameter provided when the postprocessor is invoked. It can get bean definitions from the context.
  • BeanDefinitionRegistry(API): Interface needed to register new beans that will be instantiated.
  • DefaultListableBeanFactory(API): The existant implementation class for ConfigurableListableBeanFactory. It happens to implement BeanDefinitionRegistry aswell.
  • Resource(Reference): Spring access to low-level resources. In our case, classes in the classpath.
  • RootBeanDefinition(API): The basic type of bean definition.
First of all, you can get the full source here. The involved packages are es.internna.spring.annotations and es.internna.spring.context. I won't post here the full source but the interesting part.

postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory){
   if (BeanDefinitionRegistry.class.isInstance(configurableListableBeanFactory)) {
      BeanDefinitionRegistry registry =
               (BeanDefinitionRegistry) configurableListableBeanFactory;
      for (String packagePattern : includePath) {
         try {
            Resource[] resources =
                     this.applicationContext.getResources(packagePattern);
            for (Resource resource : resources) {
               Class clazz = loadClass(
                     configurableListableBeanFactory.getBeanClassLoader(),
                     packagePattern, resource);
               Bean bean = clazz.getAnnotation(Bean.class);
               createAndRegisterBean(registry, clazz, bean);
            }
         } catch (IOException ex) {
            if (log.isErrorEnabled())
               log.error("Error retrieving " + packagePattern + " resources");
         }
      }
   }
}

90% of the magic happens here. This method will be invoked by Spring directly after reading all the beans. The parameter (a DefaultListableBeanFactory at runtime) always happen to implement BeanDefinitionRegistry so it will allow us to register new beans in the context (remember that this is done before initialization). Just need to find and load the actual beans. The application context can scan the classpath and return a pointer to the resource (even if it is packed in a jar file). This resource, once loaded as a class, has to be probed. If it was annotated it should proceed to register the bean.

To use it in a project, just declare the post-processor in an XML including (important) the paths to be scanned

<bean class="es.internna.spring.context.AnnotatedBeanRegistry">
   <property name="includePath">
      <set>
         <value>classpath*:es/internna/**/*.class</value>
         <value>classpath*:com/myclasses/**/*.class</value>
      </set>
   </property>
</bean>

Remember the code was submitted to the Spring Annotations project so it will eventually be released there. Until then you can download full sources and examples at Internna - Google Code

sábado, 10 de febrero de 2007

AOP / AJAX Enabled Controllers in Spring MVC

There are two reasons that make me select Spring MVC when I have to start a project, the first one being robustness and the second being seamless integration with the rest of the components. There are two reasons aswell that I sometimes miss, the first one being (annotated) AOP in my controllers and the second a better handling of AJAX requests.

As is known, AOP in the Spring framework is based on dynamic proxies. Spring will create a proxy to an object when needed and then intercept the calls applying the declared advices. As a side effect, Spring cannot intercept anything that it didn’t wire from the start. When working with Spring MVC the main interface to use is Controller which provides a method handleRequest to perform actions. Any controller that gets declared can be wired later to a DispatcherServlet. So far so good, you can intercept the execution of the handleRequest method an apply whatever aspects you need (in my case Security and Logging are a must). Unfortunately working with Controller directly is sometimes not enough as it provides little functionality. The framework can offer more power (MultiActionController, SimpleFormController) but it won’t come without price as the handleRequest method is lost (implemented and declared final) and with it the possibility of annotating it with your aspects.

On the other hand there’s just no meaningful AJAX integration. Fortunately DWR solves this quite nicely (and even better since 2.0). When using DWR in conjunction with Spring there’s one thing that still bothers me and it is, no other, than not complying with the DRY principle, having to declare both Controllers for the MVC and DWR beans for AJAX doing the same actual work.

From now on I’ll try to offer a solution that can combine a little bit of everything. Full sources and a working example are available at Internna - Google Code.

To start, some interfaces need to be defined. They will come handy later to wire everything together:

public interface RequestHandler {
   public void addMapping(String urlMapping);
   public void addMappings(Collection urlMappings);
   public void setMappings(Set urlMappings);
   public Set getUrlMappings();
   public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception;
}

public interface AdvisableController extends Controller {
   public void addRequestHandler(RequestHandler requestHandler);
   public void addAllRequestHandlers(Collection requestHandlers);
   public void setRequestHandlers(Set requestHandlers);
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface UrlMapping {
   String value();
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AutowireToController {
   String controllerBean() default "";
   Class controllerClass() default AutowireToController.class;
}

As you can see the first two define the new logic and the second are just annotations (they will be used later to simplify the XML definitions). AdvisableController (which extends Controller) will be the root of our Controller hierarchy. It will provide beans compatible with the rest of the MVC and usable by the DispatcherServlet. RequestHandler defines the characteristics needed to actually execute the business logic.

Each of the interfaces come with an abstract class that implements the core functionality. AbstractRequestHandler basically manages the URLs this bean handles. The business logic should be coded in a subclass. AbstractAdvisableController role is to determine which of the available handlers should process a request. If no suitable handler is found it returns a 404 error. This class should be subclassed to add bindings or mappings for example. The important code is reduced to the following:

public final ModelAndView handleRequest(HttpServletRequest httpServletRequest,
  HttpServletResponse httpServletResponse) throws Exception {

   String controllerPath = httpServletRequest.getPathInfo();
   for (RequestHandler handler : this.requestHandlers) {
      if (canHandle(controllerPath, handler.getUrlMappings()))
         return handler.handleRequest(httpServletRequest, httpServletResponse);
   }
   httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
   return null;
}

We are half way to achieve our first goal. Simply by defining two classes that extend the abstract ones we can have an advised MultiActionController working. Let's see an example:

//Just subclassed to add a mapping
@UrlMapping("/internna/*")
public class MultiActionAdvisableController extends AbstractAdvisableController {}

@UrlMapping("/nocalc.mvc")
@AutowireToController(controllerBean="multiaction")
public class NoCalculatorRequestHandler extends AbstractRequestHandler {

   @LogDebug(loggerClass=SampleRequestHandler.class)
   @PermitAll
   public ModelAndView handleRequest(HttpServletRequest request,
                     HttpServletResponse response) throws Exception {
       Map m = new HashMap();
       m.put("calculator", 0);
       return new ModelAndView("reached", m);
   }
}

// New declarations in the bean definition XML
<bean id="noCalc" class="samples.NoCalculatorRequestHandler" />
<bean id="multiaction" class="samples.MultiActionAdvisableController" />

Since release 2 DWR works even more nicely with Spring and Spring MVC. The configuration has changed so it is possible to define everything within Spring, getting rid of changes in web.xml or dwr.xml. See Bram Smeets Blog for a detailed explanation. With this in mind our task now is to integrate our MVC controllers with the DWR one. This is done creating a very simple wrapper class:

public class DWRWrapper {
   private RequestHandler requestHandler;

   public void setRequestHandler(RequestHandler requestHandler) {
      this.requestHandler = requestHandler;
   }

   public Map getResult(HttpServletRequest request) throws Exception {
      return requestHandler.handleRequest(request, null).getModel();
   }
}

At this point with an adecuate configuration our controllers can be both used in Spring MVC and in DWR without changing anything.

<dwr:controller id="dwrController" debug="true" />

<bean id="calculatorWrapper" class="es.internna.spring.mvc.DWRWrapper">
   <dwr:remote javascript="CalculatorWrapper" />
   <property name="requestHandler" ref="noCalc" />
</bean>

Don't forget to add the needed schemas and map correctly the paths needed by the DWR controller in the dispatcher servlet. In my case I had to map /engine.js, /util.js, /interface/CalculatorWrapper.js and /call/**

Once done, your controllers can be easily annotated with aspects and used directly in DWR, and in an easy way to boot! Remember to download full source code and examples at Internna - Google Code.


miércoles, 7 de febrero de 2007

Wrapping Alfresco with Spring MVC

Alfresco is a Content Management System (see here for a definition) written in Java that is gaining momentum because of multiple reasons right now. One of the most compelling, at least for the development crew, is being Open Source software, of course. As of today, it offers a good suite of integrated functionality, shining its Document Management (see) capabilities above all. Though the rest of the list is also promising, including Collaboration, Records Management, Knowledge Management, Web Content Management and Imaging.

It’s not farfetched to say that data manipulation is the principal role an application has to handle. Data may come in different flavours and one of the most common are files. Even though you can deal with them quite easily in Java, if the gross volume and the requirements grow it’s better to rely in a dedicated subsystem just as you would do when dealing with structured data and a database.

Alfresco offers right out-of-the-box, a powerful solution for managing both users (and groups) and documents that is very useful in a stand-alone configuration but not that much if you have to combine it with an existing security model. Imaging having to create thousands (or more) of workspaces to store documents for a user a then creating the links between them. Cumbersome, no doubt, a better alternative has to exist.

One of the most interesting features that Alfresco packs is embedding a full-featured server inside your application. As Alfresco is itself a Spring application is quite easy to load it sharing the application context and wire everything together. There’s just one setback, the performance may not meet your expectations. If your application is already a beast adding more workload (and an important one nonetheless) could easily become just too much. Deploying Alfresco in another server just seems right. The challenge is to share the context (or at least mimic it) while still getting a good deal performance wise.

The best solution I came across was to proxy Alfresco and require usage tickets. I’m going to post an image of the architecture and then I’ll proceed to explain it a little.

As you can see two new applications appear. The first one is deployed in the same AS as your existing code and the second will be deployed in other server. This second server can just be a servlet container (read Tomcat) if you prefer.

The flow is as follows:
  • A client requests something (ie, an upload) to the document server
  • The client recieves a HTML page with the form
  • Automatically the page tries to retrieve a ticket from the AS (via AJAX)
  • The server creates and stores a ticket, then sends a unique ID to the client
  • The user submits the form with an attached file to the document server
  • The request is intercepted. The provided ticket is examined.
  • The file is transferred to Alfresco based on the information available in the ticket

The first application is in charge of creating tickets for each action (download, upload, search...) that will be later requested in the document server (a ticket is no more than an object that contains information that can be later checked to allow or deny access to Alfresco) It leverages the fact that you can share the authentication state of a user between all the installed applications in a security realm (see Glassfish for example). The application itself is very easy, it will just answer an AJAX request (see DWR) creating and storing a new ticket. In this implementation it uses an EJB3 to generate unique UUIDs (optional).

<script src='/[your_app]/dwr/interface/TicketManager.js'></script>
<script src='/[your_app]/dwr/engine.js'></script>
<script src='/[your_app]/dwr/util.js'></script>
<script language="javascript">
   function generate() {
      TicketManager.getTicketId(loadinfo);
   }

   function loadinfo(data) {
      DWRUtil.setValue("generatedValue", data);
   }
</script>

<dwr>
   <allow>
      <create creator="spring" javascript="TicketManager">
         <param name="beanName" value="ticketManager"/>
      </create>
   </allow>
</dwr>

<bean id="hex" class="es.internna.utils.impl.HexadecimalImpl" />

<jee:jndi-lookup
   id="UUIDEJB"
   jndi-name="uuid"
   resource-ref="true"
   cache="false"
   proxy-interface="es.internna.utils.UUID"
/>

<bean id="ticketManager" class="es.internna.alfresco.TicketManagerImpl">
   <property name="encoder" ref="hex" />
   <property name="generator" ref="UUIDEJB" />
</bean>

The second application only has to retrieve the ticket (this can be done with an interceptor for example) and operate if it's valid. The only difficulty here is to configure an Alfresco server inside your application. You have to download Alfresco SDK to start (my recommendation is to install an Alfresco server first). Extract it and add the jars from the lib/server directory to your classpath. Then in your *-servlet.xml add the folllowing lines to import the context (remember that Alfresco currently only supports Spring 1.2 and this is 2.0 syntax):

<bean id="ticketValidator" class="es.internna.validators.TicketValidator" />

<bean id="ticketInterceptor" class="es.internna.mvc.TicketInterceptor">
   <property name="validator" ref="ticketValidator" />
</bean>

<bean id="alfrescoUploader" class="es.internna.alfresco.ContentUpload">
   <property name="serviceRegistry" ref="serviceRegistry" />
</bean>

<bean id="fileUploadController" class="es.internna.mvc.FileUploadController">
   <property name="commandName" value="fileUploadBean" />
   <property name="commandClass" value="es.internna.domain.FileUploadBean"/>
   <property name="formView" value="fileuploadform"/>
   <property name="successView" value="confirmation"/>
   <property name="alfresco" ref="alfrescoUploader" />
</bean>

<import resource="classpath:alfresco/application-context.xml" />

<bean id="repository-properties"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="ignoreUnresolvablePlaceholders" value="true" />
   <property name="order" value="1" />
   <property name="locations">
      <list>
         <value>classpath:alfresco/alfresco-shared.properties</value>
         <value>classpath:alfresco/repository.properties</value>
         <value>classpath:alfresco/version.properties</value>
         <value>classpath:alfresco/domain/transaction.properties</value>
         <value>classpath:newalfresco.properties</value>
      </list>
   </property>
</bean>

Override the minimum properties (in a file called newalfresco.properties in this case):

dir.root=D:/Alfresco/alf_data
db.pool.initial=2
db.pool.max=5
db.username=alfresco
db.password=alfresco
db.driver=org.gjt.mm.mysql.Driver
db.url=jdbc:mysql://localhost/alfresco

And that's all. The next time that you start your application, Alfreso will be started aswell (beware it takes some time) and injected in your MVC context, ready to be used. Sample code is provided in the Alfresco SDK, look at the FirstFoundationClient to begin.