implements Elegance {

// Elwyn Malethan's musings on software development, mountain biking and general navel–gazing...

Articles tagged with 'seemorej'

Publishing in multiple Formats using SeemoreJ

I‘ve been really busy lately and have been neglecting my website and a bunch of other stuff besides. So this post is going to be brief.

... quite a lot more brief than that.

Formats made easy using SeemoreJ

You could also say, Rails-style.

In this post I‘m going to be talking about how SeemoreJ deals with deciding what format to present a resource in and how easy it is to display the same resource in multiple different formats.

The need for this was driven by my desire to provide a new feed for the articles on my website. That was straight forward and I just implemented a special case, which just spat out some XML and didn‘t forward on to a JSP view. This resulted in the following code for the list action.

BlogController.java (before)
package com.malethan.blog.app;

//...

public class BlogController {

    //...

    ArticlePager pager;

    //...

    @BeforeFilter(include = {"home", "list", "byCategory", "byMonth"})
    public void createPager() {
        pager = new ArticlePager();
        pager.setResultsPerPage(10);
        try {
            pager.setCurrentPageNumber(Integer.valueOf(request().getParameter("p")));
        } catch (NumberFormatException e) {
            pager.setCurrentPageNumber(1);
        }
        request().setAttribute("pager", pager);
    }

    @AfterFilter(include = {"home", "list", "byCategory", "byMonth"})
    public void initialisePager() {
        try {
            pager.initialise();
        } catch (Exception e) {
            log.error("Pager failed to initialise", e);
        }
    }

    //...

    public void list() {
        if ("html".equalsIgnoreCase(request().getParameter(FORMAT))) {
            request().setAttribute("sectionTitle", "All Articles");
        } else {
            try {
                Syndicate syndicate = new Syndicate(RequestUtil.getAppURL(request()));
                syndicate.syndicateBlog("atom_1.0", response().getWriter());
                renderNothing();
            } catch (IOException e) {
                log.error("Couldn't produce ATOM feed", e);
                renderView("404");
            }
        }
    }

    //...
}

A quick note on the BeforeFilter and AfterFilter annotated methods. These are a SeemoreJ feature that allow any arbitrary method to be invoked before and after any action. There'll be more on this in future posts.

Anyway, back to the subject at hand. The code above does the job but is not elegant. It did not please me to write it and it does not please me to look at it. It worked well enough and so this was the code for my site for a few months despite the fact that it did not really sit comfortably with me.

A better solution

I recently added SeemoreJ to ohloh. I'm not really sure what ohloh is or whether its going to be useful to me yet, or whether it has or will gain the critical mass of users to become a success. However, one of the features on there was to provide a news feed specifically for a project. So I figured I could just publish all the posts in the SeemoreJ category.

This article is in danger of becoming something far more verbose and – crucially – not at all brief. So I'll cut to the chase.

I have added a feature to SeemoreJ that allows easy customisation of what format to deliver a resource in. Navigate to http://www.malethan.com/all.html, you get a HTML. However, navigate to http://www.malethan.com/all.atom, you get XML. Atom XML to be precise.

This is achieved by having the view JSPs named in such a way that allows SeemoreJ to determine what format they represent. So I have a JSP called list.html.jsp for HTML and list.atom.jsp for Atom XML. Fans of Rails reading this will be familiar with the convention.

First, lets have a look at the relevant code in my controller class now. List is now a one–liner, specifying the title for the page/feed only.

BlogController.java (after)
package com.malethan.blog.app;

//...

public class BlogController {

    //...

    public void list() {
        request().setAttribute("sectionTitle", "All Articles");
    }

    //...
}

To deliver any resource with Atom I just need to create an appropriately named JSP and let it deliver the content. So I have the following view JSP for my Atom feed…

list.atom.jsp
<%@ page contentType="text/atom+xml;charset=UTF-8" language="java" %>
<%@ page import="com.malethan.blog.RequestUtil" %>
<%@ page import="com.malethan.blog.feed.Syndicate" %>
<%@ page import="com.malethan.blog.models.ArticlePager" %>

<%
    String title = request.getAttribute("sectionTitle") + " | implements Elegance { // Elwyn Malethan's Blog";
    ArticlePager pager = (ArticlePager) request.getAttribute("pager");
    Syndicate syndicate = new Syndicate(RequestUtil.getAppURL(request));
    syndicate.syndicateArticles("atom_1.0", response.getWriter(), pager.getResults(), title);
%>

... and this for the HTML

list.html.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/WEB-INF/common/taglibs.jsp" %>

<html>
<head>
    <title><%@ include file="/WEB-INF/app/blog/_title.jsp" %></title>
</head>
<body>

<div id="content" class="wide">
    <c:if test="${empty(pager.results)}">
        <p>Your selection has resulted in a page with no articles. Perhaps you would like to look at
            <a href="/all.html">all of them</a>.</p>
    </c:if>
    <c:if test="${!empty(pager.results)}">
        <c:set var="blogPosts" value="${pager.results}" />
        <pager:pages pager="${pager}" />
        <%@ include file="_list.jsp" %>
        <pager:pages pager="${pager}" />
    </c:if>
</div>

</body>
</html>

So, as only somewhat briefly described, I can now syndicate SeemoreJ posts alone to ohloh. It also means that all the other categories and the archive is similarly published.

First published on Jul 6, 2009. Last updated on: Dec 29, 2009.

Introducing SeemoreJ: Part #2 CRUD

In my last post about SeemoreJ I gave an account of how one might bootstrap a new web project using the seemorej–example–archetype. In this post I‘ll introduce how quick and easy it is to get a scaffolded CRUD application up and running.

I‘ll do this by stepping through the creation of the Person POJO (so pervasive in tutorials and demos), with Hibernate/JPA annotations as an example of a persistent model and – in the process we‘ll cover the default configuration of database interaction.

The model

Create a package called com.mycompany.model and add this class there.

package com.mycompany.model;

import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.Email;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Entity
public class Person implements Serializable {

    private Long id;
    private String firstName;
    private String lastName;
    private Date dateOfBirth;
    private String emailAddress;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotEmpty
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @NotEmpty
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Temporal(TemporalType.DATE)
    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public void setDateOfBirth(Date dateOfBirth) {
        this.dateOfBirth = dateOfBirth;
    }

    @NotEmpty
    @Email
    public String getEmailAddress() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
}

There‘s a lot of annotation in this POJO. Some for JPA persistence and some for Hibernate Validator, which the Hibernate specific SeemoreJ package uses as the validation framework. We‘ll see shortly what these validation annotations do for us.

Persistence

Mapping

Add this line to hibernate.cfg.xml within the session-factory element.

<mapping class="com.mycompany.model.Person" />

Database connection

Now to configure the database connection. I‘m assuming you have MySQL installed and that this is what you‘re going to use. Find the following section in the POM (pom.xml) and change the values to something appropriate.

<!-- ... -->
    <properties>
        <!-- ... -->
        <hibernate.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</hibernate.dialect>
        <jdbc.groupId>mysql</jdbc.groupId>
        <jdbc.artifactId>mysql-connector-java</jdbc.artifactId>
        <jdbc.version>5.0.5</jdbc.version>
        <jdbc.driverClassName>com.mysql.jdbc.Driver</jdbc.driverClassName>
        <jdbc.url>jdbc:mysql://localhost/myapp?createDatabaseIfNotExist=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=utf-8</jdbc.url>
        <jdbc.username></jdbc.username>
        <jdbc.password></jdbc.password>
    </properties>
<!-- ... -->

CRUD Scaffold

Add the following class to the com.mycompany.app. Whilst this is a great deal more verbose than it would be in Rails, this is all you need to have CRUD functionality for a Hibernate mapped class. It certainly beats implementing each action required. My intention is replace this implementation inheritance with some sort of configuration, probably annotation. This would make the resulting controller classes more flexible and nicer to use.

package com.mycompany.app;

import com.malethan.seemorej.hibernate.crud.CrudControllerHibernate;
import com.mycompany.model.Person;

public class PeopleController extends CrudControllerHibernate<Person, Long> {
    public PeopleController() {
        super(Person.class, Long.class);
    }
}

Now start Jetty up using mvn jetty:run-exploded. If you‘re running it for the first time you‘ll have to wait for all the dependencies to download. Once it‘s up and running got to http://localhost:8080/people/list.html

What you‘ll see is a rudimentary, fairly ugly – if I‘m honest – CRUD application. On my To–do list is to make it more attractive and – through configuration – provide some customisation. Also, I‘d like to support one–to–many, many–to–many and many–to–one relationships.

In my next post about SeemoreJ I‘ll be talking about action filters and how they‘re implemented in SeemoreJ.

First published on Apr 30, 2009. Last updated on: Dec 30, 2009.

Introducing SeemoreJ: Part #1 Hello World

I've been mentioning SeemoreJ in passing for a while in my posts on here. I've mentioned that it is a yet another Java web framework and that it is inspired by my experiences working with Ruby on Rails and Merb (soon to be one and the same thing). Also, there‘s a link at the bottom of every page. So I think it‘s high time I stopped faffing. It‘s in a pretty reasonable state now so I think it‘s time to release it as an open–source project.

I hasten to add at this point that I am in no way under the illusion that SeemoreJ will become popular or attract (m)any users. I developed it because of my frustration with the verbose and heavyweight frameworks that were already available. I wanted to bring some of the simplicity and expressiveness that I experienced working with Ruby into my Java development.

Essentially, SeemoreJ allows me write web applications quickly, efficiently and pleasurably. That‘s my only motivation. If others find it useful or draw inspiration from it as well, that‘s a bonus.

Getting started

I think that one of the big facilitators in the uptake of rails is the easy bootstrapping of your fist project, this page makes it look friendly. So this section is going to be inspired by that page. Well... without all the pretty graphics...

Java

I‘ve been using Java 6 for my work. SeemoreJ will probably work with Java 5 just as well. Follow those links and follow the instructions for your platform.

Alternatively, if you have Ubuntu, like me, the following whould do the trick.

~$ sudo apt-get install sun-java6-jdk

Maven

Maven is a build management tool (like Make and Rake), which I think will completely replace Ant as the build tool of choice for most Java developers. Get the latest version here then follow the installation instructions for your platform. Alternatively, if your using Ubuntu, just type

~$ sudo apt-get install maven2

Then check Maven is installed by running mvn -v. You should see something like this.

~$ mvn -v
Maven version: 2.0.8
Java version: 1.6.0_06
OS name: "linux" version: "2.6.18-xenu" arch: "i386" Family: "unix"

Starter application (or archetype)

This is the Maven equivalent of running rails my_app. It‘s a little more verbose but we‘ll only ever have to do it once per project.

~$ mvn archetype:generate -DarchetypeCatalog=http://maven.malethan.com/repo/archetype-catalog.xml

Select seemorej-example-archetype from the list, this will probably be number 1, since I have no other archetypes there at the time of writing. Select a suitable groupId (e.g. com.mycompany) artifactId (e.g. myapp) and accept the defaults for the rest.

Now change into the project directory and type the following.

~/myproject$ mvn jetty:run-exploded

Then visit http://localhost:8080/index.html

Voila! You now have a running SeemoreJ application. Now let‘s have a look around the application source.

.
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |       `-- mycompany
    |   |           `-- HelloController.java
    |   |-- resources
    |   |   |-- hibernate.cfg.xml
    |   |   |-- hibernate.properties
    |   |   `-- log4j.xml
    |   `-- webapp
    |       |-- WEB-INF
    |       |   |-- app
    |       |   |   |-- default
    |       |   |   |   `-- default.jsp
    |       |   |   `-- hello
    |       |   |       `-- world.jsp
    |       |   |-- common
    |       |   |   |-- _flash.jsp
    |       |   |   `-- taglibs.jsp
    |       |   |-- decorators
    |       |   |   `-- application.jsp
    |       |   |-- decorators.xml
    |       |   |-- urlrewrite.xml
    |       |   `-- web.xml
    |       |-- javascripts
    |       |   `-- prototype.js
    |       `-- stylesheets
    |           `-- application.css
    `-- production
        `-- resources
            `-- hibernate.properties

In my next post on the subject I‘ll show you how to set up a simple CRUD application, based on a Hibernate POJO. Also, at some point or other I‘ll create a project on Google Code, just in case anybody is interested in the source.

First published on Apr 22, 2009. Last updated on: Dec 30, 2009.

Humanise CamelCase in Java

In an effort to make my CRUD scaffolder for Seemore more friendly I embarked on the modest endeavour of implementing a utility method to convert camelCase variable or class names to something more human friendly.

A nice, easy little task to try and forget the hangover I managed to get myself last night (thanks Dave!). Here‘s the code.

/**
 * Converts a camelCase to a more human form, with spaces. E.g. 'Camel case'
 *
 */
public String humaniseCamelCase(String word) {
    Pattern pattern = Pattern.compile("([A-Z]|[a-z])[a-z]*");

    Vector<String> tokens = new Vector<String>();
    Matcher matcher = pattern.matcher(word);
    String acronym = "";
    while(matcher.find()) {
        String found = matcher.group();
        if(found.matches("^[A-Z]$")) {
            acronym += found;
        } else {
            if(acronym.length() > 0) {
                //we have an acronym to add before we continue
                tokens.add(acronym);
                acronym  = "";
            }
            tokens.add(found.toLowerCase());
        }
    }
    if(acronym.length() > 0) {
        tokens.add(acronym);
    }
    if (tokens.size() > 0) {
        String humanisedString = capitaliseFirstLetter(tokens.remove(0));
        for (String s : tokens) {
            humanisedString +=  " " + s;
        }
        return humanisedString;
    }

    return word;
}

The test case for this can be seen below.

import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collection;

@RunWith(Parameterized.class)
public class StringUtilTest {

    private static StringUtils util;

    @BeforeClass
    public static void setUpBeforeClass() {
        util = new StringUtils();
    }

    @Parameterized.Parameters
    public static Collection regExValues() {
     return Arrays.asList(new String[][] {
         {"camel", "Camel"},
         {"Camel", "Camel"},
         {"camelCase", "Camel case"},
         {"CamelCase", "Camel case"},
         {"doubleCamelCase", "Double camel case"},
         {"DoubleCamelCase", "Double camel case"},
         {"somethingRandomInTheHouse", "Something random in the house"},
         {"aTLA", "A TLA"},
         {"aTLAAndSomeMore", "A TLA and some more"},
         {"NOTCAMELCASE", "NOTCAMELCASE"},
         {"Certainly not camel case", "Certainly not camel case"}
      });
    }

    String input;
    String expectedOutcome;

    public StringUtilTest(String input, String expectedOutcome) {
        this.input = input;
        this.expectedOutcome = expectedOutcome;
    }

    @Test
    public void humaniseShouldHandleCamelCase() {
        assertEquals(expectedOutcome, util.humaniseCamelCase(input));
    }
}

I‘m not sure I like the way JUnit does the parameterised tests. It‘s certainly an improvement on having to write each test out individually (who‘d do that!?) and it‘s probably better than lumping all scenarios/criteria into one test. However, the reporting of each scenario/run isn‘t any more detailed than doing just that. The only difference is that the array index of the failing parameters is given – hardly useful when the failed assert already tells us what‘s wrong.

When you compare the above to something like how it would look implemented in Rspec, it looks just plain ugly. I don't like ugly. I must look into TestNG, to see if it has a more elegant approach. Failing that, I'll have a look at how the JtestR project is coming along and start thinking about writing some tests using Rspec again.

Update: There's a better, more considered implementation of this here.

First published on Feb 8, 2009. Last updated on: Dec 30, 2009.

SeemoreJ

SeemoreJ is a lightweight MVC2 framework that I have developed as a pet project. This site runs on SeemoreJ, amongst other things. "Another one!?" I can imagine some people exclaiming. SeemoreJ is different, honest! I've developed a lot of apps using Struts 1 & 2 and I‘ve dabbled in some other Java-based MVC2 frameworks. They all have one thing in common. They‘re all terribly verbose and somewhat obese.

SeemoreJ is open–source and freely available under the LGPL on Google Code.

Verbose? Obese?

The one thing that strikes me with the majority of the popular Java web-frameworks is how much effort one has to go just to say “Hello World!”. The number of files that need creating because of how few assumptions are made is a real hindrance to a quick bootstrapping of a new project, Even one as simple as Hello World

I have also developed a number of apps using Rails and Merb. I have my issues with both of these but the one thing they are good at is allowing a developer to concisely and quickly build web applications. This is because that while these two frameworks aren‘t limited in their configurability (well, ActiveRecord is useless for legacy data and Rails more or less requires that you use it) they do make a lot of sensible assumptions that allow a developer to just get on with things. That is my main motivation in developing SeemoreJ.

I initially implemented Seemore in PHP just as an experiment, but quickly rediscovered why I hated developing in PHP (I had a job as a PHP developer for 2 years) so I ported it to Java. I've got a lot to do before it can be considered anywhere near a viable alternative to the current crop of MVC2 frameworks. I'm currently working on a simple annotation-based validation framework (I'm currently using Hibernate Validator for this) and automagic request to bean population, which will lead on to a make_resourceful-style autoCRUD and scaffolding. When I think it is worthy of public view I‘ll make it available for feedback and the critique of my peers.

As a quick illustration of how concise SeemoreJ allows one to be when developing web applications, below is an extract from the controller class for basic CRUD functionality.

package com.malethan.blog.app;

import com.malethan.seemorej.*;
import static com.malethan.seemorej.HttpMethod.*;
import static com.malethan.seemorej.SeemoreJ.request;
import static com.malethan.seemorej.SeemoreJ.response;
i
/* ... */

/**
 * <p>Controller for the website</p>
 */
public class BlogController {
    //----------------------------------------------------------------------- Filters

    @BeforeFilter()
    public void loadPageArtifacts() { /* ... */ }

    @BeforeFilter(include = "new")
    public void clearSesssion() { /* ... */ }

    //----------------------------------------------------------------------- Actions

    public void list() { /* ... */ }

    public void show() { /* ... */ }

    public void edit() { /* ... */ }

    @Accepts(method = POST)
    public void delete() { /* ... */ }

    @Accepts(method = POST)
    public void update() { /* ... */ }

    @Accepts(method = POST)
    public void create() { /* ... */ }

}

A controller is usually a POJO where each action is a public method. By default, a JSP view of the same name will be looked for to render for the action.

Common tasks that need to run before and after actions are configured using Annotations BeforeFilter and AfterFilter respectively.

An Accepts annotation can be used to limit the HTTP method allowed for a given action.

When I have some time I‘ll give a more comprehensive account of what SeemoreJ is and how it works.

First published on Nov 18, 2008. Last updated on: Dec 30, 2009.