PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/XML/xml/parser/javacc/XmlCollector.java

#
Java | 169 lines | 114 code | 26 blank | 29 comment | 19 complexity | cf4010c2c2579620e6e67048ee32287e MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * XmlCollector.java -- structures an HTML document tree.
  3. * Copyright (C) 1999 Quiotix Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License, version 2, as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License (http://www.gnu.org/copyleft/gpl.txt)
  13. * for more details.
  14. */
  15. package xml.parser.javacc;
  16. import java.io.FileInputStream;
  17. import java.io.InputStream;
  18. import java.util.*;
  19. /**
  20. * An XmlVisitor which modifies the structure of the document so that
  21. * begin tags are matched properly with end tags and placed in TagBlock
  22. * elements. Typically, an XmlDocument is created by the parser, which
  23. * simply returns a flat list of elements. The XmlCollector takes this
  24. * flat list and gives it the structure that is implied by the HTML content.
  25. *
  26. * @author Brian Goetz, Quiotix
  27. */
  28. public class XmlCollector extends XmlVisitor {
  29. protected ElementStack tagStack = new ElementStack();
  30. protected ElementStack elements;
  31. protected boolean collected;
  32. private static class TagStackEntry {
  33. String tagName;
  34. int index;
  35. }
  36. private static class ElementStack extends Vector {
  37. ElementStack() {
  38. super();
  39. }
  40. ElementStack( int n ) {
  41. super( n );
  42. }
  43. public void popN( int n ) {
  44. elementCount -= n;
  45. }
  46. }
  47. protected int pushNode( XmlDocument.XmlElement e ) {
  48. if (e != null) {
  49. elements.addElement( e );
  50. }
  51. return elements.size() - 1;
  52. }
  53. public void visit( XmlDocument.Comment c ) {
  54. pushNode( c );
  55. }
  56. public void visit( XmlDocument.Text t ) {
  57. pushNode( t );
  58. }
  59. public void visit( XmlDocument.Newline n ) {
  60. pushNode( n );
  61. }
  62. public void visit( XmlDocument.Tag t ) {
  63. if (t == null) {
  64. return;
  65. }
  66. TagStackEntry ts = new TagStackEntry();
  67. int index;
  68. /* Push the tag onto the element stack, and push an entry on the tag
  69. stack if it's a tag we care about matching */
  70. index = pushNode( t );
  71. if ( !t.emptyTag ) {
  72. ts.tagName = t.tagName;
  73. ts.index = index;
  74. tagStack.addElement( ts );
  75. }
  76. }
  77. public void visit( XmlDocument.EndTag t ) {
  78. if (t == null)
  79. return;
  80. int i;
  81. for ( i = tagStack.size() - 1; i >= 0; i-- ) {
  82. TagStackEntry ts = ( TagStackEntry ) tagStack.elementAt( i );
  83. if ( t.tagName.equals( ts.tagName ) ) {
  84. XmlDocument.TagBlock block;
  85. XmlDocument.ElementSequence blockElements;
  86. XmlDocument.Tag tag;
  87. // Create a new ElementSequence and copy the elements to it
  88. blockElements = new XmlDocument.ElementSequence( elements.size() - ts.index - 1 );
  89. for ( int j = ts.index + 1; j < elements.size(); j++ ) {
  90. blockElements.addElement( ( XmlDocument.XmlElement ) elements.elementAt( j ) );
  91. }
  92. tag = ( XmlDocument.Tag ) elements.elementAt( ts.index );
  93. block = new XmlDocument.TagBlock( tag, blockElements, t );
  94. block.setStartLocation( tag.getStartLocation() );
  95. block.setEndLocation( t.getEndLocation() );
  96. // Pop the elements off the stack, push the new block
  97. elements.popN( elements.size() - ts.index );
  98. elements.addElement( block );
  99. // Pop the matched tag and intervening unmatched tags
  100. tagStack.popN( tagStack.size() - i );
  101. collected = true;
  102. break;
  103. }
  104. }
  105. // If we didn't find a match, just push the end tag
  106. if ( i < 0 )
  107. pushNode( t );
  108. }
  109. public void visit( XmlDocument.TagBlock bl ) {
  110. if (bl == null)
  111. return;
  112. XmlCollector c = new XmlCollector();
  113. c.start();
  114. c.visit( bl.body );
  115. c.finish();
  116. pushNode( bl );
  117. }
  118. public void visit( XmlDocument.ElementSequence s ) {
  119. if ( s == null )
  120. return ;
  121. elements = new ElementStack( s.size() );
  122. collected = false;
  123. for ( Iterator iterator = s.iterator(); iterator.hasNext(); ) {
  124. XmlDocument.XmlElement htmlElement = ( XmlDocument.XmlElement ) iterator.next();
  125. if ( htmlElement != null )
  126. htmlElement.accept( this );
  127. }
  128. if ( collected )
  129. s.setElements( elements );
  130. }
  131. public static void main( String[] args ) throws Exception {
  132. InputStream r = new FileInputStream( args[ 0 ] );
  133. try {
  134. XmlDocument document = new XmlParser( r ).XmlDocument();
  135. document.accept( new XmlScrubber() );
  136. document.accept( new XmlCollector() );
  137. document.accept( new XmlDumper( System.out ) );
  138. }
  139. finally {
  140. r.close();
  141. }
  142. }
  143. }