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