Saturday, October 15, 2005

Portlet technology rant

Now time for a little portlet whinge, it is long overdue...

Nobody is perfect and it is all too easy to criticise. There is something about the JSR168 portlet architecture that strikes me as a giant leap backwards. Maybe it is concept of modes (View, Edit, Help) that reminds me of my early days as a Perl programmer where a single script would deliver all the application pages. At least at first glance the portlet architecure appears to have little similarity with the much admired MVC architecture. JSR168 portlet development with all these different competing scopes existing in parallel is very confusing even for an experienced J2EE developer.

Best practices for portlet development have yet to be properly established. With the current absence of something like a portlet aware JSTL it makes current J2EE best practices difficult to translate into the portlet development arena.

This current void in the portlet technology stack is an opportunity for unscrupulous purveyors of MVC solutions and such to tout their wares as the missing pieces. I am a great admirer of Craig McClanahan's work but I have yet to see why JSF is better than Struts. This probably makes me a non-believer but if I was to choose a new framework technology to learn more about it is much more likely I would choose Spring rather than JSF. The likes of Sun's JSF are likely to benefit as Sun are shoehorning it into portlet creation wizards such as in their Java Studio Creator 2. I don't want to cast aspersions but I would also expect Oracle to take advantage of the confusion surrounding portlets by integrating JSF and their JSF extension ADF, into their portlet factory software.

Don't get me wrong, I'm sure that Sun, Oracle, IBM, Novell and all the other technologies that creep into my portlet applications by stealth will stand or fall on their own merits. However, call me old fashioned but I'd like to do the choosing of which technology I integrate into my portlets and this is why projects like Apache's Portals Bridge will be so important to make the connection between existing J2EE best practice and future portlet best practice.

...it's out of my system, I feel better now.

An extended <portlet:defineObjects/> tag

I have just created an extended version of Pluto's <portlet:defineObjects/> which will make additional portlet related implicit objects available. So you can access portlet scoped attributes using pure JSTL rather than via scriptlets.

You can find more information about this new extension on JASIG's wiki under portlet defineObjects tag extension.

This new tag extension is an interim measure as the best way to handle the new portlet scopes would be with a portlet aware version of JSTL. From what I understand a portlet aware version of JSTL is now being developed.

Thursday, October 06, 2005

Slabbekoorn's KML/GPX XSLTs, Robogeo & an E4X/Google Maps experiment

Some time back I produced a Google Maps page that would render the locations from a live GeoURL RDF feed. I also did some further experiments using XSLT with Google Maps, Google Earth, KML and GPX data formats.

Things elsewhere have moved on somewhat, William A. Slabbekoorn (aka Cybarber) has produced a set of XSLT to transform between the various GPX versions and Google Earth’s KML. He distributes these XSLTs with an IE specific format conversion hypertext application. After a quick scan, most of these XSL appear to be perfectly usable with other XSL engines (I tried some GPX conversion XSL with Javas Xalan and they worked well). There is now also a commercial application called Robogeo that can convert GPX and other formats into Google Maps html. I suspect there are probably other offerings about of which I am not aware.

As a further experiment with ECMAScript for XML (E4X), I thought I’d revisit my first GeoURL and Google Maps page but this time I would try and use E4X to do the XML processing. AFAIK, client side E4X is currently only implemented in Mozilla Firefox 1.5 Beta and Mozilla 1.8 Beta browsers.

I used Introduction to E4X: Part 1) Reading XML and Brendan Eich's E4X presentation, which incidentally uses Eric Meyer's S5 slide show system. An usuable E4X reference with examples is a little hard to find at present, the ECMA E4X spec is a little too technical for little 'ol me. You may like to compare the example below that uses E4X with my previous effort; is the XML feed processing easier to understand? I’ll let you decide.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://maps.google.com/maps?file=api&amp;v=1&amp;key=ABQIAAAA4Wxrd1ZmQfRHvggZWM0QkxTwM0brOpm-All5BF6PoaKBxRWWERTxZC7TxHvaaZq75azqC6aFU4f4gA" type="text/javascript">
</script>
<script type="text/javascript;e4x=1">
//<![CDATA[
function onLoad() {

var request = new XMLHttpRequest();
request.open("GET", "geourl.xml", false);
request.send(null);

var rdf = new XML(request.responseText.replace(/^[\s\S]*<rdf:RDF/, "<rdf:RDF"));
var rssNs = new Namespace("http://purl.org/rss/1.0/");
var geourlNs = new Namespace("http://geourl.org/rss/module/");

// Get first set of co-ordinates to set the centre of the map.

var long1=rdf.rssNs::item[0].geourlNs::longitude;
var lat1=rdf.rssNs::item[0].geourlNs::latitude;

var map = new GMap(document.getElementById("map"));
map.centerAndZoom(new GPoint(parseFloat(long1), parseFloat(lat1)), 4);

map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());

// Now add the markers from the list

var title,link,long2,lat2;
for each (var item in rdf..rssNs::item) {
title=item.rssNs::title;
link=item.rssNs::link;
long2=item.geourlNs::longitude;
lat2=item.geourlNs::latitude;
var point = new GPoint(long2,lat2);
var p = new XML("<p/>");
p.a.@href = link.*;
p.a.b = title.*;
var marker = createMarker(point, p);
map.addOverlay(marker);
}


}

function createMarker(point, html)
{
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function()
{
marker.openInfoWindowHtml(html);
}
);
return marker;
}
//]]>
</script>
<title></title>
</head>
<body onload="onLoad()">
<div id="map" style="width: 500px; height: 500px"></div>
</body>
</html>