December 10, 2014

Had my own 'Meet the Ancestors' Moment Earlier in the Week.

It all started when I was chatting with friends about the upcoming centennials for various World War 1 campaigns and I mentioned that I believed a family member died at Gallipoli. One of my friends expressed great surprise as they had believed that only Australians and New Zealanders had died there. I decided to find out a little more and a little judicious internet surfing rapidly made it clear that the Gallipoli Campaign had been pretty bloody killing over a hundred thousand soldiers and wounding many more before it ground to a halt. Of those deaths the majority were British.

With that knowledge I asked my mother about it, it turned out that my among my father's nicknames were 'The War Memorial' or 'Granite with Knobs On' as he had been named for his uncle who had died at Gallipoli. My mother further added that this was in part an act of atonement as my paternal grandfather had been his commander at the time.

I then dug a little deeper and the first thing I found was this article about a remembrance last year (2013) for the campaign which quoted the gravestone of a Lieutenant Commander J.R.Boothby (my father was J.R.M.Boothby). The quote just felt right:
With undaunted heart he breasted life's last hill.
Apparently the families were given just 64 characters and I was really glad that, if this was my great-uncle, my family had done so well.

As I dug further I discovered that Lt. Cdr. J.R.Boothby had died early in May 1915 as part of the RNAS Armoured Car Squadron. I dug further and discovered that the RNAS was in fact the Royal Naval Air Service a forerunner of both the Fleet Air Arm and the RAF. What I hadn't realised was that the RNAS had the only mechanized land forces in the British forces at the start of the war. In fact it formed the nucleus of the unit that created the first tank.

With that I managed to understand how my grandfather fitted in when I discovered this book called the Devil's Chariots and on perusal of the limited pages made available by Google I was able to determine that my grandfather had been in command of the RNAS Armoured Car Division at the time of Gallipoli so it all tied up.

I'm still researching the topic but as a result I'm going to see what I can do for the centenary of my great-uncle's death to remember him and his sacrifice.

November 19, 2014

A Judicious Use of Generics to Simplify Working With Java Maps.

I've always been a little ambivalent about Generics in Java but every now and then I come across a neat usage that really helps out.

In this case the neat usage is with Java Maps.

Java Maps Generics have always struck me as being a little all or nothing you can use generics to define the types of all the keys and all the values but it's a bit blunt instrument there is no way to individually relate the key to the type of the value.

To that end I've created a little open source code that certainly works for me in many use cases: TypedMap on GitHub. I'll get round to releasing a Maven-ised version of this on a public repo soon, but the code is pretty trivial.

It introduces an interface called a TypedKey that takes a generic type parameter that indicates the type of the value related to the key. This interface has no methods and can be implemented by any of your classes so that they can be used as keys.

It then introduces an interface called TypedMap which extends the core java.util.Map interface to add three new methods, putTyped, getTyped and removeTyped. These are generically typed variants on the java.util.Map put, get and remove methods taking a TypedKey to define the type of the value being worked with.

Taking advantage of the way Generics works, these interfaces provide compile time type safety and eliminate the need for casting values retrieved from the map as long as an appropriate TypedKey is used.

Two concrete implementations of the interfaces are provided: DefaultTypedKey and TypedMapDecorator.

The DefaultTypedKey is the simplest possible implementation of the TypedKey interface, it is a direct child of java.lang.Object and inherits the hashcode and equals semantics.

TypedMapDecorator delegates all java.util.Map functionality to an embedded Map instance and implements the typed methods backed by the embedded Map.

I'm still working on the generics usage to make it more elegant and to provide a greater degree of control to the user, but even in this version I believe that the use of a TypedMap with TypedKeys can significantly simplify code in many use cases.

June 30, 2014

Spring-WS Default Endpoint Configuration

We've recently been trying to set up some web services that provide common security functionality such as signing and signature verification. We really wanted to keep them generic as we did not want to have to set up individual operations and services. We chose to use Spring-WS because it had the concept of a default endpoint that could be configured to consume any web service not otherwise handled. For the security element we chose to use WSS4J Interceptors.

When it came to setting up the default endpoint I could find nothing at all that clearly defined how to do it, Spring Documentation, Spring Forums and even blog posts and Stack Overflow did not seem to have the answer. In the end it took trial and error and a certain amount of reading the source code to work out the magic sauce.

To save others the pain I thought that I would record a how-to here.

<beans xmlns:context="http://www.springframework.org/schema/context" xmlns:sws="http://www.springframework.org/schema/web-services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.yourpackage">

    <sws:annotation-driven>

    <bean class="org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter" id="messageEndpointAdapter" lazy-init="false">

    <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" id="endpointMapping" lazy-init="false">
        <property name="defaultEndpoint">
            <ref bean="defaultEndpoint">
        </ref></property>
    </bean>

    <bean class="com.yourpackage.DefaultEndpoint" id="defaultEndpoint">
    
</bean></bean></sws:annotation-driven></context:component-scan></beans>

The spring beans configuration supports annotation based component scan which is how I would normally set up endpoints but in the case of a default endpoint there appears to be no annotation based approach. I've set up a MessageEndpointAdapter that will be used by the PayloadRootAnnotationEndpointMapping class to be able to communicate with the default endpoint. Finally we explicitly set up the Endpoint Mapping with our default endpoint set in as a property.

The default endpoint implements the MessageEndpoint interface which uses a generic mechanism for representing the incoming message called the MessageContext. Below you can see an example where the default endpoint echoes the request message to be the response.

package com.yourpackage;

import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.endpoint.MessageEndpoint;


public class DefaultEndpoint implements MessageEndpoint{
   @Override
    public void invoke(MessageContext messageContext) throws Exception {
        messageContext.setResponse(messageContext.getRequest());
    }
}


To be honest setting up a default endpoint is not hard once you know how. Shame the documentation isn't really there.