1 package com.icl.saxon.tree; 2 import com.icl.saxon.om.*; 3 import com.icl.saxon.expr.*; 4 import com.icl.saxon.PreviewManager; 5 import com.icl.saxon.ExtendedInputSource; 6 import com.icl.saxon.Context; 7 import com.icl.saxon.Controller; 8 9 import org.xml.sax.*; 10 import org.xml.sax.helpers.*; 11 import javax.xml.transform.TransformerException ; 12 13 import java.util.*; 14 import java.io.*; 15 import java.net.URL ; 16 17 22 23 public class TreeBuilder extends Builder 24 25 { 26 private static AttributeCollection emptyAttributeCollection = 27 new AttributeCollection((NamePool)null); 28 29 private ParentNodeImpl currentNode; 30 31 private NodeFactory nodeFactory; 32 private int[] size = new int[100]; private int depth = 0; 34 private Vector arrays = new Vector(); private boolean previousText; 36 private StringBuffer charBuffer; 37 38 private int nextNodeNumber = 1; 39 40 43 44 public TreeBuilder() { 45 nodeFactory = new DefaultNodeFactory(); 46 } 47 48 51 52 public void setNodeFactory(NodeFactory factory) { 53 nodeFactory = factory; 54 } 55 56 60 63 64 public void startDocument () throws TransformerException 65 { 66 failed = false; 68 started = true; 69 70 DocumentImpl doc; 71 if (currentDocument==null) { 72 doc = new DocumentImpl(); 74 currentDocument = doc; 75 } else { 76 if (!(currentDocument instanceof DocumentImpl)) { 78 throw new TransformerException ("Root node supplied is of wrong type"); 79 } 80 doc = (DocumentImpl)currentDocument; 81 if (doc.getFirstChild()!=null) { 82 throw new TransformerException ("Supplied document is not empty"); 83 } 84 85 } 86 if (locator==null || locator.getSystemId()==null) { 87 locator = this; 88 } 89 doc.setSystemId(locator.getSystemId()); 90 doc.setNamePool(namePool); 91 doc.setNodeFactory(nodeFactory); 92 currentNode = doc; 93 depth = 0; 94 size[depth] = 0; 95 doc.sequence = 0; 96 charBuffer = new StringBuffer (estimatedLength); 97 doc.setCharacterBuffer(charBuffer); 98 if (lineNumbering) { 99 doc.setLineNumbering(); 100 } 101 102 } 104 105 108 109 public void endDocument () throws TransformerException 110 { 111 if (currentNode==null) return; currentNode.compact(size[depth]); 113 currentNode = null; 114 115 arrays = null; 118 119 122 } 123 124 127 128 public void setDocumentLocator (Locator locator) 129 { 130 this.locator = locator; 131 } 132 133 136 137 public void startElement ( 138 int nameCode, Attributes attributes, int[] namespaces, int namespacesUsed) throws TransformerException 139 { 140 142 146 AttributeCollection atts; 147 int numAtts = attributes.getLength(); 148 if (numAtts==0) { 149 atts = emptyAttributeCollection; 150 } else { 151 atts = new AttributeCollection(namePool, attributes); 152 } 153 ElementImpl elem = nodeFactory.makeElementNode( currentNode, 156 nameCode, 157 atts, 158 namespaces, 159 namespacesUsed, 160 locator, 161 nextNodeNumber++); 162 163 167 while (depth >= arrays.size()) { 168 arrays.addElement(new NodeImpl[20]); 169 } 170 elem.useChildrenArray((NodeImpl[])arrays.elementAt(depth)); 171 172 currentNode.addChild(elem, size[depth]++); 173 if (depth >= size.length - 1) { 174 int[] newsize = new int[size.length * 2]; 175 System.arraycopy(size, 0, newsize, 0, size.length); 176 size = newsize; 177 } 178 size[++depth] = 0; 179 180 namespacesUsed = 0; 181 182 if (currentNode instanceof DocumentInfo) { 183 ((DocumentImpl)currentNode).setDocumentElement(elem); 184 } 185 186 187 currentNode = elem; 188 } 189 190 193 194 public void endElement (int nameCode) throws TransformerException 195 { 196 currentNode.compact(size[depth]); 198 199 if (previewManager != null) { 201 202 if (previewManager.isPreviewElement(currentNode.getFingerprint())) { 203 Context context = controller.makeContext(currentNode); 205 controller.applyTemplates( 206 context, 207 new SingletonNodeSet(currentNode), 208 controller.getRuleManager().getMode(previewManager.getPreviewMode()), 209 null); 210 currentNode.dropChildren(); 211 } 212 } 213 214 depth--; 215 currentNode = (ParentNodeImpl)currentNode.getParentNode(); 216 } 217 218 221 222 public void characters (char ch[], int start, int length) throws TransformerException 223 { 224 if (length>0) { 226 int bufferStart = charBuffer.length(); 227 229 TextImpl n = new TextImpl(currentNode, new String (ch, start, length)); 232 currentNode.addChild(n, size[depth]++); 233 previousText = true; 234 235 } 236 } 237 238 243 244 public void processingInstruction (String name, String remainder) 245 { 246 if (!discardComments) { 247 int nameCode = namePool.allocate("", "", name); 248 ProcInstImpl pi = new ProcInstImpl(nameCode, remainder); 249 currentNode.addChild(pi, size[depth]++); 250 if (locator!=null) { 251 pi.setLocation(locator.getSystemId(), locator.getLineNumber()); 252 } 253 } 254 } 255 256 259 260 public void comment (char ch[], int start, int length) throws TransformerException 261 { 262 if (!discardComments) { 263 CommentImpl comment = new CommentImpl(new String (ch, start, length)); 264 currentNode.addChild(comment, size[depth]++); 265 } 266 } 267 268 269 275 276 public void graftElement(ElementImpl element) throws TransformerException { 277 currentNode.addChild(element, size[depth]++); 278 } 279 280 283 284 public void setUnparsedEntity(String name, String uri) { 285 ((DocumentImpl)currentDocument).setUnparsedEntity(name, uri); 286 } 287 288 289 294 private class DefaultNodeFactory implements NodeFactory { 295 296 public ElementImpl makeElementNode( 297 NodeInfo parent, 298 int nameCode, 299 AttributeCollection attlist, 300 int[] namespaces, 301 int namespacesUsed, 302 Locator locator, 303 int sequenceNumber) 304 305 { 306 if (attlist.getLength()==0 && namespacesUsed==0) { 307 308 310 ElementImpl e = new ElementImpl(); 311 String baseURI = null; 312 int lineNumber = -1; 313 314 if (locator!=null) { 315 baseURI = locator.getSystemId(); 316 lineNumber = locator.getLineNumber(); 317 } 318 319 e.initialise(nameCode, attlist, parent, baseURI, lineNumber, sequenceNumber); 320 321 return e; 322 323 } else { 324 ElementWithAttributes e = new ElementWithAttributes(); 325 String baseURI = null; 326 int lineNumber = -1; 327 328 if (locator!=null) { 329 baseURI = locator.getSystemId(); 330 lineNumber = locator.getLineNumber(); 331 } 332 333 e.setNamespaceDeclarations(namespaces, namespacesUsed); 334 335 e.initialise(nameCode, attlist, parent, baseURI, lineNumber, sequenceNumber); 336 337 return e; 338 } 339 } 340 } 341 342 343 } 345 | Popular Tags |