implements Elegance {

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

Articles tagged with 'java'

Unit testing with Commons HttpClient

I‘ve been adding some test coverage to some existing code today. This code under test uses Commons HTTP Client to fetch data from an external resource. I ran into problems with mocking/stubbing the response to the HTTP requests.

I am not the only one who has faced problems with this Http Client. In that article, Florin provides a good solution using a concrete subclass of HttpClient in order to mock it‘s behaviour. His article was very useful in helping me formulate my approach.

I use JMock for dynamic mock objects and so I was keen not to have to mix of JMock-based mocks and concrete mock objects. So my approach is to use JMock‘s custom actions to provide an implementation that populates the right values in the right way. Although, I had to use some reflective cheating to set the necessary values.

private static Action willRespondWith(final int code, final String status, final String body) {
    return new CustomAction("will respond with status: " + code +  ", and contents: " + body) {
        @Override
        public Object invoke(Invocation invocation) throws Throwable {
            final Object method = invocation.getParameter(0);

            final Field statusLine = HttpMethodBase.class.getDeclaredField("statusLine");
            statusLine.setAccessible(true);
            statusLine.set(method, new StatusLine("HTTP/1.0 " + code + " " + status)); //Although, 'OK' could be anything 

            final Method setResponseStream = HttpMethodBase.class.getDeclaredMethod("setResponseStream", InputStream.class);
            setResponseStream.setAccessible(true);
            setResponseStream.invoke(method, new ByteArrayInputStream(body.getBytes("UTF-8")));

            return code;
        }
    };
}

This is intended to be used as follows:

@Test
public void testSomeHttpStuff() throws Exception {

    jmock.checking(new Expectations() {{
        allowing(client).executeMethod(with(any(HttpMethod.class)));
        will(willRespondWith(200, "OK", "{some: 'value'}"));
    }});
        
    sendHttpRequest("http://some.server/some/resource.json");
        
}

Now I can simulate all sorts of responses from the external resource.

First published on Apr 26, 2010. Last updated on: Apr 26, 2010.

How to catch GWT HorizontalSplitPanel double click event

I was using GWT's HorizontalSplitPanel. The thing is that it was a quite good solution but not everything I wanted. GWT standard widget–set is known for being on the Spartan side. I have no complaint about this, it is just a fact. The added behaviour I was after is the ability to double-click the splitter in order to toggle a fully collapsed or restored state. I'm not the only one, it seems.

This was not as straight–forward to achieve as I thought it would be. This is an account of the dead-end strategies I followed in trying to achieve this and the solution I settled on.

Inheritance strategy

My first (possibly lazy) approach was to use an inheritance strategy to extend HorizontalSplitPanel. Anyone whose familiar with the GWT standard widget set will know that this approach is a non–starter, since HorizontalSplitPanel is final so it can't be extended and — one step further up the class hierarchy — SplitPanel has package-local access so that can‘t be extended either (not in a class outside the same package in any event).

So of course, I put my best–practice hat back on to try and solve the problem properly.

Composition

So I used a SimplePanel as the base class for my widget as follows.

public class ElegantHorizSplitPanel extends SimplePanel {
    private String presetPosition;
    private HorizontalSplitPanel splitPanel;

    public ElegantHorizSplitPanel() {
        splitPanel = new HorizontalSplitPanel();
        this.add(splitPanel);
        setSplitPosition("30%");
    }

    public void setLeftWidget(Widget widget) {
        splitPanel.setLeftWidget(widget);
    }

    public void setRightWidget(Widget widget) {
        splitPanel.setRightWidget(widget);
    }

    public void setSplitPosition(String position) {
        presetPosition = position;
        splitPanel.setSplitPosition(position);
    }
}

This implementation does not support all the functionality provided by HorizontalSplitPanel — in fact it does nothing more than delegate what little functionality it does support directly to HorizontalSplitPanel. However, it provides enough detail to demonstrate the technique. The methods providing all the other functionality could be added fairly easily.

So now on to adding double-lick behaviour. To do this I needed to get a reference to the the splitter DOM element. Unfortunately — but probably for good reasons — the getter for this element is protected in HorizontalSplitPanel . So, this means we have to cheat a little. GWT exposes some of the DOM traversal JavaScript methods in the Widget API, so provided I could get hold of an element in splitter‘s ancestry somewhere there was hope.

I used Firebug to find out what HTML was generated by my new widget and found the following.

Illustration of the splitter DOM-element using Firebug

So in order to get a reference to the splitter element I need the element returned by:

this.getElement().getFirstChildElement().getFirstChildElement().getFirstChildElement().getNextSiblingElement()

But that – as we all know – is a what @unclebobmartin (and others) describes as a train wreck, so I added the following methods to ElegantHorizSplitPanel

public class ElegantHorizSplitPanel extends SimplePanel {

    // ...

    private Element getSplitterElement() {
        return getLeftElement().getNextSiblingElement();
    }

    private Element getLeftElement() {
        return getSplitPanelInnerElement().getFirstChildElement();
    }

    private Element getSplitPanelInnerElement() {
        return getSplitPanelOuterElement().getFirstChildElement();
    }

    private Element getSplitPanelOuterElement() {
        return getElement().getFirstChildElement();
    }

    // ...

}

Caveat: I checked IE HTML as well and it uses more or less the same HTML, though I suppose it's possible that compiling for different user agents could result in different HTML. I could probably add some test coverage for this using Matt Raible's guide to testing GWT libraries with Selenium, something to look into in future.

Adding double-click behaviour

I‘m more familiar with JavaScript and the DOM than I am GWT so my first approach to adding the behaviour was add native JavaScript code to attach the behaviour to the splitter element.

public class ElegantHorizSplitPanel extends SimplePanel {

    // ...

    private void toggleLeftPanel() {
        int leftWidth = getLeftElement().getClientWidth();
        if(leftWidth == 0) {
            splitPanel.setSplitPosition(presetPosition);
        } else {
            splitPanel.setSplitPosition("0px");
        }
    }

    private native void addBehaviour(Element splitter)/*-{
        var panel = this;
        splitter.ondblclick = function() {
            panel.@com.malethan.gwt.ui.widgets.client.ElegantHorizSplitPanel::toggleLeftPanel()()
        };
    }-*/;

    // ...

}

This actually works just fine in IE but is patchy in Firefox for some reason. But more importantly it introduces a reference cycle and is an almost guaranteed way to introduce a memory leak in most browsers.

Reference cycles & memory leaks.

Well, Google had already thought of that. They provide a standard, non–native way to add event handlers to DOM elements. So the actual code we use to add the double–click behaviour to the splitter element is the following:

public class ElegantHorizSplitPanel extends SimplePanel {

    // ...

    private  void addBehaviour(Element splitter) {
        Event.setEventListener(splitter, new EventListener() {
            public void onBrowserEvent(Event event) {
                if(event.getTypeInt() == Event.ONDBLCLICK) {
                    toggleLeftPanel();
                }
            }
        });
        Event.sinkEvents(splitter, Event.ONDBLCLICK);
    }

    // ...

}

N.B. When I started this post I had only tested the above technique in IE. It works great. Unfortunately it became quickly apparent that when I tried this in Firefox (running on Ubuntu Jaunty) it worked sporadically if at all. If anyone knows of a way to get this working in Firefox, please let me know and I'll post a correction.

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

Groovy BeanFactory wrapper using propertyMissing

I‘ve been using Easyb for some integration style testing. The system I‘m testing has a bunch of dependencies all wired together using Spring. So my stories started getting filled up with non dynamic looking clunky Java just so I could get at my configured beans. Something like this:

import org.springframework.beans.factory.xml.XmlBeanFactory
import org.springframework.core.io.ClassPathResource

def beanFactory = new XmlBeanFactory(new ClassPathResource("storyContext.xml"))
def myService = beanFactory.getBean("myService")

scenario "Some integration test", {
  given "Some criteria", {
    // ...
  }
  when "my service is invoked", {
    service.turnLeadIntoGold()
  }
  then "I expect to see some results", {
    // ...
  }
}

For this one small example story it doesn‘t seem like a big deal. Most stories are far more elaborate however. Also add a few more stories and even the top few lines of this example starts looking very non–DRY. So my answer was this:

import org.springframework.beans.factory.xml.XmlBeanFactory
import org.springframework.core.io.ClassPathResource

class SpringHelper {

  private def beanFactory;

  def SpringHelper(String resource) {
    beanFactory = new XmlBeanFactory(new ClassPathResource(resource));
  }

  def propertyMissing(name) {
    beanFactory.getBean name
  }
}

Like a Ruby , Groovy supports dynamic methods and properties (Ruby doesn‘t distinguish between the two). This seems so simple, that it surprises me that I couldn‘t find it done already somewhere.

So now my stories are a little leaner and a little tidier.

import com.malethan.easyb.helpers.SpringHelper

def spring = new SpringHelper("storyContext.xml")

scenario "Some integration test", {
  given "Some criteria", {
    // ...
  }
  when "my service is invoked", {
    spring.myService.turnLeadIntoGold()
  }
  then "I expect to see some results", {
    // ...
  }
}

I‘m pretty new to Groovy, so I may have missed a trick. It‘s nice to be working with a more flexible language again though.

First published on Sep 2, 2009. Last updated on: Dec 29, 2009.

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.

Pingback Java API

A couple of weeks ago I set about implementing Pingback 1.0 for this website. The first logical step was trying to see if there was an existing open–source project for Java implementations of Pingback or whether there were any easily reusable examples to borrow on the intarwebz.

My searches came up dry, so I rolled my own. And, so I have something to write about too! Here‘s how I did it.

The first thing I looked at was identifying links to other pages within the articles of my site. There are loads of regular expressions claiming some degree of effectiveness at identifying URLs, I chose a regex based on this one.

/**
 * This regex checks for both Textile ("blah":url) and HTML (&lt;a href="url"&gt;blah&lt;/a&gt;) links.
 */
public static final String URL_REGEX = "((\":)|href=\")((http(s?)\\:\\/\\/|~/|/)?((\\w+:\\w+@)?(([-\\w]+\\.)+(com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))|localhost)(:[\\d]{1,5})?(((/([-\\w~!$+|.,=]|%[a-f\\d]{2})+)+|/)+|\\?|#)?((\\?([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)(&([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)*)*(#([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)?)"

Regular expressions are incomprehensible when they get that big! And, this is probably overkill and too specific (e.g. it will ignore any new top–level–domains that are invented).

Anyway, my regex matches any URLs that are either the value for a href attribute in HTML (e.g. href="some_url"...) or part of Textile markup ("Some label":some_url). I check for both because Textile allows for HTML to be embedded so just parsing links in Textile won‘t do. Also this allows me to use the same regex to check remote pages for links to my own site for Pingback server compliance as I use to check my own Textile articles for outgoing links.

The codebase for the API has turned out to be quite tiny. I wouldn‘t say that it is innovative but it certainly re-usable and should simplify the task for anyone who is trying to do the same as I have done. The source is available here. It's in the form of a maven project, so if you want to build it, just type mvn install .

Pingback Client

It is for implementing Pingback clients that this API provides most value. This is the case because I found it very difficult to decouple the Pingback server functionality from the specific implementation of my website. That‘s the subject for another post, however.

Here‘s how the code in my website uses the API.

package com.malethan.blog.app;

import com.malethan.blog.RequestUtil;
import com.malethan.blog.models.BlogPost;
import com.malethan.pingback.Link;
import com.malethan.pingback.PingbackClient;
import com.malethan.pingback.LinkLoader;
import com.malethan.pingback.PingbackException;
import com.malethan.seemorej.AfterFilter;
import static com.malethan.seemorej.SeemoreJ.*;
import static com.malethan.seemorej.Flash.*;
import com.malethan.seemorej.hibernate.crud.CrudControllerHibernate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.xml.XmlBeanFactory;

import java.util.List;
import java.util.ArrayList;

/**
 * <p>The controller for managing articles/blog posts</p>
 */
public class BlogPostController extends CrudControllerHibernate<BlogPost, Long> {
    //----------------------------------------------------------------------- Static Properties and Constants

    private static final Log log = LogFactory.getLog(BlogPostController.class);

    //----------------------------------------------------------------------- Static Methods
    //----------------------------------------------------------------------- Instance Properties

    XmlBeanFactory beanFactory;
    PingbackClient pingbackClient;
    LinkLoader linkLoader;
    List<String> failedPings;

    //----------------------------------------------------------------------- Constructors

    public BlogPostController() {
        super(BlogPost.class, Long.class);
        beanFactory = new XmlBeanFactory(new ClassPathResource("/applicationContext.xml", getClass()));
    }

    //----------------------------------------------------------------------- Filters

    @AfterFilter(include = {"create", "update"})
    public void createOutgoingLinks() throws Exception {
        BlogPost blogPost = (BlogPost) request().getAttribute(modelNameLower);
        if (blogPost.isPublished()) {
            initialiseClientAndLinkLoader();
            failedPings = new ArrayList<String>();
            for (String linkAddress : linkLoader.findLinkAddresses(blogPost.getBody())) {
                if (!blogPost.hasOutgoingLinkToUrl(linkAddress)) {
                    loadRemotePageAndSendPingbacks(blogPost, linkAddress);
                }
            }

            dao.saveOrUpdate(blogPost);

            if (failedPings.size() > 0) {
                notifyUserOfBadPingbacks(failedPings);
            }
        }
    }

    //----------------------------------------------------------------------- Actions
    //----------------------------------------------------------------------- Getters and Setters
    //----------------------------------------------------------------------- Instance Methods

    private void initialiseClientAndLinkLoader() {
        pingbackClient = (PingbackClient) beanFactory.getBean("pingBackClient");
        linkLoader = (LinkLoader) beanFactory.getBean("pingbackLinkLoader");
    }

    private void loadRemotePageAndSendPingbacks(BlogPost blogPost, String linkAddress) {
        Link link = linkLoader.loadLink(linkAddress);
        if(link.isSuccess()) {
            if(link.isPingbackEnabled()) {
                sendPingback(blogPost, link);
            } else {
                blogPost.addOutGoingLink(link.getTitle(), link.getUrl());
            }
        }
    }

    private void sendPingback(BlogPost blogPost, Link link) {
        try {
            String permaLink = RequestUtil.getAppURL(request()) + "/article/" + blogPost.getSlug() + ".html";
            pingbackClient.sendPingback(permaLink, link);
            blogPost.addOutGoingLink(link.getTitle(), link.getUrl());
        } catch (PingbackException e) {
            log.error("Pingback to '" + link.getUrl() + "' failed", e);
            failedPings.add("Pingback to " + link.getUrl() + " failed because of " + e.getMessage() + " ");
            if (PingbackClient.PINGBACK_ALREADY_REGISTERED == e.getFaultCode()) {
                blogPost.addOutGoingLink(link.getTitle(), link.getUrl());
            }
        }
    }

    private void notifyUserOfBadPingbacks(List<String> failedPings) {
        String errMsg = "";
        for (String failedPing : failedPings) {
            errMsg += failedPing;
        }
        flash(NOTICE, errMsg);
    }
}

The annotation  @AfterFilter(include = {"create", "update"}) causes the method createOutgoingLinks() to be invoked after an action is invoked if the action is called create or update. Those two actions are part of the SeemoreJ CRUD framework (that's another post as well, if I ever get around to it). Hopefully, it's easy to make out what's going on. Essentially, if a post is published it, looks for all links with fully qualified URLs in the article and – if the remote resources support it – attempts to send them a pingback. Any failures are displayed using a Rails–style flash system.

I‘ve noticed that this chugs a little if there are a few links in a page and/or certain resources are slow loading. Still, it‘s not publicly visible so I‘ll deal with it for the moment.

Also, this example uses Spring to load the default implementations of LinkLoader and PingbackClient both interfaces defined in the library. It would work just as well with concrete instantiations. Though, it would be more difficult to test :)

It was certainly fun to write, I hope somebody finds it useful :)

First published on Mar 20, 2009. Last updated on: Dec 30, 2009.

Humanise CamelCase in Java (non hungover version)

Yesterday, I posted a hangover–inspired camel–case humaniser. Today – with the benefit of a clearer mind I decided I didn't like what I'd written much. In fact I thought it was at best ugly, at worst not at all that clear. So I set about implementing a cleaner solution and factoring the changes into Seemore.

There are those who say that it doesn‘t matter what code looks like as long as it passes the tests. They‘ll say that if it passes the tests then it does what it‘s meant to do, who cares that it looks like a turd?! Neither the customer nor the JVM (in the case of Java) cares what the code looks like, so why should we? Some even say that even unit tests don't matter — there's entertaining discussion at the end of that article as well.

Any experienced developer will know that it does matter what code looks like. Or, more specifically how readable it is. Devs who‘ve been about for a while will have been on the receiving end of a plethora of badly written classes – I know I have over the years – only to spend hours tracing through the execution with a debugger and more hours trying to decipher badly named classes. methods and variables. All in a vain attempt to extract some meaning.

It matters what code looks like! I heard somewhere (can't remember where) that – when actively developing (i.e. producing code) – developers spend only 10% of their time writing code, the rest of the time is spent reading existing code. It matters what code looks like!

It also matters a great deal that there are unit tests. In this case, if there were no unit tests, evaluating the success of the following re-implementation would have been far more difficult, certainly less repeatable. Anyway, here‘s the (hopefully) more readable version.

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class HumaniseCamelCase {
    //----------------------------------------------------------------------- Static Properties and Constants

    private static final String CAMEL_CASE_PATTERN = "([A-Z]|[a-z])[a-z]*";

    //----------------------------------------------------------------------- Instance Properties

    private String humanisedString;
    private String acronym;

    //----------------------------------------------------------------------- Instance Methods

    /**
     * Converts a camelCase to a more human form, with spaces. E.g. 'Camel case'
     *
     * @param camelCaseString
     * @return a humanised version of a camelCaseString if it is indeed camel-case. Returns the
     * original string if it is'nt camel-case
     */
    public String humanise(String camelCaseString) {
        reset();
        Matcher wordMatcher = camelCaseWordMatcher(camelCaseString);
        while(wordMatcher.find()) {
            String word = wordMatcher.group();
            boolean wordIsSingleCapitalLetter = word.matches("^[A-Z]$");
            if(wordIsSingleCapitalLetter) {
                addToAcronym(word);
            } else {
                appendAcronymIfThereIsOne();
                appendWord(word);
            }
        }
        appendAcronymIfThereIsOne();
        return humanisedString.length() > 0 ? humanisedString : camelCaseString;
    }

    private Matcher camelCaseWordMatcher(String camelCaseString) {
        return Pattern.compile(CAMEL_CASE_PATTERN).matcher(camelCaseString);
    }

    private void reset() {
        humanisedString = "";
        acronym = "";
    }

    private void addToAcronym(String word) {
        acronym += word;
    }

    private void appendWord(String word) {
        boolean firstWord = humanisedString.length() == 0;
        humanisedString += firstWord ? capitaliseFirstLetter(word) : " " + word.toLowerCase();
    }

    private void appendAcronymIfThereIsOne() {
        if(acronym.length() > 0) {
            boolean firstWord = humanisedString.length() == 0;
            humanisedString += firstWord ? acronym : " " + acronym;
            acronym = "";
        }
    }

    private String capitaliseFirstLetter(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

}

I‘m torn as to whether more readable means more elegant, but that can be a belly–button inspection for another day.

First published on Feb 9, 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.

jMock 2.x more expressive than 1.x?

jMock 2.5 has been around since July this year, and 2.x for much longer, but I've only recently used the 2.x API. I was pleasantly surprised. It makes great use of Generics to allow concise creation of mock objects and improves the the ability of a developer to rely on compiler/IDE support in specifying expectations. I‘m not so sure that the new expectation format is necessarily an improvement however.

In jMock 1.x I would have expected to have to write the following code (within a JUnit test case extending MockObjectTestCase) to create a mock object, implementing an arbitrary interface called Subscriber, then using it as an argument in some production code I want to test in isolation.

Mock mockSubscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add( (Subscriber)mockSubscriber.proxy() );

It‘s not that concise and there‘s a bunch of typing I‘d rather not be doing. More generally, I‘ve found that a major improvement that Java 1.5 brought to the party was the syntactic candy that allows far more concise, and sometimes expressive source code.

This is illustrated in the example below that uses the jMock 2.x syntax

final Subscriber subscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add(subscriber);

No casting and no reference to to some mysterious method called ‘proxy‘. It makes more sense in terms of the developers intention (that is to create mock object) and is less verbose.

Expressiveness vs Convenience (or is it ideology vs pragmatism?)

The way in which a developer might express expectations using jMock 2.x, I‘m not so sure it‘s an improvement. Certainly not when one considers the way in which Rspec or Mocha allows one to express the same thing.

Using jMock 1.x I might have expected to express an expectation using the following form.

mockSubscriber.expects(once()).method("receive").with( eq(message) );

There are a bunch of parentheses that are in the way but, that aside, it does kind of read in a way that might be considered natural language This is great because it is easy to read, even to someone who may not be a developer. Put in another way, it means that it allows a developer to express a solution that is closer to the way one might be thinking about it. That is, without having to model the solution in terms of the constraints of the Java language – even though it is syntactically valid Java code.

jMock 2.x employs the following approach.

checking(new Expectations() {{
    oneOf (subscriber).receive(message);
}});

One major advantage of the 2.x approach is that through the use of Generics any typo‘s in relation to the method names specified in the expectation will be caught at compile-time (or in the IDE) rather than at run-time. In addition, for those using a quality IDE (A) (there‘s only one IMHO :p ) one can take advantage of code-completion. I suspect that this may have been the major motivation in implementing it in this way. It was certainly a pleasurable experience being able to make more use of the productivity features in my IDE. The 2.x approach is also far more concise, which is a virtue.

It could hardly be said that it reads in a natural way however. Whilst reading the 1.x format it almost sounds like English. Reading the 2.x example would sound like you‘re learning English, and not doing too well!

Using a more natural language

If thought of on the same time-scale as human history – and all the technologies and skills humankind has developed over the millennia – software development, and computing in general could be considered a technology still in it‘s infancy. Not just computing either! The internal combustion engine was invented over a century ago, it‘s still only 30% efficient and our cars are still propelled by it!

It is no surprise therefore that some might consider that most programming languages pose a significant productivity shortcoming, despite being the result of decades of development. They force developers to express solutions (be it a single test case or an entire application) in terms that are specific to the programming language being used. This is also true of frameworks in languages that don‘t necessarily have quite as restrictive a syntactic or runtime straitjacket. TestUnit in Ruby being a case in point when compared to Rspec.

This is why frameworks such as Rspec are such a joy to use. They allow a developer to express solutions in terms that are far more like natural language. Not by coincidence are frameworks such as this far more suited to the problem domain in which they are employed. Moreover Rspec does this all within the constraints of the Ruby syntax and specification.

The whole concept of expressing solutions using a more optimal grammar is described in far more depth and far more articulately in Sergei Dmitriev‘s article on language oriented programming. He is selling a product in this article but that‘s not a crime and it‘s interesting nonetheless.

The code examples in this article have come straight from the jMock website, where there are many more great examples of usage.

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

 
People I like
Other sites