KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > extensions > XSLProcessorContext


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: XSLProcessorContext.java,v 1.18 2004/02/11 05:26:23 minchau Exp $
18  */

19 package org.apache.xalan.extensions;
20
21 import javax.xml.transform.TransformerException JavaDoc;
22
23 import org.apache.xalan.templates.Stylesheet;
24 import org.apache.xalan.transformer.ClonerToResultTree;
25 import org.apache.xalan.transformer.TransformerImpl;
26 import org.apache.xml.dtm.DTM;
27 import org.apache.xml.dtm.DTMAxisIterator;
28 import org.apache.xml.dtm.DTMIterator;
29 import org.apache.xalan.serialize.SerializerUtils;
30 import org.apache.xml.serializer.SerializationHandler;
31 import org.apache.xml.utils.QName;
32 import org.apache.xpath.XPathContext;
33 import org.apache.xpath.axes.DescendantIterator;
34 import org.apache.xpath.axes.OneStepIterator;
35 import org.apache.xpath.objects.XBoolean;
36 import org.apache.xpath.objects.XNodeSet;
37 import org.apache.xpath.objects.XNumber;
38 import org.apache.xpath.objects.XObject;
39 import org.apache.xpath.objects.XRTreeFrag;
40 import org.apache.xpath.objects.XString;
41 import org.w3c.dom.DocumentFragment JavaDoc;
42 import org.w3c.dom.traversal.NodeIterator;
43
44 // import org.apache.xalan.xslt.*;
45

46 /**
47  * Provides transformer context to be passed to an extension element.
48  *
49  * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
50  * @xsl.usage general
51  */

52 public class XSLProcessorContext
53 {
54
55   /**
56    * Create a processor context to be passed to an extension.
57    * (Notice it is a package-only constructor).
58    *
59    * @param transformer non-null transformer instance
60    * @param stylesheetTree The owning stylesheet
61    * @param sourceTree The source document
62    * @param sourceNode The current source node
63    * @param mode the current mode being executed.
64    */

65   public XSLProcessorContext(TransformerImpl transformer,
66                              Stylesheet stylesheetTree)
67   {
68
69     this.transformer = transformer;
70     this.stylesheetTree = stylesheetTree;
71     // %TBD%
72
org.apache.xpath.XPathContext xctxt = transformer.getXPathContext();
73     this.mode = transformer.getMode();
74     this.sourceNode = xctxt.getCurrentNode();
75     this.sourceTree = xctxt.getDTM(this.sourceNode);
76   }
77
78   /** An instance of a transformer */
79   private TransformerImpl transformer;
80
81   /**
82    * Get the transformer.
83    *
84    * @return the transformer instance for this context
85    */

86   public TransformerImpl getTransformer()
87   {
88     return transformer;
89   }
90
91   /** The owning stylesheet for this context */
92   private Stylesheet stylesheetTree;
93
94   /**
95    * Get the Stylesheet being executed.
96    *
97    * @return the Stylesheet being executed.
98    */

99   public Stylesheet getStylesheet()
100   {
101     return stylesheetTree;
102   }
103
104   /** The root of the source tree being executed. */
105   private org.apache.xml.dtm.DTM sourceTree;
106
107   /**
108    * Get the root of the source tree being executed.
109    *
110    * @return the root of the source tree being executed.
111    */

112   public org.w3c.dom.Node JavaDoc getSourceTree()
113   {
114     return sourceTree.getNode(sourceTree.getDocumentRoot(sourceNode));
115   }
116
117   /** the current context node. */
118   private int sourceNode;
119
120   /**
121    * Get the current context node.
122    *
123    * @return the current context node.
124    */

125   public org.w3c.dom.Node JavaDoc getContextNode()
126   {
127     return sourceTree.getNode(sourceNode);
128   }
129
130   /** the current mode being executed. */
131   private QName mode;
132
133   /**
134    * Get the current mode being executed.
135    *
136    * @return the current mode being executed.
137    */

138   public QName getMode()
139   {
140     return mode;
141   }
142
143   /**
144    * Output an object to the result tree by doing the right conversions.
145    * This is public for access by extensions.
146    *
147    *
148    * @param stylesheetTree The owning stylesheet
149    * @param obj the Java object to output. If its of an X<something> type
150    * then that conversion is done first and then sent out.
151    *
152    * @throws TransformerException
153    * @throws java.io.FileNotFoundException
154    * @throws java.io.IOException
155    * @throws java.net.MalformedURLException
156    */

157   public void outputToResultTree(Stylesheet stylesheetTree, Object JavaDoc obj)
158           throws TransformerException JavaDoc, java.net.MalformedURLException JavaDoc,
159                  java.io.FileNotFoundException JavaDoc, java.io.IOException JavaDoc
160   {
161
162     try
163     {
164       SerializationHandler rtreeHandler = transformer.getResultTreeHandler();
165       XPathContext xctxt = transformer.getXPathContext();
166       XObject value;
167
168       // Make the return object into an XObject because it
169
// will be easier below. One of the reasons to do this
170
// is to keep all the conversion functionality in the
171
// XObject classes.
172
if (obj instanceof XObject)
173       {
174         value = (XObject) obj;
175       }
176       else if (obj instanceof String JavaDoc)
177       {
178         value = new XString((String JavaDoc) obj);
179       }
180       else if (obj instanceof Boolean JavaDoc)
181       {
182         value = new XBoolean(((Boolean JavaDoc) obj).booleanValue());
183       }
184       else if (obj instanceof Double JavaDoc)
185       {
186         value = new XNumber(((Double JavaDoc) obj).doubleValue());
187       }
188       else if (obj instanceof DocumentFragment JavaDoc)
189       {
190         int handle = xctxt.getDTMHandleFromNode((DocumentFragment JavaDoc)obj);
191         
192         value = new XRTreeFrag(handle, xctxt);
193       }
194       else if (obj instanceof DTM)
195       {
196         DTM dtm = (DTM)obj;
197         DTMIterator iterator = new DescendantIterator();
198         // %%ISSUE%% getDocument may not be valid for DTMs shared by multiple
199
// document trees, eg RTFs. But in that case, we shouldn't be trying
200
// to iterate over the whole DTM; we should be iterating over
201
// dtm.getDocumentRoot(rootNodeHandle), and folks should have told us
202
// this by passing a more appropriate type.
203
iterator.setRoot(dtm.getDocument(), xctxt);
204         value = new XNodeSet(iterator);
205       }
206       else if (obj instanceof DTMAxisIterator)
207       {
208         DTMAxisIterator iter = (DTMAxisIterator)obj;
209         DTMIterator iterator = new OneStepIterator(iter, -1);
210         value = new XNodeSet(iterator);
211       }
212       else if (obj instanceof DTMIterator)
213       {
214         value = new XNodeSet((DTMIterator) obj);
215       }
216       else if (obj instanceof NodeIterator)
217       {
218         value = new XNodeSet(new org.apache.xpath.NodeSetDTM(((NodeIterator)obj), xctxt));
219       }
220       else if (obj instanceof org.w3c.dom.Node JavaDoc)
221       {
222         value =
223           new XNodeSet(xctxt.getDTMHandleFromNode((org.w3c.dom.Node JavaDoc) obj),
224                        xctxt.getDTMManager());
225       }
226       else
227       {
228         value = new XString(obj.toString());
229       }
230
231       int type = value.getType();
232       String JavaDoc s;
233
234       switch (type)
235       {
236       case XObject.CLASS_BOOLEAN :
237       case XObject.CLASS_NUMBER :
238       case XObject.CLASS_STRING :
239         s = value.str();
240
241         rtreeHandler.characters(s.toCharArray(), 0, s.length());
242         break;
243
244       case XObject.CLASS_NODESET : // System.out.println(value);
245
DTMIterator nl = value.iter();
246         
247         int pos;
248
249         while (DTM.NULL != (pos = nl.nextNode()))
250         {
251           DTM dtm = nl.getDTM(pos);
252           int top = pos;
253
254           while (DTM.NULL != pos)
255           {
256             rtreeHandler.flushPending();
257             ClonerToResultTree.cloneToResultTree(pos, dtm.getNodeType(pos),
258                                                    dtm, rtreeHandler, true);
259
260             int nextNode = dtm.getFirstChild(pos);
261
262             while (DTM.NULL == nextNode)
263             {
264               if (DTM.ELEMENT_NODE == dtm.getNodeType(pos))
265               {
266                 rtreeHandler.endElement("", "", dtm.getNodeName(pos));
267               }
268
269               if (top == pos)
270                 break;
271
272               nextNode = dtm.getNextSibling(pos);
273
274               if (DTM.NULL == nextNode)
275               {
276                 pos = dtm.getParent(pos);
277
278                 if (top == pos)
279                 {
280                   if (DTM.ELEMENT_NODE == dtm.getNodeType(pos))
281                   {
282                     rtreeHandler.endElement("", "", dtm.getNodeName(pos));
283                   }
284
285                   nextNode = DTM.NULL;
286
287                   break;
288                 }
289               }
290             }
291
292             pos = nextNode;
293           }
294         }
295         break;
296       case XObject.CLASS_RTREEFRAG :
297         SerializerUtils.outputResultTreeFragment(
298             rtreeHandler, value, transformer.getXPathContext());
299 // rtreeHandler.outputResultTreeFragment(value,
300
// transformer.getXPathContext());
301
break;
302       }
303     }
304     catch(org.xml.sax.SAXException JavaDoc se)
305     {
306       throw new TransformerException JavaDoc(se);
307     }
308   }
309
310   /**
311    * I need a "Node transformNode (Node)" method somewhere that the
312    * user can call to process the transformation of a node but not
313    * serialize out automatically. ????????????????
314    *
315    * Does ElemTemplateElement.executeChildTemplates() cut it? It sends
316    * results out to the stream directly, so that could be a problem.
317    */

318 }
319
Popular Tags