Location, Location, Location and JAXP
Still on the XSLT theme. The XSLT transformed output contains urls for the hyperlinks, images and stylesheets. To get relative urls to work the same in different browsers after responses are made up on the fly, dispatched and filtered is impossible. Set Content Base header doesn't work.
JAXP comes to the rescue here by allowing us to inject an absolute url into the transform object:
tf = TransformerFactory.newInstance();
xform = tf.newTransformer(new StreamSource(ctx.getResourceAsStream(xslt)));
The XSL transformation picks up this value as a parameter:
<xsl:param name="absolute_url" select="'http://default'"/>
The absolute url can be picked up on the fly with something like:
StringBuffer absoluteUrl = new StringBuffer("http://");
String serverName = request.getServerName();
int serverPort = request.getServerPort();
if (serverPort > 0 && serverPort != 80)
absoluteUrl.append(":" + serverPort);
String contextName = request.getContextPath();
absoluteUrl.append(contextName + "/");
Posted at 06:31AM Jul 30, 2006 by Brian Peter Clark in View Factory & XSLT |
XSLT, Servlet Filter and a Squeak on Browser Reload
The SOCKET view layer uses XSLT in a servlet filter to transform XML content to HTML for the browser.
Everything worked fine - until, that is, one clicked the refresh button on the browser when the thing squeaked about a premature end to the file that was being transformed.
The problem went away with Cache-Control = no-store, Pragma = no-store, and Expires = a long time ago set on the response headers. (Firefox doesn't work with 'no-cache' instead of 'no-store', IE is indifferent.) Not quite, though. When the university proxy server was switched on through the browser LAN settings, again the refresh failed.
I've only just stumbled upon an explanation of what's going on in Eric Burke's book, Java & XSLT, out of O'Reilly. Even the expert said that it was a difficult one to track down.
The error arises from the fact that in certain circumstances Tomcat re-uses the same HttpServletResponse object. One of these circumstances is the browser reload. Burke states that the servlet specs are not definitive on this point so that implementation dependent behaviour will be observed. We haven't tested on anything other than Tomcat 5 and 5.5, while Burke referred to version 4.
And so, the problem is finally laid to rest. It put up a good fight. The solution is to test for a zero or null output byte array from the ByteArrayPrintWriter, and, if positive, send back the original unwrapped response with
instead of the
which results in the squeak. Job's a good 'un.
Posted at 06:12AM Jul 30, 2006 by Brian Peter Clark in View Factory & XSLT |
The Industrial Estate Design Pattern
Atif, SOCKET lead developer, always shakes his head in a disapproving manner whenever I refer to the SOCKET view application (code: Sun, Rob & I; XSLT: Rob) as the "View Factory". "It's not a factory. It's a servlet filter that calls an XSLT transformation". Atif is, indeed, correct. As it stands, the View won't fit in with the elegance of the design of the rest of the project. Atif has seen to it that the core functionality of SOCKET is highly modular and pluggable. Even the plugs have plugs. So the View must become a true View Factory. (Sink me, a hacker such as meself straying into Gang of Four territory feels most odd.) Not that this is an unreasonable development: the Abstract Factory Pattern is often applied in affairs of the View. Swing abounds with factories.
There is a 2-dimensional structure at the heart of the implementation of the Abstract Factory Pattern. For example, one dimension could be the platform, such as Windows, Motif or MacOS, and the other could be a range of view widgets. A program might be charged with producing widgets so that the program can easily be configured for each particular platform.
In SOCKET, one dimension can be looked on as View Technology and the other as User Agent. The pluggable consumer software module that is in place at the moment happens to feed out an xml file, an abstract Graphical User Interface Descriptor (GUID), to be posh. The natural view technology is therefore an XSLT transformation. However, another implementation of the consumer module (OK, the consumer factory) might send out a bean, in which case a more natural view technology might be a JSP page or a pojo beanhandler.
So what is required is a Factory architecture that will facilitate the production of the View for a range of technologies and a range of User Agents - browsers, PDAs, WAP and so on. And so, we start with an interface. (By the way, I refuse to put Impl on the end of everything that derives from an interface. It's damned ugly - for a start, Impl is too close to pimple.)
public interface ISocketViewFactory
//For PC browsers.
public abstract XhtmlView createXhtmlView();
//For range of mobile devices.
public abstract XhtmlBasicView createXhtmlBasicView();
//For WAP browsers.
public abstract WmlView createWmlView();
I might even add a special one for my pride and joy, my Nokia 770
We can then have an XSLT factory, say.
public class XsltSocketViewFactory implements ISocketViewFactory
public XhtmlView createXhtmlView()
return new XsltXhtmlView();
public XhtmlBasicView createXhtmlBasicView()
return new XsltXhtmlBasicView();
public WmlView createWmlView()
return new XsltWmlView();
Each returned view object will have a transform method to carry out the actual data transformation.
Now the good bit - the SocketViewFactoryFactory - a factory to create the factory. Depending on an input parameter, a different implementation of the view factory can be returned.
public class SocketViewFactoryFactory
private static SocketViewFactoryFactory soleInstance = new SocketViewFactoryFactory();
//XSLT-based view factory.
public final static int XSLT = 1;
//View factory processes Java bean containing view data.
public final static int BEANHANDLER = 2;
* Private constructor brings about singleton status.
* Returns the one and only instance of the SocketViewFactoryFactory.
* @return soleInstance
public static SocketViewFactoryFactory getInstance()
* Returns a SocketViewFactory whose type is determined by the
* technology integer.
* technology = 1 => XSLT factory
* technology = 2 => BeanHandler factory
* @param int technology
* @return ISocketViewFactory
public ISocketViewFactory createSocketViewFactory(int technology)
return new XsltSocketViewFactory();
return new BeanHandlerSocketViewFactory();
return new XsltSocketViewFactory();
Is that OK, Atif? I need what now? A message queue???
Some factory classes are completely populated by factory methods. A good name for this might be the Industrial Estate Design Pattern. Might not internationalize well.
ps The Pojo BeanHandlers is actually the name of a Tennessee mountain jug band.
Posted at 03:00PM Jun 18, 2006 by Brian Peter Clark in View Factory & XSLT |
EE, isn't the View luvvly...
In the past five years or so there seems to have been a moderate and growing interest in the subject of abstract descriptions of the user interface (UI) to software applications (Wikipedia lists about 20 different flavours). Starting from an abstract user interface description (UID), transformations can be applied to create concrete UIs suitable for a range of different client devices and display technologies.
XML is the universally favoured tool for the UID language (UIDL) and transformations can be carried out by direct programmatic manipulation of the markup or using XSLT transformations.
One important part of the SOCKET project is the View Factory (VF), a servlet filter that renders a view from an XML feed produced by the service consumer software.
I've just about convinced meself that the technology that will ultimately constitute the main part the SOCKET VF will be XForms. The browser interface is form-based: data that will populate the soap message are posted to a server before being sent orff using Axis. However, the time is not right - for a small project team and a short project I suspect that it is an API too far to give it proper attention. Also, getting to grips with the various XForm engines would be a task. We are all doing well with WSDL, SOAP, JAX-RPC, Axis, UDDI, XSLT/XPath, and Aggie has just tamed Windows Server 2003, IIS 6, SQL Server 2005 and Questionmark Perception. It is simpler at present to create a poor man's XForms (an extremely poor man - more than a poor man - a man deeply in debt - a lost soul - OK, to tell the truth, nothing like XForms). A couple of drafts of the VF schema had been completed before I tracked down the schema from the WSGUI project originally instigated at Stanford University as part of the FX-Agents research project (Michael Kassoff, Daishi Kato, Waqar Mohsin) and revised by Josef Spillner (January 2006 - see http://web.inf.tu-dresden.de/~js177634/webservices/wsgui.html). This is the closest thing I've seen to my original impression of how the design should go. The SOCKET VF schema is more agricultural, the initial aim being to keep the XSLT processing relatively straightforward. However, the SOCKET version is strongly typed, which allows a greater degree of client-side validation. With Web services you have two bites at client-side validation: first bite on the browser; and second bite using the consumer software (OK, it's really server-side validation). I suppose it's validation of the individual input parameters on the browser and schema-based message validation by the consumer software should a schema be available.
Posted at 07:36PM May 03, 2006 by Brian Peter Clark in View Factory & XSLT |