001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.portals.applications.transform.impl;
018:
019: import java.io.IOException;
020: import java.io.InputStreamReader;
021: import java.io.OutputStream;
022: import java.io.Writer;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.Map;
026:
027: import javax.xml.parsers.DocumentBuilder;
028: import javax.xml.parsers.DocumentBuilderFactory;
029: import javax.xml.parsers.ParserConfigurationException;
030: import javax.xml.parsers.SAXParserFactory;
031: import javax.xml.transform.Templates;
032: import javax.xml.transform.Transformer;
033: import javax.xml.transform.TransformerFactory;
034: import javax.xml.transform.dom.DOMSource;
035: import javax.xml.transform.sax.SAXTransformerFactory;
036: import javax.xml.transform.sax.TemplatesHandler;
037: import javax.xml.transform.sax.TransformerHandler;
038: import javax.xml.transform.stream.StreamResult;
039:
040: import org.apache.portals.applications.transform.Transform;
041: import org.apache.portals.applications.transform.TransformException;
042: import org.apache.portals.applications.transform.TransformObjectPublisher;
043: import org.apache.portals.applications.util.Streams;
044: import org.w3c.dom.Document;
045: import org.xml.sax.InputSource;
046: import org.xml.sax.XMLReader;
047: import org.xml.sax.helpers.XMLReaderFactory;
048:
049: /**
050: * TransformComponent
051: *
052: * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
053: * @version $Id: JetspeedTransform.java 516448 2007-03-09 16:25:47Z ate $
054: */
055: public class JetspeedTransform implements Transform {
056: public JetspeedTransform() {
057: // TODO: make all JAX factories configurable
058: synchronized (mutex) {
059: if (transformerFactory == null) {
060: System.setProperty(JAX_TRANSFORM_PROPERTY,
061: jaxTransformFactoryProp);
062: System.setProperty(JAX_SAX_PARSER_PROPERTY,
063: jaxSaxFactoryProp);
064: System.setProperty(JAX_DOM_PARSER_PROPERTY,
065: jaxDomFactoryProp);
066: System.setProperty(SAX_XML_READER_PROPERTY,
067: saxXmlReaderProp);
068:
069: TransformerFactory tFactory = TransformerFactory
070: .newInstance();
071: domFactory = DocumentBuilderFactory.newInstance();
072: domFactory.setValidating(false);
073: saxFactory = SAXParserFactory.newInstance();
074: saxFactory.setValidating(false);
075: //if (!tFactory.getFeature(SAXTransformerFactory.FEATURE)) { throw new TransformException(
076: // "Invalid SAX Tranformer. Doesn't support SAX"); }
077: transformerFactory = ((SAXTransformerFactory) tFactory);
078: }
079: }
080:
081: publisher = new TransformObjectPublisher();
082: }
083:
084: private static DocumentBuilderFactory domFactory = null;
085:
086: private static SAXParserFactory saxFactory = null;
087:
088: private static SAXTransformerFactory transformerFactory = null;
089:
090: //
091: // JAXP Service Configuration
092: //
093: private final static String CONFIG_JAX_FACTORY_SAX = "jax.factory.sax";
094:
095: private final static String jaxSaxFactoryProp = "org.apache.xerces.jaxp.SAXParserFactoryImpl";
096:
097: private final static String CONFIG_JAX_FACTORY_DOM = "jax.factory.dom";
098:
099: private final static String jaxDomFactoryProp = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
100:
101: private final static String CONFIG_JAX_FACTORY_TRANSFORM = "jax.factory.transform";
102:
103: private final static String jaxTransformFactoryProp = "org.apache.xalan.processor.TransformerFactoryImpl";
104:
105: private final static Object mutex = new Object();
106:
107: //
108: // JAXP System Wide Properties
109: //
110: private static final String JAX_TRANSFORM_PROPERTY = "javax.xml.transform.TransformerFactory";
111:
112: private static final String JAX_SAX_PARSER_PROPERTY = "javax.xml.parsers.SAXParserFactory";
113:
114: private static final String JAX_DOM_PARSER_PROPERTY = "javax.xml.parsers.DocumentBuilderFactory";
115:
116: //
117: // Standard Parser Vendor Property
118: //
119: private static final String SAX_XML_READER_PROPERTY = "org.xml.sax.driver";
120:
121: //
122: // Standard Parser Vendor Configuration
123: //
124: private final static String saxXmlReaderProp = "org.apache.xerces.parsers.SAXParser";
125:
126: // DTD Map
127: static private Map dtds = new HashMap();
128:
129: private TransformObjectPublisher publisher = null;
130:
131: public void transform(String xslt, InputSource inputSource,
132: OutputStream os, Map parameters) throws TransformException {
133: if (xslt == null) {
134: try { // if no stylesheet specified simply drain the stream
135: Streams.drain(inputSource.getByteStream(), os);
136: } catch (IOException e) {
137: throw new TransformException(e);
138: }
139: } else {
140: transformStream(xslt, inputSource, new StreamResult(os),
141: parameters);
142: }
143: }
144:
145: public void transform(String xslt, InputSource inputSource,
146: Writer writer, Map parameters) throws TransformException {
147: if (xslt == null) {
148: try { // if no stylesheet specified simply drain the stream
149: Streams.drain(inputSource.getCharacterStream(), writer);
150: } catch (IOException e) {
151: throw new TransformException(e);
152: }
153: } else {
154: transformStream(xslt, inputSource,
155: new StreamResult(writer), parameters);
156: }
157: }
158:
159: private static void transformStream(String xslt,
160: InputSource inputSource, StreamResult streamResult,
161: Map parameters) throws TransformException {
162: if (xslt == null) {
163: throw new TransformException(
164: "Invalid Transform, no stylesheet set!");
165: }
166:
167: //
168: // create a new document builder to load the XML file for transformation
169: //
170: DocumentBuilder docBuilder = null;
171: try {
172: docBuilder = domFactory.newDocumentBuilder();
173: docBuilder
174: .setEntityResolver(new TransformDTDEntityResolver(
175: dtds));
176:
177: } catch (ParserConfigurationException e) {
178: throw new TransformException(
179: "Failed to load JAX Document Builder: "
180: + e.toString());
181: }
182:
183: try {
184: // Create a ContentHandler to handle parsing of the stylesheet.
185: TemplatesHandler templatesHandler = transformerFactory
186: .newTemplatesHandler();
187:
188: // Create an XMLReader and set its ContentHandler.
189: XMLReader reader = XMLReaderFactory.createXMLReader();
190: reader.setContentHandler(templatesHandler);
191:
192: // Set it to solve Entities via cache
193: reader.setEntityResolver(new TransformDTDEntityResolver(
194: dtds));
195:
196: //
197: // Get the stylesheet's content from the deployment
198: //
199: java.io.FileInputStream is = new java.io.FileInputStream(
200: xslt);
201: InputStreamReader ssreader = new InputStreamReader(is);
202:
203: // Parse the stylesheet.
204: final InputSource xstyle = new InputSource(ssreader);
205: xstyle.setSystemId(xslt);
206: reader.parse(xstyle);
207:
208: //Get the Templates object from the ContentHandler.
209: Templates templates = templatesHandler.getTemplates();
210:
211: // Create a ContentHandler to handle parsing of the XML source.
212: TransformerHandler handler = transformerFactory
213: .newTransformerHandler(templates);
214:
215: // Reset the XMLReader's ContentHandler.
216: reader.setContentHandler(handler);
217:
218: //
219: // Parse the Document into a DOM tree
220: //
221: //
222: org.w3c.dom.Document doc = docBuilder.parse(inputSource);
223:
224: // reader.setProperty("http://xml.org/sax/properties/lexical-handler",
225: // handler);
226:
227: final Transformer processor = handler.getTransformer();
228:
229: //
230: // Get the transform variables (parameters)
231: //
232: Iterator keys = parameters.keySet().iterator();
233: while (keys.hasNext()) {
234: String name = (String) keys.next();
235: String value = (String) parameters.get(name);
236: processor.setParameter(name, value);
237: }
238:
239: //
240: // do the transformation now
241: //
242: processor.transform(new DOMSource(doc), streamResult);
243:
244: } catch (Exception e) {
245: throw new TransformException("Error in Transformation: "
246: + e.toString());
247: }
248: }
249:
250: private static void transformStream(String xslt, Document document,
251: StreamResult streamResult, Map parameters)
252: throws TransformException {
253: if (xslt == null) {
254: throw new TransformException(
255: "Invalid Transform, no stylesheet set!");
256: }
257:
258: synchronized (mutex) {
259: if (transformerFactory == null) {
260: System.setProperty(JAX_TRANSFORM_PROPERTY,
261: jaxTransformFactoryProp);
262: System.setProperty(JAX_SAX_PARSER_PROPERTY,
263: jaxSaxFactoryProp);
264: System.setProperty(JAX_DOM_PARSER_PROPERTY,
265: jaxDomFactoryProp);
266: System.setProperty(SAX_XML_READER_PROPERTY,
267: saxXmlReaderProp);
268:
269: TransformerFactory tFactory = TransformerFactory
270: .newInstance();
271: domFactory = DocumentBuilderFactory.newInstance();
272: domFactory.setValidating(false);
273: saxFactory = SAXParserFactory.newInstance();
274: saxFactory.setValidating(false);
275: if (!tFactory.getFeature(SAXTransformerFactory.FEATURE)) {
276: throw new TransformException(
277: "Invalid SAX Tranformer. Doesn't support SAX");
278: }
279: transformerFactory = ((SAXTransformerFactory) tFactory);
280: }
281: }
282:
283: //
284: // create a new document builder to load the XML file for transformation
285: //
286: DocumentBuilder docBuilder = null;
287: try {
288: docBuilder = domFactory.newDocumentBuilder();
289: docBuilder
290: .setEntityResolver(new TransformDTDEntityResolver(
291: dtds));
292:
293: } catch (ParserConfigurationException e) {
294: throw new TransformException(
295: "Failed to load JAX Document Builder: "
296: + e.toString());
297: }
298:
299: try {
300: // Create a ContentHandler to handle parsing of the stylesheet.
301: TemplatesHandler templatesHandler = transformerFactory
302: .newTemplatesHandler();
303:
304: // Create an XMLReader and set its ContentHandler.
305: XMLReader reader = XMLReaderFactory.createXMLReader();
306: reader.setContentHandler(templatesHandler);
307:
308: // Set it to solve Entities via cache
309: reader.setEntityResolver(new TransformDTDEntityResolver(
310: dtds));
311:
312: //
313: // Get the stylesheet's content from the deployment
314: //
315: java.io.FileInputStream is = new java.io.FileInputStream(
316: xslt);
317: InputStreamReader ssreader = new InputStreamReader(is);
318:
319: // Parse the stylesheet.
320: final InputSource xstyle = new InputSource(ssreader);
321: xstyle.setSystemId(xslt);
322: reader.parse(xstyle);
323:
324: //Get the Templates object from the ContentHandler.
325: Templates templates = templatesHandler.getTemplates();
326:
327: // Create a ContentHandler to handle parsing of the XML source.
328: TransformerHandler handler = transformerFactory
329: .newTransformerHandler(templates);
330:
331: // Reset the XMLReader's ContentHandler.
332: reader.setContentHandler(handler);
333:
334: //
335: // Parse the Document into a DOM tree
336: //
337: //
338: // org.w3c.dom.Document doc = docBuilder.parse(inputSource);
339:
340: // reader.setProperty("http://xml.org/sax/properties/lexical-handler",
341: // handler);
342:
343: final Transformer processor = handler.getTransformer();
344:
345: //
346: // Get the transform variables (parameters)
347: //
348: Iterator keys = parameters.keySet().iterator();
349: while (keys.hasNext()) {
350: String name = (String) keys.next();
351: String value = (String) parameters.get(name);
352: processor.setParameter(name, value);
353: }
354:
355: //
356: // do the transformation now
357: //
358: processor.transform(new DOMSource(document), streamResult);
359:
360: } catch (Exception e) {
361: throw new TransformException("Error in Transformation: "
362: + e.toString());
363: }
364:
365: }
366:
367: public void transform(String xslt, Document document,
368: OutputStream os, Map parameters) throws TransformException {
369: if (xslt == null) {
370: throw new TransformException("xslt is null");
371: } else {
372: transformStream(xslt, document, new StreamResult(os),
373: parameters);
374: }
375: }
376:
377: /* (non-Javadoc)
378: * @see org.apache.jetspeed.syndication.services.transform.TransformService#getPublisher()
379: */
380: public TransformObjectPublisher getPublisher() {
381: return publisher;
382: }
383:
384: }
|