Stripes on Rail

I have yet to become a Ruby fan. But it does make me, a Java developer, envy some of its perceived simplicity. I do want a framework that is flexible and configurable. I do want my Java compiler and IDE catching errors for me at compile time or before that. There are a few frameworks out there currently that put together many other frameworks and has the ability to generate CRUD code: JBoss IDE for JBoss Seam? Appfuse's Appgen for variety of frameworks.

But sometimes I can't help but to think if we can get any simpler? I say yes we can! How simple can we get? Obviously, from the basic domain entity classes, we should be able to generate at runtime all the things we ever need for basic CRUD operations (including screen, sql). This has been done and that's what made other frameworks (even language) popular. However, we are Java developers. We want to do this while maintaining good multi-teired POJO architecture and its flexibility!

For this, we need to look in to quite a few currently available technology:

  1. Spring
  2. Stripes
  3. Hibernate
  4. EJB3
  5. Maven2

Spring

What! Wasn't this suppose to be easy? Do we really have to write XML? The answer is of course not! Well, maybe for a few configuration issues. But that's another issue we'll deal with in Maven2 profile. But we do need Spring to tie all the frameworks together while maintaing flexibility in the future when necessary. The default Spring configurations can be encapsulated in a Jar file so that no body really need to edit it for the default behavior. Moreover, we can use Acegi Security for authentication. Of course, this default confdiguration is encapsulated as well.

Stripes

Stripes is a light and simple framework that takes advantages of Java 5 Annotations while keeping away from what I call "annotation hell". With Stripes, we can easily extend its ActionBean and ActionResolver facilities. What this means is that we can creat a GenericCRUDActionBean like:

public interface GenericsCRUDActionBean<T> {

public T getEntity(); // single

public void setEntity(T entity);

public List<T> getEntities(); // multiple entities, such as query results

public setEntities(List<T> entities);

public Resolution save(); // event

public Resolution query(); // event

public Resolution delete(); // event

}

ActionResolver can be used to automatically determine what ActionBean is to be instantiated for a URI request. For example, /context/Person.action will automatically instantiate a new GenericsCRUDActionBean<T> and serve the incoming request.

Moreover, quite remarkable jobs has been done with Stripes form generation by community members that can generate HTML forms from ActionBeans. Associations are also taken into account. We can further extend this to use DOJO widgets for property types such as Date (DOJO date picker). Moroever, we can also generate DOJO validation attributes from Stripes' Validation annotation or other validation oriented annotations.

EJB3

To stay away from XML configuration, we can use EJB3 annotations for entity beans, a.k.a. domain classes. To further staying away from EJB3 descriptors, we can use Hibernate for ORM. Not only that, we dont' even need to write hibernate.cfg.xml to declare what domain classes should be mapped! The reason is that we can resolve EJB3 annotated entity beans the same way Stripes resolve its ActionBeans. Stripes annotation resolver utility can be easily integrated into a new Spring bean that extends AnnotationHibernateSessionFactoryBean.

Hibernate

Generics DAO pattern already exist for Hibernate. Thus, there can be a class GenericsDAO<T> that looks like:

public interface GenericsDAO<T, ID> {

public void save(T entity);

public void findByExample(T example);

public void delete(ID id);
}

What about the Service Layer?

By default, similar GenericsManager<T, ID> can be implemented that delegates to GenericsDAO<T, ID>. Although not strictly necessary, but it may help enforce some architectural consistency if one decided to get away from these Generics stuff. After all, they are generic!

Maven2

Maven2 can help in the overall build, test, and deploy process. Specifically, I'm looking at Maven2 in the following areas:

  1. Configuration (profile.xml)
  2. Build and Packaging (into deployable WAR file)
  3. Dependency (let's see… stripes, hibernate, ejb3, spring, acegisecurity, …)
  4. Testing and Reports (All kinds of reports in test results, code quality, documentations, todos, …)
  5. Archetype (Who wants to rewrite all these? Create the whole project from the archetype!)
  6. Execdution (Jetty6 plugin seems very promising. One can execute a web project using just one command)

Basically, with Maven2, this is what we do to get started:

  1. mvn archetype:create ……. (create a new project with all the default pom.xml, directory structure, dependencies, report requirements, site generations, packaging details, and of course, Jetty6 plugin to execute the whole thing for immediate results)
  2. Create a domain entity class, e.g. a Person class.
  3. mvn jetty6:run (compile and run the application! go to http://localhost:8080/project/Person.action to see it in action)

That should be the MOST that one should need to do. Database generation and initial data loading can be configured to execute at deployment/initialization time. These can also be done via command line such as mvn hibernate:schemaExport, mvn dbunit:loadData (via corresponding plugins).

Now suppose we make this even simpler:

  1. createProject com.nooton.webapp my-webapp
  2. @Entity public class Person { @Id public Long id; public String name; public String address; }
  3. runProject
  4. http://localhost:9090/my-webapp/Person.action

That's all.

Abstract DAO

In this architecture, one is free to implement their own DAO, Manager, or ActionBean. We can make the DAO implementation job easier by introducing Abstract DAO annotation from previous idea and implementation. So in case one really needs to do some custom queries, one can annotate the query to an abstract method, rather than getting into Hibernate details (getHibernateTemplate()… throw exceptions…) 

Conclusion

Whew! There are obviously many frameworks that would need to be integrated. But the good news is, most of the integration are probably done daily for a new project based with Spring, Hibernate, and similar tools. While this "framework" can allow quick implementations of simple CRUD web applications, it is based on the entire POJO stack that can be easily extended to the extent that any other similar project structure can extend to. It does not pose any restrictions on the entire application coding "convention". In fact, if one really want to use another framework for any layer, it is possible to completely swap the entire layer out with Spring configuration.

About these ads

One comment

  1. Pingback: Ray Tsang’s Blog » Blog Archive » Prototype


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s