KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > tinytree > TinyBuilder


1 package com.icl.saxon.tinytree;
2 import com.icl.saxon.om.*;
3 import com.icl.saxon.Controller;
4 import com.icl.saxon.Context;
5 import com.icl.saxon.PreviewManager;
6 import com.icl.saxon.ExtendedInputSource;
7 import com.icl.saxon.expr.SingletonNodeSet;
8
9 import org.xml.sax.Attributes JavaDoc;
10 import javax.xml.transform.TransformerException JavaDoc;
11
12
13 /**
14   * The TinyBuilder class is responsible for taking a stream of SAX events and constructing
15   * a Document tree, using the "TinyTree" implementation.
16   *
17   * @author Michael H. Kay (mhkay@iclway.co.uk)
18   */

19   
20 public class TinyBuilder extends Builder
21
22 {
23
24     private int currentDepth = 0;
25     private int nodeNr = 0; // this is the local sequence within this document
26
private int attributeNodeNr = 0;
27     private int namespaceNodeNr = 0;
28     private boolean ended = false;
29
30     /*NEXT*/ private int[] prevAtDepth = new int[100];
31
32     public void createDocument () {
33         currentDocument = new TinyDocumentImpl();
34         if (locator==null) {
35             locator = this;
36         }
37         TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
38         doc.setSystemId(locator.getSystemId());
39         doc.setNamePool(namePool);
40     }
41
42     /**
43     * Callback interface for SAX: not for application use
44     */

45
46     public void startDocument () throws TransformerException JavaDoc
47     {
48         // System.err.println("Builder: " + this + " Start document");
49
failed = false;
50         if (started) {
51             // this happens when using an IdentityTransformer
52
return;
53         }
54         started = true;
55
56         if (currentDocument==null) {
57             // normal case
58
createDocument();
59         } else {
60             // document node supplied by user
61
if (!(currentDocument instanceof TinyDocumentImpl)) {
62                 throw new TransformerException JavaDoc("Root node supplied is of wrong type");
63             }
64             if (currentDocument.hasChildNodes()) {
65                 throw new TransformerException JavaDoc("Supplied document is not empty");
66             }
67             currentDocument.setNamePool(namePool);
68         }
69
70         //currentNode = currentDocument;
71
currentDepth = 0;
72         nodeNr = 0;
73
74         TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
75         if (lineNumbering) {
76             doc.setLineNumbering();
77         }
78
79         doc.addNode(NodeInfo.ROOT, 0, 0, 0, -1);
80         /*NEXT*/ prevAtDepth[0] = 0;
81         /*NEXT*/ doc.next[0] = -1;
82  
83         currentDepth++;
84         nodeNr++;
85
86     }
87
88     /**
89     * Callback interface for SAX: not for application use
90     */

91
92     public void endDocument () throws TransformerException JavaDoc
93     {
94              // System.err.println("TinyBuilder: " + this + " End document");
95

96         if (ended) return; // happens when using an IdentityTransformer
97
ended = true;
98
99         /*NEXT*/ TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
100         /*NEXT*/ int prev = prevAtDepth[currentDepth];
101         /*NEXT*/ if (prev > 0) {
102         /*NEXT*/ doc.next[prev] = -1;
103         /*NEXT*/ }
104         /*NEXT*/ prevAtDepth[currentDepth] = -1;
105
106         //namePool.diagnosticDump();
107

108     }
109
110     /**
111     * Callback interface for SAX: not for application use
112     */

113
114     public void startElement (
115         int nameCode, Attributes JavaDoc attributes, int[] namespaces, int namespacesUsed) throws TransformerException JavaDoc
116     {
117          // System.err.println("TinyBuilder Start element (" + nameCode + ")");
118

119         // Construct element name as a Name object
120

121         TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
122
123         // register the namespaces
124

125         int firstNS = (namespacesUsed==0 ? -1 : doc.numberOfNamespaces);
126         for (int n=0; n<namespacesUsed; n++) {
127             doc.addNamespace( nodeNr,
128                                 namespaces[n] );
129         }
130         namespacesUsed = 0;
131
132         // register the attributes
133

134         int numAtts = attributes.getLength();
135         int firstAtt = (numAtts==0 ? -1 : doc.numberOfAttributes);
136
137         doc.addNode(NodeInfo.ELEMENT, currentDepth, firstAtt, firstNS, nameCode);
138         
139         for (int i=0; i<numAtts; i++) {
140             int anamecode = namePool.allocate(
141                                 Name.getPrefix(attributes.getQName(i)),
142                                 attributes.getURI(i),
143                                 attributes.getLocalName(i));
144             doc.addAttribute( nodeNr,
145                                 anamecode,
146                                 attributes.getType(i),
147                                 attributes.getValue(i) );
148         }
149
150         
151
152         /*NEXT*/ int prev = prevAtDepth[currentDepth];
153         /*NEXT*/ if (prev > 0) {
154         /*NEXT*/ doc.next[prev] = nodeNr;
155         /*NEXT*/ }
156         /*NEXT*/ prevAtDepth[currentDepth] = nodeNr;
157         currentDepth++;
158
159         /*NEXT*/ if (currentDepth == prevAtDepth.length) {
160         /*NEXT*/ int[] p2 = new int[currentDepth*2];
161         /*NEXT*/ System.arraycopy(prevAtDepth, 0, p2, 0, currentDepth);
162         /*NEXT*/ prevAtDepth = p2;
163         /*NEXT*/ }
164         /*NEXT*/ prevAtDepth[currentDepth] = -1;
165         
166         if (locator!=null) {
167             doc.setSystemId(nodeNr, locator.getSystemId());
168             if (lineNumbering) {
169                 doc.setLineNumber(nodeNr, locator.getLineNumber());
170             }
171         }
172         nodeNr++;
173     }
174
175     /**
176     * Callback interface for SAX: not for application use
177     */

178
179     public void endElement (int nameCode) throws TransformerException JavaDoc
180     {
181         // System.err.println("End element (" + nameCode + ")");
182

183         TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
184         
185         // if a preview handler is registered, call it now
186
if (previewManager != null) {
187
188             int elementFP = nameCode & 0xfffff;
189             if (previewManager.isPreviewElement(elementFP)) {
190                 NodeInfo currentNode = doc.getNode(prevAtDepth[currentDepth-1]);
191                 //Controller c = previewManager.getController();
192
Context context = controller.makeContext(currentNode);
193                 controller.applyTemplates(
194                     context,
195                     new SingletonNodeSet(currentNode),
196                     controller.getRuleManager().getMode(previewManager.getPreviewMode()),
197                     null);
198                     
199                 // reset nodeNr to effectively delete the node's descendants
200
nodeNr = prevAtDepth[currentDepth-1] + 1;
201                 doc.truncate(nodeNr);
202                 // TODO: should truncate the text buffer, the attributes, etc.
203
}
204         }
205
206         /*NEXT*/ int prev = prevAtDepth[currentDepth];
207         /*NEXT*/ if (prev > 0) {
208         /*NEXT*/ doc.next[prev] = -1;
209         /*NEXT*/ }
210         /*NEXT*/ prevAtDepth[currentDepth] = -1;
211
212         currentDepth--;
213     }
214
215     /**
216     * Callback interface for SAX: not for application use
217     */

218
219     public void characters (char ch[], int start, int len) throws TransformerException JavaDoc
220     {
221          // System.err.println("Characters: " + new String(ch, start, len));
222
TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
223         if (len>0) {
224             int bufferStart = doc.charBufferLength;
225             doc.appendChars(ch, start, len);
226             doc.addNode(NodeInfo.TEXT, currentDepth, bufferStart, len, -1);
227
228             /*NEXT*/ int prev = prevAtDepth[currentDepth];
229             /*NEXT*/ if (prev > 0) {
230             /*NEXT*/ doc.next[prev] = nodeNr;
231             /*NEXT*/ }
232             /*NEXT*/ prevAtDepth[currentDepth] = nodeNr;
233
234             nodeNr++;
235
236         }
237
238
239     }
240
241    
242     /**
243     * Callback interface for SAX: not for application use<BR>
244     * Note: because SAX1 does not deliver comment nodes, we get these in the form of a processing
245     * instruction with a null name. This requires a specially-adapted SAX driver.
246     */

247
248     public void processingInstruction (String JavaDoc piname, String JavaDoc remainder) throws TransformerException JavaDoc
249     {
250         // System.err.println("Builder: PI " + piname);
251
TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
252         if (!discardComments) {
253             int s = doc.commentBuffer.length();
254             doc.commentBuffer.append(remainder);
255             int nameCode = namePool.allocate("", "", piname);
256             doc.addNode(NodeInfo.PI, currentDepth, s, remainder.length(),
257                          nameCode);
258
259             /*NEXT*/ int prev = prevAtDepth[currentDepth];
260             /*NEXT*/ if (prev > 0) {
261             /*NEXT*/ doc.next[prev] = nodeNr;
262             /*NEXT*/ }
263             /*NEXT*/ prevAtDepth[currentDepth] = nodeNr;
264             
265             nodeNr++;
266
267                 // TODO: handle PI Base URI
268
//if (locator!=null) {
269
// pi.setLocation(locator.getSystemId(), locator.getLineNumber());
270
//}
271
}
272     }
273
274     /**
275     * Callback interface for SAX: not for application use
276     */

277  
278     public void comment (char ch[], int start, int length) throws TransformerException JavaDoc
279     {
280         addComment(new String JavaDoc(ch, start, length));
281     }
282
283     private void addComment(String JavaDoc comment) throws TransformerException JavaDoc {
284         TinyDocumentImpl doc = (TinyDocumentImpl)currentDocument;
285         if (!discardComments && !inDTD) {
286             int s = doc.commentBuffer.length();
287             doc.commentBuffer.append(comment);
288             doc.addNode(NodeInfo.COMMENT, currentDepth, s, comment.length(), -1);
289
290             /*NEXT*/ int prev = prevAtDepth[currentDepth];
291             /*NEXT*/ if (prev > 0) {
292             /*NEXT*/ doc.next[prev] = nodeNr;
293             /*NEXT*/ }
294             /*NEXT*/ prevAtDepth[currentDepth] = nodeNr;
295
296             nodeNr++;
297         }
298
299     }
300
301     /**
302     * Set an unparsed entity in the document
303     */

304
305     public void setUnparsedEntity(String JavaDoc name, String JavaDoc uri) {
306         ((TinyDocumentImpl)currentDocument).setUnparsedEntity(name, uri);
307     }
308
309
310
311 } // end of outer class TinyBuilder
312

313 //
314
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
315
// you may not use this file except in compliance with the License. You may obtain a copy of the
316
// License at http://www.mozilla.org/MPL/
317
//
318
// Software distributed under the License is distributed on an "AS IS" basis,
319
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
320
// See the License for the specific language governing rights and limitations under the License.
321
//
322
// The Original Code is: all this file.
323
//
324
// The Initial Developer of the Original Code is
325
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
326
//
327
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
328
//
329
// Contributor(s): none.
330
//
331
Popular Tags