/* Copyright (c) 2003 eInnovation Inc. All rights reserved This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ /* * (c) Copyright 2001 MyCorporation. * All Rights Reserved. */ package org.openedit.entermedia.generators; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; 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; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.openedit.Generator; import com.openedit.OpenEditException; import com.openedit.WebPageRequest; import com.openedit.generators.BaseGenerator; import com.openedit.generators.Output; import com.openedit.page.Page; import com.openedit.page.manage.PageManager; import com.openedit.util.PathUtilities; /** * This generator transforms XML input through an XSLT stylesheet. * * @author Eric Galluzzo * @author Matt Avery, mavery@einnovation.com */ public class XsltGenerator extends BaseGenerator implements Generator { private static Log log = LogFactory.getLog(XsltGenerator.class); protected PageManager fieldPageManager; protected ThreadLocal fieldTransformers; /** * Run the given page through the stylesheet specified in its config file and output the result * to the given output stream. This generator accepts a configuration which looks like this: * <pre> * <generator name="xslt"> * <stylesheet>/path/to/my/stylesheet.xsl</stylesheet> * [<use-request-parameters>true</use-request-parameters>] * [<generator>...</generator>] * </generator> * </pre> * * @see Generator#generate(Page, WebPageContext) */ public void generate( WebPageRequest inContext, Page inPage, Output inOut ) throws OpenEditException { // Put all the request parameters as parameters to the stylesheet, if // the user so desired. In addition, pass "requestURI" and // "queryString" parameters, which have the obvious values. try { String template = inContext.findValue("xsltlayout"); Transformer transformer = getTransformer(template); if ( Boolean.parseBoolean(inContext.findValue("xsltaddrequestparameters") ) ) { populateParameters( inContext, transformer ); } StreamResult result = new StreamResult(inOut.getWriter()); String home = (String) inContext.getPageValue("home"); transformer.setParameter("home", home); if( !inPage.exists()) { inPage = getPageManager().getPage(PathUtilities.extractPagePath(inPage.getPath()) + ".xml"); } StreamSource xmlSource = new StreamSource(inPage.getReader()); transformer.transform(xmlSource, result); transformer.clearParameters(); inOut.getWriter().flush(); } catch (Exception ex) { throw new OpenEditException(ex); } } protected ThreadLocal getTransformers() { if( fieldTransformers == null) { fieldTransformers = new ThreadLocal(); } return fieldTransformers; } protected Transformer getTransformer(String inXslt) throws Exception { Page style = getPageManager().getPage( inXslt ); long mod = style.getContentItem().getLastModified(); Map map = (Map)getTransformers().get(); if( map == null) { map = new HashMap(); getTransformers().set(map); } TransformerModDate trans = (TransformerModDate)map.get(style.getContentItem().getActualPath()); if ( trans == null || trans.modDate != mod) { Source source = new StreamSource(style.getReader()); trans = new TransformerModDate(); trans.modDate = mod; Transformer transform = TransformerFactory.newInstance().newTransformer(source); trans.transformer = transform; map.put(style.getContentItem().getActualPath(), trans); } return trans.transformer; } /** * @param inContext */ protected void populateParameters( WebPageRequest inContext, Transformer inTrans ) throws Exception { HttpServletRequest request = inContext.getRequest(); inTrans.setParameter("requestURI", request.getRequestURI()); inTrans.setParameter("queryString", request.getQueryString()); for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); inTrans.setParameter(name, request.getParameter(name)); } } public PageManager getPageManager() { return fieldPageManager; } public void setPageManager( PageManager pageManager ) { fieldPageManager = pageManager; } class TransformerModDate { protected long modDate; protected Transformer transformer; } }