1 23 24 package org.enhydra.xml.dom; 25 26 import java.util.Iterator ; 27 import java.util.TreeMap ; 28 29 import org.enhydra.xml.lazydom.LazyDOMTraversal; 30 import org.w3c.dom.Attr ; 31 import org.w3c.dom.CDATASection ; 32 import org.w3c.dom.Comment ; 33 import org.w3c.dom.Document ; 34 import org.w3c.dom.DocumentFragment ; 35 import org.w3c.dom.DocumentType ; 36 import org.w3c.dom.Element ; 37 import org.w3c.dom.Entity ; 38 import org.w3c.dom.EntityReference ; 39 import org.w3c.dom.NamedNodeMap ; 40 import org.w3c.dom.Node ; 41 import org.w3c.dom.Notation ; 42 import org.w3c.dom.ProcessingInstruction ; 43 import org.w3c.dom.Text ; 44 45 56 public class DOMTraversal { 57 61 public static final int SORT_ATTRIBUTES = 0x01; 62 63 66 public static final int ALL_ATTRIBUTES = 0x02; 67 68 71 public interface Handler { 72 77 public void handleDocument(Document document) throws Exception ; 78 79 83 public void handleDocumentType(DocumentType documentType) throws Exception ; 84 85 89 public void handleDocumentFragment(DocumentFragment documentFragment) throws Exception ; 90 91 95 public void handleAttr(Attr attr) throws Exception ; 96 97 101 public void handleEntity(Entity entity) throws Exception ; 102 103 107 public void handleEntityReference(EntityReference entityRef) throws Exception ; 108 109 114 public void handleElement(Element element) throws Exception ; 115 116 119 public void handleNotation(Notation notation) throws Exception ; 120 121 124 public void handleProcessingInstruction(ProcessingInstruction pi) throws Exception ; 125 126 129 public void handleCDATASection(CDATASection cdata) throws Exception ; 130 131 134 public void handleComment(Comment comment) throws Exception ; 135 136 139 public void handleText(Text text) throws Exception ; 140 } 141 142 146 abstract public class NodeHandler implements Handler { 147 150 abstract public void handleNode(Node node) throws Exception ; 151 152 155 public void handleDocument(Document document) throws Exception { 156 handleNode(document); 157 } 158 public void handleDocumentType(DocumentType documentType) throws Exception { 159 handleNode(documentType); 160 } 161 public void handleDocumentFragment(DocumentFragment documentFragment) throws Exception { 162 handleNode(documentFragment); 163 } 164 public void handleAttr(Attr attr) throws Exception { 165 handleNode(attr); 166 } 167 public void handleEntity(Entity entity) throws Exception { 168 handleNode(entity); 169 } 170 public void handleEntityReference(EntityReference entityRef) throws Exception { 171 handleNode(entityRef); 172 } 173 public void handleElement(Element element) throws Exception { 174 handleNode(element); 175 } 176 public void handleNotation(Notation notation) throws Exception { 177 handleNode(notation); 178 } 179 public void handleProcessingInstruction(ProcessingInstruction pi) throws Exception { 180 handleNode(pi); 181 } 182 public void handleCDATASection(CDATASection cdata) throws Exception { 183 handleNode(cdata); 184 } 185 public void handleComment(Comment comment) throws Exception { 186 handleNode(comment); 187 } 188 public void handleText(Text text) throws Exception { 189 handleNode(text); 190 } 191 } 192 193 194 protected Handler fHandler; 195 196 197 protected int fOptions; 198 199 200 protected int fDepth; 201 202 203 protected boolean fProcessingAttribute; 204 205 211 public DOMTraversal(DOMTraversal.Handler handler, 212 int options) { 213 fHandler = handler; 214 fOptions = options; 215 } 216 217 220 public DOMTraversal(int options) { 221 fOptions = options; 222 } 223 224 227 public void setHandler(DOMTraversal.Handler handler) { 228 fHandler = handler; 229 } 230 231 239 public void traverse(Node root) { 240 fDepth = 0; 241 fProcessingAttribute = false; 242 processNode(DOMOps.getActualNode(root)); 244 } 245 246 249 public final int getDepth() { 250 return fDepth; 251 } 252 253 256 public final boolean processingAttribute() { 257 return fProcessingAttribute; 258 } 259 260 263 public void processChildren(Node node) { 264 fDepth++; 265 for (Node child = node.getFirstChild(); child != null; 266 child = child.getNextSibling()) { 267 if (!(child instanceof DocumentType )) { 268 processNode(child); 269 } 270 } 271 fDepth--; 272 } 273 274 277 public void processAttributes(Element element) { 278 NamedNodeMap attrMap = element.getAttributes(); 279 if (attrMap != null) { 280 fDepth++; 281 if ((fOptions & SORT_ATTRIBUTES) != 0) { 282 processAttrsSorted(attrMap); 283 } else { 284 processAttrsUnsorted(attrMap); 285 } 286 fDepth--; 287 } 288 } 289 290 293 public void processDocumentType(Document document) { 294 DocumentType docType = document.getDoctype(); 295 if (docType != null) { 296 processNode(docType); 297 } 298 } 299 300 303 public void processDocumentTypeContents(DocumentType documentType) { 304 processNamedNodeMap(documentType.getEntities()); 305 processNamedNodeMap(documentType.getNotations()); 306 } 307 308 311 private void processAttrsSorted(NamedNodeMap attrMap) { 312 int len = attrMap.getLength(); 314 TreeMap map = new TreeMap (); 315 for (int i = 0; i < len; i++) { 316 Node node = attrMap.item(i); 317 map.put(node.getNodeName(), node); 318 } 319 320 Iterator attrs = map.values().iterator(); 322 while (attrs.hasNext()) { 323 processNode((Node )attrs.next()); 324 } 325 } 326 327 330 private void processAttrsUnsorted(NamedNodeMap attrMap) { 331 int len = attrMap.getLength(); 332 for (int i = 0; i < len; i++) { 333 processNode(attrMap.item(i)); 334 } 335 } 336 337 340 private void processNamedNodeMap(NamedNodeMap nodeMap) { 341 if (nodeMap != null) { 342 fDepth++; 343 int len = nodeMap.getLength(); 344 for (int i = 0; i < len; i++) { 345 processNode(nodeMap.item(i)); 346 } 347 fDepth--; 348 } 349 } 350 351 354 protected void processNode(Node node) { 355 try { 356 switch (node.getNodeType()) { 357 case Node.DOCUMENT_NODE: 358 fHandler.handleDocument((Document )node); 359 break; 360 case Node.DOCUMENT_TYPE_NODE: 361 fHandler.handleDocumentType((DocumentType )node); 362 break; 363 case Node.DOCUMENT_FRAGMENT_NODE: 364 fHandler.handleDocumentFragment((DocumentFragment )node); 365 break; 366 case Node.ATTRIBUTE_NODE: 367 processAttr((Attr )node); 368 break; 369 case Node.ELEMENT_NODE: 370 fHandler.handleElement((Element )node); 371 break; 372 case Node.ENTITY_NODE: 373 fHandler.handleEntity((Entity )node); 374 break; 375 case Node.ENTITY_REFERENCE_NODE: 376 fHandler.handleEntityReference((EntityReference )node); 377 break; 378 case Node.NOTATION_NODE: 379 fHandler.handleNotation((Notation )node); 380 break; 381 case Node.PROCESSING_INSTRUCTION_NODE: 382 fHandler.handleProcessingInstruction((ProcessingInstruction )node); 383 break; 384 case Node.TEXT_NODE: 385 fHandler.handleText((Text )node); 386 break; 387 case Node.CDATA_SECTION_NODE: 388 fHandler.handleCDATASection((CDATASection )node); 389 break; 390 case Node.COMMENT_NODE: 391 fHandler.handleComment((Comment )node); 392 break; 393 default: 394 throw new DOMError("unknown node type: " + node.getNodeType()); 395 } 396 } catch (RuntimeException except) { 397 throw except; 399 } catch (Exception except) { 400 throw new DOMError(except); 401 } 402 } 403 404 407 private void processAttr(Attr attr) throws Exception { 408 if (((fOptions & ALL_ATTRIBUTES) != 0) || attr.getSpecified()) { 409 fProcessingAttribute = true; 410 fHandler.handleAttr(attr); 411 fProcessingAttribute = false; 412 } 413 } 414 415 419 public static DOMTraversal getTraverser(Handler handler, 420 int options, 421 Node node) { 422 427 if (DOMOps.isLazyDOMInstance(DOMOps.getDocument(node))) { 428 return new LazyDOMTraversal(handler, options); 429 } else { 430 return new DOMTraversal(handler, options); 431 } 432 } 433 } 434 | Popular Tags |