KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > lib > PipeDocument


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: PipeDocument.java,v 1.8 2004/02/11 17:56:36 minchau Exp $
18  */

19 package org.apache.xalan.lib;
20
21 import java.io.FileNotFoundException JavaDoc;
22 import java.io.FileOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.Vector JavaDoc;
26
27 import javax.xml.transform.Templates JavaDoc;
28 import javax.xml.transform.Transformer JavaDoc;
29 import javax.xml.transform.TransformerConfigurationException JavaDoc;
30 import javax.xml.transform.TransformerException JavaDoc;
31 import javax.xml.transform.TransformerFactory JavaDoc;
32 import javax.xml.transform.sax.SAXResult JavaDoc;
33 import javax.xml.transform.sax.SAXTransformerFactory JavaDoc;
34 import javax.xml.transform.sax.TransformerHandler JavaDoc;
35 import javax.xml.transform.stream.StreamSource JavaDoc;
36
37 import org.apache.xalan.extensions.XSLProcessorContext;
38 import org.apache.xalan.templates.AVT;
39 import org.apache.xalan.templates.ElemExtensionCall;
40 import org.apache.xalan.templates.ElemLiteralResult;
41 import org.apache.xalan.transformer.TransformerImpl;
42 import org.apache.xml.utils.SystemIDResolver;
43 import org.apache.xpath.XPathContext;
44
45 import org.w3c.dom.Element JavaDoc;
46 import org.w3c.dom.Node JavaDoc;
47 import org.w3c.dom.NodeList JavaDoc;
48
49 import org.xml.sax.SAXException JavaDoc;
50 import org.xml.sax.SAXNotRecognizedException JavaDoc;
51 import org.xml.sax.XMLReader JavaDoc;
52 import org.xml.sax.helpers.XMLReaderFactory JavaDoc;
53 /**
54  */

55 // Imported Serializer classes
56
import org.apache.xml.serializer.Serializer;
57 import org.apache.xml.serializer.SerializerFactory;
58
59 /**
60  * PipeDocument is a Xalan extension element to set stylesheet params and pipes an XML
61  * document through a series of 1 or more stylesheets.
62  * PipeDocument is invoked from a stylesheet as the {@link #pipeDocument pipeDocument extension element}.
63  *
64  * It is accessed by specifying a namespace URI as follows:
65  * <pre>
66  * xmlns:pipe="http://xml.apache.org/xalan/PipeDocument"
67  * </pre>
68  *
69  * @author Donald Leslie
70  */

71 public class PipeDocument
72 {
73 /**
74  * Extension element for piping an XML document through a series of 1 or more transformations.
75  *
76  * <pre>Common usage pattern: A stylesheet transforms a listing of documents to be
77  * transformed into a TOC. For each document in the listing calls the pipeDocument
78  * extension element to pipe that document through a series of 1 or more stylesheets
79  * to the desired output document.
80  *
81  * Syntax:
82  * &lt;xsl:stylesheet version="1.0"
83  * xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
84  * xmlns:pipe="http://xml.apache.org/xalan/PipeDocument"
85  * extension-element-prefixes="pipe"&gt;
86  * ...
87  * &lt;pipe:pipeDocument source="source.xml" target="target.xml"&gt;
88  * &lt;stylesheet HREF="ss1.xsl"&gt;
89  * &lt;param name="param1" value="value1"/&gt;
90  * &lt;/stylesheet&gt;
91  * &lt;stylesheet HREF="ss2.xsl"&gt;
92  * &lt;param name="param1" value="value1"/&gt;
93  * &lt;param name="param2" value="value2"/&gt;
94  * &lt;/stylesheet&gt;
95  * &lt;stylesheet HREF="ss1.xsl"/&gt;
96  * &lt;/pipe:pipeDocument&gt;
97  *
98  * Notes:</pre>
99  * <ul>
100  * <li>The base URI for the source attribute is the XML "listing" document.<li/>
101  * <li>The target attribute is taken as is (base is the current user directory).<li/>
102  * <li>The stylsheet containg the extension element is the base URI for the
103  * stylesheet hrefs.<li/>
104  * </ul>
105  */

106   public void pipeDocument(XSLProcessorContext context, ElemExtensionCall elem)
107       throws TransformerException JavaDoc, TransformerConfigurationException JavaDoc,
108          SAXException JavaDoc, IOException JavaDoc, FileNotFoundException JavaDoc
109   {
110     try
111     {
112       SAXTransformerFactory JavaDoc saxTFactory = (SAXTransformerFactory JavaDoc) TransformerFactory.newInstance();
113       
114       // XML doc to transform.
115
String JavaDoc source = elem.getAttribute("source",
116                                          context.getContextNode(),
117                                          context.getTransformer());
118       TransformerImpl transImpl = context.getTransformer();
119
120       //Base URI for input doc, so base for relative URI to XML doc to transform.
121
String JavaDoc baseURLOfSource = transImpl.getBaseURLOfSource();
122       // Absolute URI for XML doc to transform.
123
String JavaDoc absSourceURL = SystemIDResolver.getAbsoluteURI(source, baseURLOfSource);
124
125       // Transformation target
126
String JavaDoc target = elem.getAttribute("target",
127                                          context.getContextNode(),
128                                          context.getTransformer());
129       
130       XPathContext xctxt = context.getTransformer().getXPathContext();
131       int xt = xctxt.getDTMHandleFromNode(context.getContextNode());
132  
133       // Get System Id for stylesheet; to be used to resolve URIs to other stylesheets.
134
String JavaDoc sysId = elem.getSystemId();
135       
136       NodeList JavaDoc ssNodes = null;
137       NodeList JavaDoc paramNodes = null;
138       Node JavaDoc ssNode = null;
139       Node JavaDoc paramNode = null;
140       if (elem.hasChildNodes())
141       {
142         ssNodes = elem.getChildNodes();
143         // Vector to contain TransformerHandler for each stylesheet.
144
Vector JavaDoc vTHandler = new Vector JavaDoc(ssNodes.getLength());
145         
146         // The child nodes of an extension element node are instances of
147
// ElemLiteralResult, which requires does not fully support the standard
148
// Node interface. Accordingly, some special handling is required (see below)
149
// to get attribute values.
150
for (int i = 0; i < ssNodes.getLength(); i++)
151         {
152           ssNode = ssNodes.item(i);
153           if (ssNode.getNodeType() == Node.ELEMENT_NODE
154               && ((Element JavaDoc)ssNode).getTagName().equals("stylesheet")
155               && ssNode instanceof ElemLiteralResult)
156           {
157             AVT avt = ((ElemLiteralResult)ssNode).getLiteralResultAttribute("href");
158             String JavaDoc href = avt.evaluate(xctxt,xt, elem);
159             String JavaDoc absURI = SystemIDResolver.getAbsoluteURI(href, sysId);
160             Templates JavaDoc tmpl = saxTFactory.newTemplates(new StreamSource JavaDoc(absURI));
161             TransformerHandler JavaDoc tHandler = saxTFactory.newTransformerHandler(tmpl);
162             Transformer JavaDoc trans = tHandler.getTransformer();
163             
164             // AddTransformerHandler to vector
165
vTHandler.addElement(tHandler);
166
167             paramNodes = ssNode.getChildNodes();
168             for (int j = 0; j < paramNodes.getLength(); j++)
169             {
170               paramNode = paramNodes.item(j);
171               if (paramNode.getNodeType() == Node.ELEMENT_NODE
172                   && ((Element JavaDoc)paramNode).getTagName().equals("param")
173                   && paramNode instanceof ElemLiteralResult)
174               {
175                  avt = ((ElemLiteralResult)paramNode).getLiteralResultAttribute("name");
176                  String JavaDoc pName = avt.evaluate(xctxt,xt, elem);
177                  avt = ((ElemLiteralResult)paramNode).getLiteralResultAttribute("value");
178                  String JavaDoc pValue = avt.evaluate(xctxt,xt, elem);
179                  trans.setParameter(pName, pValue);
180                }
181              }
182            }
183          }
184          usePipe(vTHandler, absSourceURL, target);
185        }
186      }
187      catch (Exception JavaDoc e)
188      {
189        e.printStackTrace();
190      }
191   }
192   /**
193    * Uses a Vector of TransformerHandlers to pipe XML input document through
194    * a series of 1 or more transformations. Called by {@link #pipeDocument}.
195    *
196    * @param vTHandler Vector of Transformation Handlers (1 per stylesheet).
197    * @param source absolute URI to XML input
198    * @param target absolute path to transformation output.
199    */

200   public void usePipe(Vector JavaDoc vTHandler, String JavaDoc source, String JavaDoc target)
201           throws TransformerException JavaDoc, TransformerConfigurationException JavaDoc,
202                  FileNotFoundException JavaDoc, IOException JavaDoc, SAXException JavaDoc, SAXNotRecognizedException JavaDoc
203   {
204     XMLReader JavaDoc reader = XMLReaderFactory.createXMLReader();
205     TransformerHandler JavaDoc tHFirst = (TransformerHandler JavaDoc)vTHandler.firstElement();
206     reader.setContentHandler(tHFirst);
207     reader.setProperty("http://xml.org/sax/properties/lexical-handler", tHFirst);
208     for (int i = 1; i < vTHandler.size(); i++)
209     {
210       TransformerHandler JavaDoc tHFrom = (TransformerHandler JavaDoc)vTHandler.elementAt(i-1);
211       TransformerHandler JavaDoc tHTo = (TransformerHandler JavaDoc)vTHandler.elementAt(i);
212       tHFrom.setResult(new SAXResult JavaDoc(tHTo));
213     }
214     TransformerHandler JavaDoc tHLast = (TransformerHandler JavaDoc)vTHandler.lastElement();
215     Transformer JavaDoc trans = tHLast.getTransformer();
216     Properties JavaDoc outputProps = trans.getOutputProperties();
217     Serializer serializer = SerializerFactory.getSerializer(outputProps);
218     
219     FileOutputStream JavaDoc out = new FileOutputStream JavaDoc(target);
220     try
221     {
222       serializer.setOutputStream(out);
223       tHLast.setResult(new SAXResult JavaDoc(serializer.asContentHandler()));
224       reader.parse(source);
225     }
226     finally
227     {
228       // Always clean up the FileOutputStream,
229
// even if an exception was thrown in the try block
230
if (out != null)
231         out.close();
232     }
233   }
234 }
235
Popular Tags