/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.piazza.commons.pagelet.xslt;
import hk.hku.cecid.piazza.commons.pagelet.HttpPageletAdaptor;
import hk.hku.cecid.piazza.commons.pagelet.Pagelet;
import hk.hku.cecid.piazza.commons.pagelet.TemplateElement;
import hk.hku.cecid.piazza.commons.servlet.RequestListenerException;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**
* HttpXsltPageletAdaptor is an HTTP pagelet adaptor which employs the XSLT
* technology for content rendering. It is basically same as the HTTP pagelet
* adpator except that all the involved pagelets, excluding the template, are
* XSL documents.
* <p>
* This pagelet adaptor supports an additional generation mode, "xml", which
* suppresses the XSL transformation. If the generation mode is "xml", no
* rendering will be done and the output will only be a trunk of consecutive XML
* sources.
*
* @author Hugo Y. K. Lam
*
*/
public abstract class HttpXsltPageletAdaptor extends HttpPageletAdaptor {
/**
* Processes the XSL pagelet. The transformation source for the given XSL
* pagelet will be retrieved by invoking the getPageletSource() method.
*
* @param pagelet the XSL pagelet.
* @throws RequestListenerException if there was any error occurred when processing the XSL pagelet.
*
* @see #transform(Pagelet, Source, HttpServletRequest, HttpServletResponse)
* @see #getPageletSource(TemplateElement, Pagelet, HttpServletRequest)
* @see hk.hku.cecid.piazza.commons.pagelet.HttpPageletAdaptor#processPagelet(hk.hku.cecid.piazza.commons.pagelet.TemplateElement, hk.hku.cecid.piazza.commons.pagelet.Pagelet, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void processPagelet(TemplateElement element, Pagelet pagelet, HttpServletRequest request,
HttpServletResponse response) throws RequestListenerException {
try {
if (pagelet != null) {
transform(pagelet, getPageletSource(element, pagelet, request), request, response);
}
}
catch (Exception e) {
throw new RequestListenerException("Error in processing XSL pagelet", e);
}
}
/**
* Processes the error generated by the XSL pagelet. The transformation
* source for the XSL error pagelet will be retrieved by invoking the
* getErrorSource() method.
*
* @throws RequestListenerException if there was any error occurred when processing the XSL error pagelet.
*
* @see #transform(Pagelet, Source, HttpServletRequest, HttpServletResponse)
* @see #getErrorSource(TemplateElement, Throwable, HttpServletRequest)
* @see hk.hku.cecid.piazza.commons.pagelet.HttpPageletAdaptor#processError(hk.hku.cecid.piazza.commons.pagelet.TemplateElement, java.lang.Throwable, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void processError(TemplateElement element, Throwable exception, HttpServletRequest request,
HttpServletResponse response)
throws RequestListenerException {
try {
transform(getErrorPagelet(request), getErrorSource(element, exception, request), request, response);
}
catch (Exception e) {
throw new RequestListenerException("Error in processing pagelet error", e);
}
}
/**
* Gets the transformation source for the given XSL pagelet.
*
* @param element the template element which represents the pagelet.
* @param pagelet the XSL pagelet.
* @param request the servlet request.
* @return the transformation source of the given XSL pagelet or null by default.
* @throws RequestListenerException if there was any error occurred when constructing the source.
*
* @see #processPagelet(TemplateElement, Pagelet, HttpServletRequest, HttpServletResponse)
*/
protected Source getPageletSource(TemplateElement element, Pagelet pagelet, HttpServletRequest request)
throws RequestListenerException {
return null;
}
/**
* Gets the transformation source for the XSL error pagelet.
*
* @param element the template element which represents the pagelet.
* @param error the error generated by the XSL pagelet process.
* @param request the servlet request.
* @return the transformation source of the XSL error pagelet or null by default.
* @throws RequestListenerException if there was any error occurred when constructing the source.
*
* @see #processError(TemplateElement, Throwable, HttpServletRequest, HttpServletResponse)
*/
protected Source getErrorSource(TemplateElement element, Throwable error, HttpServletRequest request)
throws RequestListenerException {
return null;
}
/**
* Transforms a given XML source using the specified XSL and writes the
* output to the response output stream.
*
* @param xsl the XSL for the transformation.
* @param source the XML source.
* @param request the servlet request.
* @param response the servlet response.
* @throws IOException if an I/O exception occurs during openning the XSL
* stream.
* @throws TransformerException if an unrecoverable error occurs during the
* course of the transformation.
*/
protected void transform(Pagelet xsl, Source source, HttpServletRequest request, HttpServletResponse response)
throws IOException, TransformerException {
if (xsl == null) {
return;
}
if (source == null) {
source = new DOMSource();
}
TransformerFactory factory = TransformerFactory.newInstance();
Transformer formatter;
if (isXMLMode(request)) {
formatter = factory.newTransformer();
}
else {
formatter = factory.newTransformer(new StreamSource(xsl.openStream()));
}
formatter.transform(source, new StreamResult(response.getWriter()));
}
/**
* Processes the text part of the generating page if the generation mode is
* not "xml".
*
* @see hk.hku.cecid.piazza.commons.pagelet.HttpPageletAdaptor#processText(hk.hku.cecid.piazza.commons.pagelet.TemplateElement, java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void processText(TemplateElement element, String text,
HttpServletRequest request, HttpServletResponse response)
throws RequestListenerException {
if (!isXMLMode(request)) {
super.processText(element, text, request, response);
}
}
/**
* Checks if the generation mode is "xml".
*
* @param request the servlet request.
* @return true if the generation mode is "xml"
*/
private boolean isXMLMode(HttpServletRequest request) {
return "xml".equalsIgnoreCase(request.getParameter(REQ_PARAM_PAGEMODE));
}
}