implements Elegance {

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

Articles published in category Java

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.

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 (<a href="url">blah</a>) 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.

JavaFX All your screens are belong to us

Since I keep hearing a lot about it, I recently had a look at the JavaFX site and after waiting an inordinately long time for something to happen (it seems to take longer to load than Flash). I saw the this popup…

 

Well, it wasn‘t exactly what it said but that‘s what I saw! Anyway, it was a loooong time to wait for something that looked a lot like Flash.

I‘m tempted to bitch about the whole new declarative language used to produce JavaFX apps. It looks Java–like, and it also looks JSON–like but is probably neither. But, I won‘t bitch about it just yet, I haven‘t looked into it enough to form an opinion — and certainly not enough to express an opinion.

First published on Feb 19, 2009. Last updated on: Feb 19, 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.

Caching

By changing the layout of my site the other day I caused myself some problems. I knew that my markup processing code – that translates a combination of textile formatted text with embedded source fragments – was a tad inefficient. I rolled my own processor that uses Textile4J to process the text with an added filter-style system for the source fragments, formatted with JHighlight. So a fragment of this page may look like this:

I know have one with some extra functionality. Namely the option to cache the output of the markup 
processor so that any subsequent call to the same tag&ndash;library with the same value will use 
the cached version.

<textfu:jhighlight language="xml">
<tf:out value="${blogPost.body}" engine="textile" useCache="true"/>
</textfu:jhighlight>

_Voila!_ Faster loading pages and a much happier VPS(Virtual Private Server).

h2. Caching implementation

I knew it was inefficient but it was brought home quite how inefficient yesterday.

The day before yesterday I changed the way my site is laid out so that there is more content on the home page and the listing pages. No more excerpt or intro text, straight to the main article. This meant that my cobbled together – or mashed up perhaps (makes it sound cool rather than stupid) – markup processor was doing a lot more work per request.

It may be a coincidence but my Gandi–hosted virtual server bombed yesterday. Happy to accept that I may have been to blame, I concluded that I should at least eliminate the code from my enquiries.

Incidentally, Gandi have still not responded to the support ticket I raised yesterday. As my friend Keeran quite rightly put it:

[Gandi] has potential to be huge (because of the pricing), but if the support is that weak they‘re going to FAIL.

Caching

The solution I came up with isn‘t ideal and I haven‘t given much thought to best–practice or the design that much.

I have this additional code in my tag–library class. And yes, I called my markup processor Textfu. I thought for ages about a suitable, meaningful and succinct name for it. In the end I failed, so Textfu had to do. I wonder if the inventor of attachment_fu went through the same process and ended up just settling on that name.

String html;
if (useCache) {
    log.debug("Using CacheFu");
    String key = new BASE64Encoder().encode(MessageDigest.getInstance("MD5").digest(bodyText.getBytes()));
    if(CacheFu.get(key) != null) {
        log.debug("Found cached string for key " + key);
        html = CacheFu.get(key);
    } else {
        log.debug("No value found in cache for " + key);
        html = TextFuFactory.getProcessor(engine).decorate(bodyText);
        CacheFu.put(key, html);
    }
} else {
    html = TextFuFactory.getProcessor(engine).decorate(bodyText);
}

Where before I had a tag–library that read the following:

<tf:out value="${blogPost.body}" engine="textile" />

I know have one with some extra functionality. Namely the option to cache the output of the markup processor so that any subsequent call to the same tag–library with the same value will use the cached version.

<tf:out value="${blogPost.body}" engine="textile" useCache="true"/>

Voila! Faster loading pages and a much happier VPS.

Caching implementation

I am uncertain as to whether what I‘ve implemented is a suitable solution for any large scale project or whether it‘s a big no no in terms of best–practice. It seems to be working well for my site in any case. If what I've done has any flaws, please let me know. Note the imaginative name of the class again.

package com.malethan.blog.textfu.taglib;

import java.util.Map;
import java.util.HashMap;

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

    private static ThreadLocal<Map<String,String>> LOCAL_CACHE = new ThreadLocal<Map<String, String>>();

    //----------------------------------------------------------------------- Static Methods

    public static String get(String key) {
        return getCache().get(key);
    }

    public static void put(String key, String value) {
        getCache().put(key, value);
    }

    private  static Map<String, String> getCache() {
        if (LOCAL_CACHE.get() == null) {
            LOCAL_CACHE.set(new HashMap<String, String>());
        }
        return LOCAL_CACHE.get();
    }

}

First published on Jan 28, 2009. Last updated on: Jan 29, 2009.

Maven Troubles

I‘ve been having a bit of a mare this morning with trying to get my first Maven archetype for SeemoreJ up and running. I‘ve created a SeemoreJ example application from which I want to generate an arcehtype.

I‘ve recently been following Rick Hightower's efforts with Crank and noticed he‘s been tackling maven based issues as well. Though with rather more success than me.

Anyway, as per Nino Martinez's tip I used mvn archetype:create-from-project to attempt to create an archetype from my example project.

First I get this error, despite the fact that – as I understand it – the file maven complains about being missing is not actually required and that it should prompt me for the values usually found in this file.

[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building seemorej-example
[INFO]    task-segment: [archetype:create-from-project]
[INFO] ------------------------------------------------------------------------
[INFO] [archetype:create-from-project]
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Cannot create archetype from this project.

Embedded error: /xxxx/seemorej-example/src/main/archetype/archetype.properties (No such file or directory)
[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Sat Jan 17 12:06:10 GMT 2009
[INFO] Final Memory: 4M/67M
[INFO] ------------------------------------------------------------------------

So, I add archetype.properties with some values suggested from this page and now it builds "successfully". Quotes used because I think it kind of worked in that it copied the pom.xml file over and the contents of src/main/java, src/main/resources and src/test/java into a target/archetype.jar but completely ignored the contents of my web application folder (in src/main/webapp). Also the plugin doesn't seem to behave like any of the documentation suggests. Mine seems to generate the file target/archetype.jar, unlike what Rick and Nino both describe should happen, which is the archetype project should be generated in target/generated-sources.

Well, enough sitting in front of my computer now. I‘m going to prepare my flat for some GSI (like DIY but lazier), which is in-turn to prepare it for tenants in a month or so. If anyone is looking to rent a city-centre flat in Cardiff, I‘m your man! Get in touch.

First published on Jan 17, 2009. Last updated on: Mar 12, 2009.

Comments finally enabled on my website

Some blog my website could claim to be without the possibility to leave comments here. It took a lot of work because – as usual – I decided to take the long way around to getting it done.

Modeling the comments was relatively easy using JPA annotations and Hibernate. It was also easy to get a form on the site so that information could be input. The thing is, I wanted to be able to moderate the comments to prevent any dissent. Only kidding! I wanted to prevent spammers, idiots and pr0n peddlers from making me crazy with shitty comments.

That‘s where it started to get involved and time-consuming. I ended up implementing a CRUD scaffolding system for SeemoreJ so I could manage any data I wanted. Though, it was rather more of an academic pursuit rather than a practical one – just to see if it could be done (or, more accurately, whether I could do it). I'm happy to be corrected but – as far as I am aware – the only other dynamic scaffolding available in a Java web framework is Grails.

I‘ll produce a proper write up of the code but here‘s a quick taster in the meantime.

public class CommentsController extends CrudController<Comment, Long> {

    public CommentsController() {
        super(Comment.class, Long.class);
    }

}

The code above is all that is required to produce a fully functional CRUD application. At the moment it only supports Hibernate entities, but generic JPA support shouldn‘t be too difficult. Also, it doesn‘t allow one to manage relationships with other entities but that‘s not too much more work.

No time for any more. I have plenty of work to tidy up SeemoreJ so I can get the first public release available. Watch this space!

Oh and please leave comments! :-)

First published on Jan 6, 2009. Last updated on: Jan 7, 2009.

Testing context for UrlRewrite and JUnit4

Absolutely ages ago, I found this great article on JUnit testing for UrlRewrite by Sujit Pal. It was very useful as at the time as I was looking for a way of testing that my usage of UrlRewrite was working correctly without having a servlet container running. Together with my contribution, both inbound and outbound rules are covered.

The solution is great for JUnit 3 but not really in the spirit of JUnit 4, where the test cases aren't necessarily part of an inheritance hierarchy, as this article demonstrates.

I had cause to test some rewrites again recently. However, I‘ve moved over to JUnit4 as a preference these days, so I decided to refresh Sujit‘s solution, decouple it from TestCase.

package some.pakage.name;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.tuckey.web.MockRequest;
import org.tuckey.web.MockResponse;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.RewrittenUrl;
import org.tuckey.web.filters.urlrewrite.UrlRewriteWrappedResponse;
import org.tuckey.web.filters.urlrewrite.UrlRewriter;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * <p>A context for testing UrlRewrite rules for JUnit4</p>
 */
public class UrlRewriteTesting {
    //----------------------------------------------------------------------- Instance Properties

    protected Conf conf;
    protected UrlRewriter rewriter;

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

    public UrlRewriteTesting(Conf conf) {
        org.tuckey.web.filters.urlrewrite.utils.Log.setLevel("DEBUG");
        this.conf = conf;
        rewriter = new UrlRewriter(conf);
    }

    public UrlRewriteTesting(String pathToCfg, String confFile) throws FileNotFoundException {
        this(new Conf(new FileInputStream(pathToCfg + "/" + confFile), confFile));
    }

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

    /**
     * Assertion to rewrite the URL using the UrlRewriteFilter and verify
     * that fromUrl is rewritten to toUrl using rewriting rules in conf.
     *
     * @param fromUrl the URL to be rewritten from.
     * @param toUrl   the URL to be rewritten to.
     */
    public void assertInboundRewrite(String fromUrl, String toUrl) {
        RewrittenUrl rewrittenUrl = rewriter.processRequest(new MockRequest(fromUrl), new MockResponse());

        assertNotNull("Could not rewrite URL from:" + fromUrl + " to:" + toUrl, rewrittenUrl);

        assertEquals("Rewrite from:" + fromUrl + " to:" + toUrl + " did not succeed", toUrl, rewrittenUrl.getTarget());
    }

    /**
     * Tests that an outbound url is processed correctly by the outbound rules
     *
     * @param fromUrl the url as you would be writing it in your JSPs
     * @param toUrl what you expect it to be rewritten to when rendered
     */
    public void assertOutboundRewrite(String fromUrl, String toUrl) {
        UrlRewriteWrappedResponse wrappedResponse =
                new UrlRewriteWrappedResponse(new MockResponse(), new MockRequest(fromUrl), new UrlRewriter(conf));

        assertEquals("Rewrite from:" + fromUrl + " to:" + toUrl + " did not succeed", toUrl, wrappedResponse.encodeURL(fromUrl));
    }

}

Usage

Below is an example of how SeemoreJ's rewrite rules in urlrewrite.xml for this site might look for the home page. At the time of writing, this site does not use UrlRewrite, so it's entirely hypothetical.

<!-- Index/Home -->
    <rule>
        <from>^/$</from>
        <to>/seemore?sjController=blog&amp;sjAction=home&amp;sjFormat=html</to>
    </rule>
    <rule>
        <from>^/index.(xml|html)$</from>
        <to>/seemore?sjController=blog&amp;sjAction=home&amp;sjFormat=$1</to>
    </rule>

    <outbound-rule>
        <from>/seemore\?sjController=blog&amp;sjAction=home&amp;sjFormat=(xml|html)</from>
        <to>/index.$1</to>
    </outbound-rule>

I might be making numerous minor or major changes to this file and I want the unit tests to defend against unwanted side-effects. So the test case below will (hopefully) make sure I don‘t mess things up.

package com.malethan.blog.urlrewrite;

import some.pakage.name.UrlRewriteTesting;
import org.junit.Test;

import java.io.FileNotFoundException;

public class UrlRewriteRulesTest {
    //----------------------------------------------------------------------- Instance Properties

    UrlRewriteTesting context;

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

    public UrlRewriteRulesTest() throws FileNotFoundException {
        context = new UrlRewriteTesting(System.getProperty("basedir") +"/src/main/webapp/WEB-INF", "urlrewrite.xml");
    }

    //----------------------------------------------------------------------- Tests

    @Test
    public void testIndexInbound() {
        context.assertInboundRewrite("/", "/seemore?sjController=blog&sjAction=home&sjFormat=html");
        context.assertInboundRewrite("/index.html", "/seemore?sjController=blog&sjAction=home&sjFormat=html");
        context.assertInboundRewrite("/index.xml", "/seemore?sjController=blog&sjAction=home&sjFormat=xml");
    }

    @Test
    public void testIndexOutbound() {
        context.assertOutboundRewrite("/seemore?sjController=blog&sjAction=home&sjFormat=html", "/index.html");
        context.assertOutboundRewrite("/seemore?sjController=blog&sjAction=home&sjFormat=xml", "/index.xml");
    }
}

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

Ruby has Rspec. Where's Jspec?

In my new job I am almost exclusively working with Java. Not only that, I‘m working as part of an established team, so I‘m working to their conventions and processes. So I‘m not working with the same variety of technologies as I am used to.

Having been away from Ruby land for a couple of weeks it‘s made me think about how practitioners of Ruby and those of Java differ in approach. Now, I‘m not saying for a second you have to exclusively be one camp or the other. Neither am I saying that being a Java developer somehow defines the way you think, likewise for Ruby.

However, in Ruby land you hear words like elegant , beautiful and expressive as being considered virtuous adjectives to describe solutions or source code. You don‘t hear those words half as often in Java land, it‘s a little more ruthless and business-like. There‘s a little less magic.

This got me thinking. One of my favourite Ruby frameworks is Rspec. What if someone had tried to implement a testing framework in Java using some of the ideals that the developers of Rspec employed? One of the reasons I like Rspec is it‘s sheer expressiveness. That and the fact it actually generates documentation that a non-developer could read and QA the solution against (well, if the specs are well written anyway).

Jspec?

Jspec is the fictional Java implementation of Rspec. I'm not sure if there is already a Jspec but it‘s as good a name as any to describe the fictional framework I‘m about to introduce.

Anyway what would Jspec look like? How does the Java syntax and idioms allow us to implement such a framework in the most expressive, elegant and beautiful way? Firstly let‘s look at what our test might look like using rspec to test MyWidget.

JHighlight doesn't support Ruby, so the syntax highlighting isn't great.

Pure english descriptions of our tests
describe "My Widget in some scenario" do
    before(:all) do
        # Some bootstrapping
    end

    before(:each) do
        # Some initilaisation of info
        @my_widget = MyWidget.new
    end

    describe "Given some conditions" do

        it "should satisfy some criteria" do
            @my_widget.perform_functionality

            @my_widget.result.should == "Hello World!"
        end

        it "should produce some specified results" do
            # Some testing
        end
    end
end

References the class directly
describe MyWidget, "Given in a different scenario" do
    it "should satisfy some condition we apply" # Results in a warning about a pending test
end

This doesn‘t look much like your average Ruby program. It looks like a DSL that someone came up with to describe tests in an elegant way. But it‘s not a DSL, it is perfectly valid Ruby code. Ruby has the syntactic flexibility to allow such elegant and expressive solutions. Some might even say that it is beautiful. It also has the feature of blocks and/or closures, which are unnamed blocks of code or functions that can be passed around. They‘re the biggest reason Rspec is the way it is.

Well, Java doesn‘t have unnamed functions or the ability to pass blocks of code about, well not yet anyway. The nearest thing Java has at the moment is Anonymous Classes.

Jspec using Anonymous Classes

Below is what Jspec might look like if it was implemented in today‘s Java, using Anonymous Classes. I hasten to add that I haven't implemented any of this beyond code stubs. This is just theoretical.

package com.malethan.jspec;

import static com.malethan.jspec.Jspec.*;
import com.malethan.jspec.annotations.Spec;
import com.malethan.jspec.annotations.Before;


class MyWidgetSpec {
    MyWidget thing;

    @Spec   //to mark this method as a runnable spec
    public void test() {

        describe(new Example("My Widget in some scenario") {

            @Before(ALL)
            public void setup() { /* ... */ }

            /**
             * Runs before each Should block
             */
            @Before(EACH)
            public void beforeEach() {
                thing = new MyWidget();
            }

            public void run() {
                describe(new Example("Given some conditions") {
                    public void run() {
                        itShould(new Satisfy("a given criteria or condition") {
                            public void run() {

                                thing.performFunctionality();

                                specify(thing).getResult(); should(eq("Hello World!"));
                            }
                        });

                        itShould(new Satisfy("should produce some specified results") {
                            public void run() {
                                // Some testing
                            }
                        });
                    }
                });
            }
        });

        //References the class directly
        describe(new Example(MyWidget.class, "Given in a different scenario") {
            public void run() {
                itShould(new Satisfy("should satisfy some condition we apply")); //Results in a warning about a pending test
            }
        });

    }
}

A word of explanation: The methods describe, itShould and specify are all static methods on the Jspec class. Similarly ALL and EACH are both static properties on Jspec, though these could be replaced by a separate enum perhaps. Example extends an abstract class that requires it implement the run() method. The class Satisfy extends a class that has a default implementation or run() that generates a warning (or it would if I had actually implemented any of this).

Whilst the code above satisfies expressiveness – to the extent one can using the Java syntax – it's not really that elegant and it certainly isn't beautiful. There is also far too many parentheses cluttering up the code. My conclusion is I should stick to JUnit or TestNG for the time being.

However, what might Java have in store for us in future and will this allow us more elegant, beautiful solutions? Closures might be available to us in the next release of Java. This is what Jspec might look like implemented using Java 1.7.

package com.malethan.jspec;

import static com.malethan.jspec.Jspec.*;
import com.malethan.jspec.annotations.Spec;


class MyWidgetSpec {
    MyWidget thing;

    @Spec   //to mark this method as a runnable spec
    public void test() {

        describe("My Widget in some scenario", {

            before(ALL, { /* ... */ });

            /**
             * Runs before each Should block
             */
            before(EACH, {
                thing = new MyWidget();
            });

            describe("Given some conditions", {
                it("should satisfy a given criteria or condition", {
                    thing.performFunctionality();

                    //Like how jMock does expectations in 2.x API
                    specify(thing).getResult(); should(eq("Hello World!"));
                });

                it("should produce some specified results", {
                        // Some testing
                });
            });
        });

        //References the class directly
        describe(MyWidget.class, "Given in a different scenario", {
            it("should satisfy some condition we apply"); //Results in a warning about a pending test
        });

    }
}

Voila! Definitely expressive – at least as much as Ruby. Arguably elegant and I think it could almost be considered beautiful. In fact the solution using closures is so like Rspec I wouldn‘t be surprised if someone is working on a port of it to Java 1.7 already. That is of course if the closures idea is going to be included in the next release of Java.

If someone is working on a port of Rspec, I‘d love to hear about it. Also, let‘s hope closures make it into Java 1.7.

First published on Dec 13, 2008. Last updated on: Jan 26, 2009.

 
People I like
Other sites