001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/framework/xml/XSLTDocument.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2006 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: 6711 $, $Date: 2007-04-27 16:13:10 +0200 (Fr, 27 Apr 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 );
292 throw new TransformerException( errorMsg, e );
293 }
294
295 return result;
296 }
297 }