1 19 20 package org.netbeans.modules.xml.xdm.visitor; 21 22 import java.util.List ; 23 import java.util.Stack ; 24 import org.netbeans.modules.xml.xdm.nodes.Attribute; 25 import org.netbeans.modules.xml.xdm.nodes.Document; 26 import org.netbeans.modules.xml.xdm.nodes.Element; 27 import org.netbeans.modules.xml.xdm.nodes.Node; 28 import org.netbeans.modules.xml.xdm.nodes.NodeImpl; 29 import org.netbeans.modules.xml.xdm.nodes.Text; 30 import org.netbeans.modules.xml.xdm.nodes.Token; 31 import org.netbeans.modules.xml.xdm.nodes.TokenType; 32 import org.w3c.dom.NamedNodeMap ; 33 import org.w3c.dom.NodeList ; 34 35 39 public class NodeByPositionVisitor implements XMLNodeVisitor{ 40 41 private int currentPos = 0; 42 private Node rootNode; 43 private boolean found; 44 private int position; 45 private Node foundNode; 46 private Stack <Element> stack = new Stack <Element>(); 47 48 49 public NodeByPositionVisitor(Node rootNode){ 50 this.rootNode = rootNode; 51 } 52 53 public Element getContainingElement(int position) { 54 Node node=getContainingNode(position); 56 if(node instanceof Attribute || node instanceof Text) { 57 if(stack.isEmpty()) return null; 58 return stack.peek(); 59 } 60 return (Element)node; 61 } 62 63 public Node getContainingNode(int position) { 64 reset(); 65 this.position=position; 66 rootNode.accept(this); 67 return this.foundNode; 68 } 69 70 71 public void reset(){ 72 currentPos = 0; 73 found = false; 74 foundNode = null; 75 } 76 77 public void visit(Document doc) { 78 currentPos += getLengthOfTokens(doc); 80 NodeList nodes = doc.getChildNodes(); 81 for(int i = 0; i < nodes.getLength(); i++){ 82 Node n = (Node)nodes.item(i); 83 n.accept(this); 84 if(found) return; 85 } 86 } 87 88 public void visit(Element e) { 89 stack.push(e); 90 int openStartElemPos=currentPos; 91 currentPos += getTokenLength(e, TokenType.TOKEN_WHITESPACE); currentPos += getElementStartTokenLength(e, true); NamedNodeMap attrs = e.getAttributes(); 94 for(int i = 0; i < attrs.getLength(); i++){ 95 Node attr = (Node)attrs.item(i); 96 attr.accept(this); 97 if(found) return; 98 } 99 currentPos++; int closeStartElemPos=currentPos; 101 if((position >= openStartElemPos && position < closeStartElemPos)) { 102 this.foundNode=e; 103 found = true; 104 } 105 NodeList children = e.getChildNodes(); 106 for(int i = 0; i < children.getLength(); i++){ 107 Node n = (Node)children.item(i); 108 n.accept(this); 109 if(found) return; 110 } 111 stack.pop(); 112 int openEndElemPos=currentPos; 113 currentPos += getElementStartTokenLength(e, false); currentPos++; int closeEndElemPos=currentPos; 116 if((position >= openEndElemPos && position < closeEndElemPos)) { 117 this.foundNode=e; 118 found = true; 119 } 120 } 121 122 public void visit(Text txt) { 123 int beginTextPos=currentPos; 124 currentPos += getLengthOfTokens(txt); 128 int endTextPos=currentPos; 129 if((position >= beginTextPos && position < endTextPos)) { 130 this.foundNode=txt; 131 found = true; 132 } 133 } 134 135 public void visit(Attribute attr) { 136 int beginAttrPos=currentPos; 137 currentPos += getLengthOfTokens(attr); 138 int endAttrPos=currentPos; 139 if((position >= beginAttrPos && position < endAttrPos)) { 140 this.foundNode=attr; 141 found = true; 142 } 143 } 144 145 146 153 private int getElementStartTokenLength(Element element, boolean beginTag){ 154 String value = ""; 155 List <Token> tokens = element.getTokens(); 156 for(Token token : tokens){ 157 if(token.getType() != TokenType.TOKEN_ELEMENT_START_TAG){ 158 continue; 159 } 160 String tokenValue = token.getValue(); 161 if(beginTag){ 162 if(!tokenValue.startsWith("</")){ 163 value = tokenValue; 164 } 165 } else{ if(tokenValue.startsWith("</")){ 167 value = tokenValue; 168 } 169 } 170 } 171 return value.length(); 172 } 173 174 private int getTokenLength(NodeImpl node, TokenType type){ 175 StringBuffer buf = new StringBuffer (""); 176 List <Token> tokens = node.getTokens(); 177 for(Token token : tokens){ 178 if(token.getType() == type){ 179 buf.append(token.getValue()); 180 } 181 } 182 return buf.toString().length(); 183 } 184 185 private int getLeadingWhiteSpaces(Attribute attr){ 186 Token firstToken = attr.getTokens().get(0); if(firstToken.getType() == TokenType.TOKEN_WHITESPACE){ 188 return firstToken.getValue().length(); 189 } 190 return 0; 191 } 192 193 private int getLengthOfTokens(NodeImpl node){ 194 StringBuffer buf = new StringBuffer (); 195 List <Token> tokens = node.getTokens(); 196 for(Token token : tokens){ 197 buf.append(token.getValue()); 198 } 199 return buf.length(); 200 } 201 } 202 | Popular Tags |