Tuesday, April 20, 2010

How about iCalendar Autodiscovery?

Love it or hate it, iCalendar is the pervasive calendaring format. If we can enable RSS autodiscovery then why not do the same with iCalendar feeds. Adding one line of code would make it easier for people/machines to subscribe to an iCalendar feed.


<link rel="alternate" type="text/calendar"
title="iCalendar feed for example.com"
href=""calendar.ics"" />

Tuesday, March 30, 2010

Jasig UK 2010 meeting 21 and 22 June

Jasig are a consortium of educational institutions and commercial affiliates sponsoring open source software projects for higher education. Jasig project of particular note include uPortal (a powerful framework for producing campus portals) and CAS (a secure enterprise authentication system and single sign-on service).

The Jasig UK 2010 meeting will be held at Bristol University from Monday 21 to Tuesday 22 June.  The meeting will start at 14.00 on the Monday and finish by 14.00 on the Tuesday. Details can be found at:

http://www.ja-sig.org/wiki/display/UK/2010+Meeting+Bristol

If anyone wants to attend please update the "Interested in Attending" and "Suggested Topics" wiki pages with your details and items you are interested in discussing at the meeting. There is no charge for attending the meeting.

Friday, March 19, 2010

LinkedHashMap enhanced

In my day to day Java programming it is rare for me to feel the need to re-engineer or significantly enhance something quite fundamental to the Java language. I am a pretty average programmer, I get the job done, I like to do things elegantly but I do not spend my spare time creating my own languages and compilers (that stuff looks harder than "rocket science"). Most of the time the standard Java Collections Framework with the ArrayList, HashSet, HashMap and LinkedHashMap is more than ample for my meagre needs. Sometimes I have looked elsewhere to solve a particular problem; I had previously encountered the ArrayListMultimap from the Google Collections Library. This deviates from the standard Map implementations in that it allows you to create a "Map" which may associate multiple values with a single key (well technically it does not implement the Map interface but never mind!).

Google Collections' ArrayListMultimap

The ArrayListMultimap is really useful and very powerful. Imagine for example you wanted tag cloud functionality for a blog. You can iterate through your pages, putting them in your "cloudmap" (new ArrayListMultimap<String,URL>) using the tag as the map key. You can very easily get back a list of URLs with that tag key.


List<URL> links = cloudmap.get("java");

You can also very easily produce the tag counts necessary for a tag cloud using something like.


int linkcount = cloudmap.get("java").size();

My contribution: LinkedHashMap augmented

I have been working on a timetable related application recently which provoked me to extend the behaviour of LinkedHashMap. My situation was that I needed to produce a Map where the entry order of the data was important (e.g. insertion-order). Java Collections' LinkedHashMap is designed specifically for those requirements. I had an additional requirement to be able to fetch a portion of my map whose keys range from fromKey to toKey. LinkedHashMap does not itself implement this. TreeMap is a collections class which does permit accessing ranges of data, however, TreeMap does not support insertion-order. Instead TreeMap supports data with a natural ordering (e.g. numbers in numeric order, dates in chronological order). In my map, although the keys and values were important data, the natural ordering does not provide anything useful.

So I set about extending LinkedHashMap and came up with a class which implements the following interface:


public interface ILinkedHashMapAugmented<K, V> extends Map<K, V> {

LinkedHashMapAugmented<K, V> subMap(K fromKey, K toKey);

LinkedHashMapAugmented<K, V> subMap(int fromIndex, int toIndex);

Map.Entry<K, V> getEntry(int idx);
K getKey(int idx);
V getValue(int idx);
}

You can access the implementation of this interface at this link here LinkedHashMapAugmented.java. I make no claims about this being the most efficient code ever, if I wanted that I would take a copy of open source of LinkedHashMap and rather than extend it I would completely re-engineer it. I wanted something simple and what I have produced is useful and just feels right to me. The LinkedHashMap also supports access-ordering, I have not considered how my enhancement impacts on this but it could be useful.

So for a simplified example of my new class, I can define a week schedule like this:


LinkedHashMapAugmented<String, String> schedule = new LinkedHashMapAugmented<String, String>();
schedule.put("SV14", "21-Sep-09");
schedule.put("0", "28-Sep-09");
schedule.put("1", "05-Oct-09");
schedule.put("2", "12-Oct-09");
schedule.put("3", "19-Oct-09");
schedule.put("CV1", "14-Dec-09");
schedule.put("11", "11-Jan-10");
schedule.put("12", "18-Jan-10");
schedule.put("13", "25-Jan-10");
schedule.put("EV1", "22-Mar-10");
schedule.put("21", "19-Apr-10");
schedule.put("22", "26-Apr-10");
schedule.put("23", "03-May-10");
schedule.put("SV1", "21-Jun-10");

If I want to get a Map containing data between the weeks labelled 21 to 23 I need only call:


schedule.subMap("21","23");

As insertion-order is significant I have also implemented the ability to retrieve the Nth position of Map.Entry, key or value.

I think I have produced a simple but useful enhancement to the LinkedHashMap. I could have implemented this functionality by using some combination of existing Collections classes and arrays but this single data structure approach feels better to me. I suppose I could complete the loop by implementing a similarly enhanced version of ArrayListMultimap but I currently do not have the need!

Tuesday, March 09, 2010

AJAX decoration: using jQuery Metadata for portlet AJAX

I recently examined a JSR 168 portlet which tackled the thorny area of AJAX in a Portlet ( incidentally the portlet I was looking at is the Jasig Calendar Portlet ). The technique used makes all AJAX requests into POSTs which are then passed via the portal and a redirect to a servlet to acquire the desired response. I am not new to JSR 168 portlets and have personally produced several portlets over the past few years. I have also solved the AJAX in a Portlet problem but in a completely different way. The solution I developed I am calling AJAX decoration and relies on the jQuery Metadata plugin. I think both techniques have their merits and possibly could be applicable to different scenarios. I will attempt to illustrate my solution with a simple example app (note this example is not an actual portlet and will work in your servlet container of choice).

The structure of each of my "portlet" JSPs in my example is something like this:

header.jsp


<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src=""jquery-1.3.2.min.js"><!--" --></script>
<script type="text/javascript" src=""jquery.metadata.js"><!--" --></script>
</head>
<body>
<div id="content-area">

footer.jsp


</div>
<script type="text/javascript">
var pageContext = "${pageContext.request.contextPath}";
var targetArea = "div#content-area";
</script>
<script type="text/javascript" src=""ajaxDecorated.js"><!--" --></script>
</body>
</html>

somepage.jsp


<%@ include file="header.jsp" %>
<h1>Some Page</h1>

<!-- Content goes here -->

<%@ include file="footer.jsp" %>

Notice that we will be using a consistent target area for our AJAX loaded content; in this case a div with the ID of "content-area". The jQuery Metadata plugin makes it possible to read data stored within CSS classes, doing this is a relatively clean way of storing data within our page. In this approach the content links are decorated with data and in turn this data is used to assign appropriate AJAX behaviour.

For a typical link using a GET we could use:


<a href=""page1.jsp"" class="ajaxRenderURL {link: '/page1.jsp'}">page 1</a>

For form submission we could use:


<form action="page2.jsp" class="ajaxActionURL {link: '/page2.jsp'}">
<input type="submit" />
</form>

The magic happens in the "ajaxDecorated.js" file. When the page initially loads initPage() is invoked which attaches AJAX loading behaviour to links and forms.


$(document).ready(function() {
initPage();
});

function setupLinks(){
var data = $(this).metadata();
var loadlink;
var tsSeparator = "&";
if(data.link.indexOf("?") == -1){
tsSeparator = "?"
}
if(!data.link.match("^" + pageContext)){
loadlink = pageContext + data.link + tsSeparator + new Date().getTime() + " " + targetArea;
} else {
loadlink = data.link + tsSeparator + new Date().getTime() + " " + targetArea;
}
$(targetArea).load(loadlink, null,
function () {
initPage();
});
return false;
}

function setupForms(){
var data = $(this).metadata();
var formdata = $(this).serializeArray();
var loadlink;
if(!data.link.match("^" + pageContext)){
loadlink = pageContext + data.link + " " + targetArea;
} else {
loadlink = data.link + " " + targetArea;
}
$(targetArea).load(loadlink, formdata,
function(){
initPage();
});
return false;
}

function initPage(){
$(targetArea).find('a.ajaxRenderURL').click(setupLinks);
$(targetArea).find('form.ajaxActionURL').submit(setupForms);
}

This technique adds AJAX to a web page in an unobtrusive way. In this simple example the URLs loaded by AJAX and those that would be loaded without are the same (page1.jsp, index.jsp etc). However, in an environment where the AJAX URLs and web page URLs are likely to be different or even change dynamically (such as in a portal) then this technique is equally applicable.

Thursday, February 25, 2010

DisplayTag: Producing Decorators for Lists of Maps

I have been using the Display tag library (hereafter referred to as displaytag) heavily on a big in-house web application project. Displaytag helped me make relatively short work of pagination and data export, the resulting pages look very professional to boot. Best of all using displaytag meant I was able to concentrate my efforts on other parts of the project.

Much of the time I use the displaytag in the typical way (e.g. to display collections of beans). However, the changeable nature of some of the reports required lead me to produce some of the screens using Lists of Maps. Lists of Maps are very easily acquired from a database (e.g. Spring's ColumnMapRowMapper). Once you configure displaytag to display lists of maps then you have the flexibility to make changes to the report contents purely by changing an SQL statement. Also using the SQL "AS" keywords means that user friendly table column names are easily supported. So by making use of lists of maps you can produce very flexible and easily extensible reporting screens.

So far, so good...

Formatting data and adding extra display columns

By default whether you are passing a collection of beans or a list of maps to displaytag it just works! e.g.


<display:table name="dummyData"></display:table>

Elsewhere where I have used the typical way (collections of beans) of supplying data to displaytag. Sometimes I need to reformat a date, currency column or change some columns into links. You can do most of this inside the JSP page (messy!) or alternatively you can make use of the displaytag TableDecorator. You can also use TableDecorator's to add new columns that don't exist in the data, however, once you start specifying custom generated columns then you need to explicitly specify all the columns you would like to see in the displaytag table, e.g.:


<display:table name="dummyData" decorator="edu.bristol.SampleDecorator">
<display:column property="id" />
<display:column property="date" />
<display:column property="url" />
<display:column property="columnPopulatedByTableDecorator" title="Decorator generated"/>
</display:table>

I wanted to do this with a list of maps. After a little research on the forums, I found that you could still make use of TableDecorator generated custom columns by explicitly specifying the columns in your map. As the data originates from the database, each list row will contain a map with the same set of map keys. First you retrieve the map keyset from the first result row, store this keyset in the request and then you can explicitly iterate through the map columns:


<display:table name="dummyData" decorator="edu.bristol.SampleDecorator">
<c:forEach items="${keyset}" var="key">
<display:column property="${key}" />
</c:forEach>
<display:column property="columnPopulatedByTableDecorator" title="Decorator generated"/>
</display:table>

At this point, the "columnPopulatedByTableDecorator" will be generated but the TableDecorator doesn't do any re-formatting of the existing data columns.

Producing Decorators for Lists of Maps

So now we come to the novel aspect of this blog entry! The next question is how I reformat the data in my list of maps for displaytag purposes. I searched through the forums and couldn't get an answer for this, so I came up with a solution. Internally, displaytag uses Commons BeanUtils for data manipulation. We have seen that it can handle lists of maps without any additional configuration - so it must be doing something clever! The TableDecorator test code for displaytag includes tests for accessing mapped data, so I knew that it should be possible to access the mapped data in my own TableDecorator. Part of the difficulty in accessing the data is that my key names were not easily transformed into Java method names, the keys contain spaces, capitalization and other characters that are not permitted in a method name. My solution was to alter my list of maps to become a list of "wrapped maps". Where a wrapped map looks something like:


public class WrappedMap {

Map m;

public WrappedMap(Map m) {
this.m = m;
}

public Object getMap(String propertyName) {
return m.get(propertyName);
}
}

My decorator for this list of wrapped maps could now access my oddly named keys, such as:


public class WrappedMapDecorator extends TableDecorator{

final private String startDate = "Start Date";
final private String websiteAddress = "Website Address";

public String getMap(String propertyName){
WrappedMap wm = (WrappedMap) getCurrentRowObject();
Object propertyValue = wm.getMap(propertyName);
if(startDate.equals(propertyName)){
// Implement appropriate formatting/decoration
return "<i>" + propertyValue.toString() + "</i>";
}
if(websiteAddress.equals(propertyName)){
// Implement appropriate formatting/decoration
return "<b>" + propertyValue.toString() + "</b>";
}
return propertyValue.toString();
}

}

Finally, my JSP would need to be tweaked to produce the appropriate table:


<display:table name="dummyData" decorator="edu.bristol.WrappedMapDecorator">
<c:forEach items="${keyset}" var="key">
<display:column property="map(${key})" title="${key}" />
</c:forEach>
<display:column property="columnPopulatedByTableDecorator" title="Decorator generated" />
</display:table>

I am happy with this solution. I maintain the flexibility that the List of Maps technique makes possible but it is also possible to decorate the supplied data.

Incidentally, you may have noticed that I haven't been blogging much in recent times. I am now the father of 2 pre-schoolers and so what free time I get is usually spent collapsed in a heap rather than blogging! Anyway I hope you find this useful...

Friday, August 21, 2009

Spring Web Flow 2 Web Development: Book Review

I have been keeping the good people of PACKT Publishing waiting some time for this short review; they were kind and prompt in sending me their book - in my defence I have been very busy lately. I had hoped to include some example code but as I am still short on time right now I thought I would release a general review first and maybe something with some example code at a later date when I've had some more time to digest the book further. To business, Spring Web Flow 2 Web Development is a book for Spring developers who want to give Spring Web Flow a try. So what is Spring Web Flow? As described in following excerpts from the book (page 9):

"...- you can use Spring Web Flow to create conversational web applications. ...For example, take an application with a wizard-like interface. ...You are working in a predefined flow with a specific goal, such as ordering a book or creating a new user account. ...Spring Web Flow makes it very easy to create flows. Flows created by Spring Web Flow are not only decoupled from the applications logic, but are also re-usable in different applications. A flow in Spring Web Flow is a sequence of steps, that is, with states and transitions between them. There are also actions that can be executed on various points, for example, when the flow starts or the web page is rendered..."

This book is intended to describe Spring Web Flow 2 and any book which ties itself to a particular version is going to date quickly but that said you are bound to learn something new reading this book.

The book contains the obligatory chapters describing the Spring Web Flow 2 concepts and exploring what has changed since the last version, the distribution and example code. It also has a chapter on setting up your development environment be that Ant, Maven, Eclipse (and Spring IDE) or NetBeans. A chapter on JavaServerFaces integration using the Spring Web Flow 2 "Spring Faces" module, as I've never properly explored JavaServerFaces I'm not qualified to comment on this. The sample project that is used throughout the book is a simple bug tracking system ("flow.trac"). With this project there is plenty of scope to explore what Spring Web Flow 2 has to offer in terms of user interface (JavaScript including AJAX, Apache Tiles etc.), testing (JUnit and EasyMock) and security (Spring Security) whilst utilising a JPA (Hibernate) database layer. In the appendix it shows you how you can run your code on the SpringSource dm Server and gives a gentle introduction to making you application work in an OSGi environment. The source code for the book is available @ www.packtpub.com/files/code/5425_Code.zip

One of my early impressions was one of surprise, I admit to raising an eyebrow that they chose to use Microsoft SQL Server 2008 Express Edition as their example database server. I would expect something more lightweight such as H2 or Apache Derby -e.g. something you could easily bundle as part of a Maven build.

The intended audience for this book seems to be people who plan to use the triumvirate of Spring, Spring MVC and Spring Web Flow. From my perspective Spring is a gimme and you are obviously interested in Spring Web Flow (that is why you bought the book!) but I'm not so sure you are always free to choose Spring MVC. To be fair the book goes to great pains to say that Spring Web Flow can be used with other technologies but as my main web development MVC framework is still good ole' Struts 1.3, it would be nice to see some examples of using Spring Web Flow 2 with something other than Spring MVC or maybe even in a more exotic environment like inside a Spring MVC portlet. Spring Web Flow 2 includes components for integrating with JavaScript. I have to admit to being a jQuery devotee so any alternate JavaScript technology seems a bit unnecessary to me but I can see it could be useful to some folks.

All in all and so far, I have found reading this book to be very enjoyable. It is nice to see how other developers go about things, I found myself reading and thinking "I wouldn't do it that way" AND "That's clever, I'd never have thought of that!". The experience of reading this book is very much like shadowing some very experienced senior Java developers.

Tuesday, August 11, 2009

Coming soon: Spring Web Flow 2 Web Development: Book Review

PACKT Publishing very kindly sent me a copy of Spring Web Flow 2 Web Development to review. I have been very busy with work so I have not yet gotten around to reviewing it but I plan to publish something in the not too distant future. So watch this space!