Listing 1: Example of JAXP XSLT Transform to HTTP Servlet Response

TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer =
transformerFactory.newTransformer(styleSource);
CharArrayWriter caw = new CharArrayWriter();
StreamResult result = new StreamResult(caw);
transformer.transform(xmlSource, result);

response.setContentLength(caw.toString().length());
out.write(caw.toString());


Listing 2: ApplyXSLTFilter.java

package filter;

import java.io.CharArrayWriter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class ApplyXSLTFilter implements Filter {

	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	FilterConfig filterConfig = null;

	/**
	 * Perform filtering action to apply XSLT
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest)request;

		System.out.println("Starting the filter...");
		System.out.println("Path info: " + req.getRequestURI());

		// Determine XSLT attributes
		String styleSheetPath = determineStylesheetPathFromRequest(req);
		String contentType = determineContentTypeFrom(req);
		String styleSheetName = determineStylesheetNameFromRequest(req);
		String styleSheet = styleSheetPath + styleSheetName;

		System.out.println("Here is the stylesheet we are going to load: ?" + styleSheet);

		response.setContentType(contentType);
		String stylePath =?
		this.filterConfig.getServletContext().getRealPath(styleSheet);
		File styleFile = new File(stylePath);

		if (!styleFile.exists()) {
		    System.out.println ("File " + styleFile + " does not exist");
		} else {
		    System.out.println ("File " + styleFile + " exists!");
		}

		System.out.println("Retrieving stylesheet Real Path: " + stylePath);
		Source styleSource = new StreamSource(styleFile);

		PrintWriter out = response.getWriter();
		CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse)response);
		chain.doFilter(request, wrapper);

		// Get response from Servlet
		StringReader sr = new StringReader(wrapper.toString());
		Source xmlSource = new StreamSource((Reader)sr);

		// Ok... Transform the xml:
		try {
			Transformer transformer = transformerFactory.newTransformer(styleSource);
			CharArrayWriter caw = new CharArrayWriter();
			StreamResult result = new StreamResult(caw);
			transformer.transform(xmlSource, result);

			response.setContentLength(caw.toString().length());
			out.write(caw.toString());
		} catch (Exception ex) {
			out.println(ex.toString());
			out.write(wrapper.toString());
		}

	}

	public void init(FilterConfig arg0) throws ServletException {
		this.filterConfig = arg0;
	}

public void destroy()  {
	this.filterConfig = null;
}

	/**
	 * Determine stylesheet path from request
	 * @param req
	 * @return
	 */
private String determineStylesheetPathFromRequest(HttpServletRequest req) {

		String userAgent = req.getHeader("user-agent");
		if (userAgent.indexOf("MSIE") > -1) {
			return "/stylesheets/ie/";
		}


		if (userAgent.indexOf("MobileExplorer") > -1) {
			return "/stylesheets/wml/";
		}

		return "/stylesheets/ie/";
	}

	/**
	 * Determine stylesheet name from request
	 * @param req
	 * @return
	 */
private String determineStylesheetNameFromRequest(HttpServletRequest req) {

	String uri = req.getRequestURI();
	int index = uri.lastIndexOf('/');
	uri = uri.substring(index + 1);
	System.out.println("Parsed URI: " + uri);

	if (uri.equals("index.jsp")) return "index.xsl";
	if (uri.equals("ListCustomers.do")) return "customers.xsl";
	if (uri.equals("customers.jsp")) return "customers.xsl";
	if (uri.equals("CreateCustomer.do")) return "customer_created.xsl";
	if (uri.equals("customer_created.jsp")) return "customer_created.xsl";
	if (uri.equals("CreateOrder.do")) return "order_created.xsl";
	if (uri.equals("order_created.jsp")) return "order_created.xsl";
	if (uri.equals("ListCustomerOrders.do")) return "orders.xsl";
	if (uri.equals("orders.jsp")) return "orders.xsl";
	if (uri.equals("failure.jsp")) return "failure.xsl";

	return null;

}

	/**
	 * Determine content type request
	 * @param req
	 * @return
	 */
	private String determineContentTypeFrom(HttpServletRequest req) {

		String userAgent = req.getHeader("user-agent");
		if (userAgent.indexOf("MSIE") > -1) {
			return "text/html";
		}

		if (userAgent.indexOf("MobileExplorer") > -1) {
			return "text/vnd.wap.wml";
		}

		return "text/html";
	}

}

Listing 3: CharResponseWrapper.java

In the code above, we use reference to CharResponseWrapper class that is used to wrap HttpServletResponse, so its
 String contents can be easily retrieved when needed.


package filter;

import java.io.CharArrayWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CharResponseWrapper extends HttpServletResponseWrapper {

	private CharArrayWriter output;

	public String toString() {
		return output.toString();
	}

	public CharResponseWrapper(HttpServletResponse response) {
		super(response);
		output = new CharArrayWriter();
	}

	public PrintWriter getWriter() {
		return new PrintWriter(output);
	}
}


Listing 4: Filter Mapping

<filter>
		<filter-name>ApplyXSLTFilter</filter-name>
		<filter-class>filter.ApplyXSLTFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>ApplyXSLTFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>ApplyXSLTFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
	</filter-mapping>


Listing 5: The original customers.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Customers list</title>
</head>
<body>

<jsp:useBean id="customers" type="java.util.ArrayList<domain.

Customer>" scope="request"/>

<b>Registered Customers:</b><br>
<table border="1">
<tr>
	<th>ID</th>
	<th>First Name</th>
	<th>Last Name</th>
	<th>Address</th>
	<th>Orders</th>
</tr>
<% for(domain.Customer c : customers) { %>
<tr>
	<td><%= c.getId() %></td>
	<td><%= c.getFirstName() %></td>
	<td><%= c.getLastName() %></td>
	<td><%= c.getAddress() %></td>
	<td><a href="/DBTestSH/ListCustomerOrders.do?cust_id=<%= c.getId() %>">Orders</a></td>
<% } %>

</body>
</html>


Listing 6: XML-based customers.jsp

<?xml version="1.0" encoding="UTF-8"?>

<jsp:useBean id="customers" type="java.util.ArrayList<domain.Customer>" scope="request"/>

<DATA_LIST>
<% for(domain.Customer c : customers) { %>
<CUSTOMER
	ID="<%= c.getId() %>"
	FIRST_NAME="<%= c.getFirstName() %>"
	LAST_NAME="<%= c.getLastName() %>"
	ADDRESS="<%= c.getAddress() %>"
	LINK="/DBTestSHWithXSLT/ListCustomerOrders.do?cust_id=<%= c.getId() %>"
/>
<% } %>
</DATA_LIST>


Listing 7: XSLT Style sheet for the customer display in the Microsoft Internet Explorer: customers.xsl

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="html" media-type="text/html"/>

<xsl:template match="/">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Customers list</title>
</head>
<body>

<b>Registered Customers:</b><br/>
<table border="1">
<tr>
	<th>ID</th>
	<th>First Name</th>
	<th>Last Name</th>
	<th>Address</th>
	<th>Orders</th>
</tr>
<xsl:for-each select="DATA_LIST/CUSTOMER">
<tr>
	<td><xsl:value-of select="@ID"/></td>
	<td><xsl:value-of select="@FIRST_NAME"/></td>
	<td><xsl:value-of select="@LAST_NAME"/></td>
	<td><xsl:value-of select="@ADDRESS"/></td>
	<td><a>Orders<xsl:attribute name="href"><xsl:value-of select="@LINK"/></xsl:attribute></a></td>
</tr>
</xsl:for-each>
</table>

</body>
</html>

</xsl:template>
</xsl:stylesheet>


Listing 8: WML style sheet for customer display

<?xml version="1.0"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="wml" media-type="text/vnd.wap.wml"/>
<xsl:template match="/">
<wml>

<card title="Registered Customers">
<table columns="5">
<tr>
	<th>ID</th>
	<th>First Name</th>
	<th>Last Name</th>
	<th>Address</th>
	<th>Orders</th>
</tr>
<xsl:for-each select="DATA_LIST/CUSTOMER">
<tr>
	<td><xsl:value-of select="@ID"/></td>
	<td><xsl:value-of select="@FIRST_NAME"/></td>
	<td><xsl:value-of select="@LAST_NAME"/></td>
	<td><xsl:value-of select="@ADDRESS"/></td>
	<td><a>Orders<xsl:attribute name="href"><xsl:value-of select="@LINK"/></xsl:attribute></a></td>
</tr>
</xsl:for-each>
</table>
</card>
</wml>

</xsl:template>
</xsl:stylesheet>


•   •   •   •