001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/framework/xml/XSLTDocument.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.framework.xml; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.io.OutputStream; 041 import java.io.Reader; 042 import java.net.MalformedURLException; 043 import java.net.URL; 044 import java.util.Iterator; 045 import java.util.Map; 046 import java.util.Properties; 047 048 import javax.xml.transform.Result; 049 import javax.xml.transform.Source; 050 import javax.xml.transform.Transformer; 051 import javax.xml.transform.TransformerException; 052 import javax.xml.transform.TransformerFactory; 053 import javax.xml.transform.dom.DOMResult; 054 import javax.xml.transform.dom.DOMSource; 055 import javax.xml.transform.stream.StreamResult; 056 import javax.xml.transform.stream.StreamSource; 057 058 import org.deegree.framework.log.ILogger; 059 import org.deegree.framework.log.LoggerFactory; 060 import org.deegree.framework.util.BootLogger; 061 import org.w3c.dom.Document; 062 import org.xml.sax.SAXException; 063 064 /** 065 * Encapsulates the DOM representation of an XSLT stylesheet. 066 * 067 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a> 068 * 069 * @author last edited by: $Author: mschneider $ 070 * 071 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 072 * 073 */ 074 public class XSLTDocument extends XMLFragment { 075 076 private static final long serialVersionUID = -2079718341146916400L; 077 078 private static final ILogger LOG = LoggerFactory.getLogger( XSLTDocument.class ); 079 080 private static final TransformerFactory factory = TransformerFactory.newInstance(); 081 082 static { 083 LOG.logDebug( "XSLT implementation in use (TransformerFactory): " + factory.getClass().getName() ); 084 try { 085 LOG.logDebug( "XSLT implementation in use (Transformer): " + factory.newTransformer().getClass().getName() ); 086 } catch ( Exception e ) { 087 BootLogger.logError( "Error creating test Transformer instance.", e ); 088 } 089 } 090 091 /** 092 * An empty xslt document. 093 */ 094 public XSLTDocument() { 095 super(); 096 } 097 098 /** 099 * 100 * @param url 101 * @throws IOException 102 * @throws SAXException 103 */ 104 public XSLTDocument( URL url ) throws IOException, SAXException { 105 super( url ); 106 } 107 108 /** 109 * Transforms the given <code>XMLFragment</code> instance. 110 * 111 * @param xmlDocument 112 * can not be null 113 * @param systemId 114 * SystemID for the resulting <code>XMLFragment</code>, may be null 115 * @param outputProperties 116 * transformation properties, may be null 117 * @param params 118 * transformation parameters, may be null 119 * @return the transformed xml file. 120 * @throws TransformerException 121 * @throws MalformedURLException 122 * if systemId is no valid <code>URL</code> 123 */ 124 public synchronized XMLFragment transform( XMLFragment xmlDocument, String systemId, Properties outputProperties, 125 Map<String, ?> params ) 126 throws TransformerException, MalformedURLException { 127 128 XMLFragment resultFragment = null; 129 DOMSource xmlSource = new DOMSource( xmlDocument.getRootElement() ); 130 DOMSource xslSource = new DOMSource( this.getRootElement().getOwnerDocument(), 131 this.getSystemId() == null ? null : this.getSystemId().toString() ); 132 Result result = transform( xmlSource, xslSource, new DOMResult(), outputProperties, params ); 133 Document resultDocument = (Document) ( (DOMResult) result ).getNode(); 134 resultFragment = new XMLFragment( resultDocument, systemId ); 135 136 return resultFragment; 137 } 138 139 /** 140 * Transforms the given <code>XMLFragment</code> instance. 141 * 142 * @param xmlDocument 143 * can not be null 144 * @return the transformed xml file. 145 * @throws TransformerException 146 */ 147 public synchronized XMLFragment transform( XMLFragment xmlDocument ) 148 throws TransformerException { 149 150 XMLFragment resultFragment; 151 try { 152 resultFragment = transform( xmlDocument, null, null, null ); 153 } catch ( MalformedURLException e ) { 154 LOG.logError( "Internal Error. This should not happen." ); 155 throw new TransformerException( "Internal Error. This should not happen.", e ); 156 } 157 158 return resultFragment; 159 } 160 161 /** 162 * Transforms the given <code>XMLFragment</code> instance. 163 * 164 * @param xmlDocument 165 * can not be null 166 * @param target 167 * output stream where the result of the transformation will be written to 168 * @throws TransformerException 169 */ 170 public synchronized void transform( XMLFragment xmlDocument, OutputStream target ) 171 throws TransformerException { 172 173 DOMSource xmlSource = new DOMSource( xmlDocument.getRootElement() ); 174 DOMSource xslSource = new DOMSource( this.getRootElement().getOwnerDocument(), 175 this.getSystemId() == null ? null : this.getSystemId().toString() ); 176 StreamResult sr = new StreamResult( target ); 177 transform( xmlSource, xslSource, sr, null, null ); 178 179 } 180 181 /** 182 * Transforms an input XML stream to an output stream using this <code>XSLTDocument</code>. 183 * 184 * @param input 185 * provides the input xml as a stream 186 * @param target 187 * output stream where the result of the transformation will be written to 188 * @throws TransformerException 189 */ 190 public synchronized void transform( InputStream input, OutputStream target ) 191 throws TransformerException { 192 193 Source xmlSource = new StreamSource( input ); 194 DOMSource xslSource = new DOMSource( this.getRootElement().getOwnerDocument(), 195 this.getSystemId() == null ? null : this.getSystemId().toString() ); 196 StreamResult sr = new StreamResult( target ); 197 transform( xmlSource, xslSource, sr, null, null ); 198 199 } 200 201 /** 202 * Transforms the XML from the given <code>InputStream</code>. 203 * <p> 204 * NOTE: You have to make sure that the <code>InputStream</code> provides a valid XML document. 205 * 206 * @param instream 207 * @param systemId 208 * SystemID for the resulting <code>XMLFragment</code> 209 * @param outputProperties 210 * transformation properties, may be null 211 * @param params 212 * transformation parameters, may be null 213 * @return the transformed xml file. 214 * @throws TransformerException 215 * if transformation fails 216 * @throws MalformedURLException 217 * if given systemId is no valid <code>URL</code> 218 */ 219 public synchronized XMLFragment transform( InputStream instream, String systemId, Properties outputProperties, 220 Map<String, ?> params ) 221 throws TransformerException, MalformedURLException { 222 223 DOMSource xslSource = new DOMSource( getRootElement().getOwnerDocument(), 224 this.getSystemId() == null ? null : this.getSystemId().toString() ); 225 Result result = transform( new StreamSource( instream ), xslSource, new DOMResult(), outputProperties, params ); 226 Document resultDocument = (Document) ( (DOMResult) result ).getNode(); 227 228 return new XMLFragment( resultDocument, systemId ); 229 } 230 231 /** 232 * Transforms the XML from the given <code>Reader</code>. 233 * <p> 234 * NOTE: You have to make sure that the <code>Reader</code> provides a valid XML document. 235 * 236 * @param reader 237 * @param systemId 238 * SystemID for the resulting <code>XMLFragment</code> 239 * @param outputProperties 240 * transformation properties, may be null 241 * @param params 242 * transformation parameters, may be null 243 * @return the transformed xml file. 244 * @throws TransformerException 245 * if transformation fails 246 * @throws MalformedURLException 247 * if given systemId is no valid <code>URL</code> 248 */ 249 public synchronized XMLFragment transform( Reader reader, String systemId, Properties outputProperties, 250 Map<String, ?> params ) 251 throws TransformerException, MalformedURLException { 252 253 DOMSource xslSource = new DOMSource( getRootElement().getOwnerDocument(), 254 this.getSystemId() == null ? null : this.getSystemId().toString() ); 255 Result result = transform( new StreamSource( reader ), xslSource, new DOMResult(), outputProperties, params ); 256 Document resultDocument = (Document) ( (DOMResult) result ).getNode(); 257 258 return new XMLFragment( resultDocument, systemId ); 259 } 260 261 /** 262 * Transforms the given XML <code>Source</code> instance using the also submitted XSLT stylesheet 263 * <code>Source</code>. 264 * 265 * @param xmlSource 266 * @param xslSource 267 * @param result 268 * @param outputProperties 269 * may be null 270 * @param params 271 * may be null 272 * @return the transformed xml file. 273 * @throws TransformerException 274 * @throws TransformerException 275 */ 276 public static Result transform( Source xmlSource, Source xslSource, Result result, Properties outputProperties, 277 Map<String, ?> params ) 278 throws TransformerException { 279 280 try { 281 Transformer transformer = factory.newTransformer( xslSource ); 282 283 if ( params != null ) { 284 Iterator<String> it = params.keySet().iterator(); 285 while ( it.hasNext() ) { 286 String key = it.next(); 287 transformer.setParameter( key, params.get( key ) ); 288 } 289 } 290 if ( outputProperties != null ) { 291 transformer.setOutputProperties( outputProperties ); 292 } 293 294 transformer.transform( xmlSource, result ); 295 } catch ( TransformerException e ) { 296 String transformerClassName = null; 297 String transformerFactoryClassName = factory.getClass().getName(); 298 try { 299 transformerClassName = factory.newTransformer().getClass().getName(); 300 } catch ( Exception e2 ) { 301 LOG.logError( "Error creating Transformer instance." ); 302 } 303 String errorMsg = "XSL transformation using stylesheet with systemId '" + xslSource.getSystemId() 304 + "' and xml source with systemId '" + xmlSource.getSystemId() 305 + "' failed. TransformerFactory class: " + transformerFactoryClassName 306 + "', Transformer class: " + transformerClassName; 307 LOG.logError( errorMsg, e ); 308 throw new TransformerException( errorMsg, e ); 309 } 310 311 return result; 312 } 313 }