1 11 package org.eclipse.pde.internal.ui.model; 12 13 import java.util.*; 14 15 import org.eclipse.jface.text.*; 16 import org.xml.sax.*; 17 import org.xml.sax.helpers.*; 18 19 public abstract class DocumentHandler extends DefaultHandler { 20 21 protected FindReplaceDocumentAdapter fFindReplaceAdapter; 22 protected Stack fDocumentNodeStack = new Stack(); 23 protected int fHighestOffset = 0; 24 private Locator fLocator; 25 26 public DocumentHandler() { 27 } 28 29 32 public void startDocument() throws SAXException { 33 fDocumentNodeStack.clear(); 34 fHighestOffset = 0; 35 fFindReplaceAdapter = new FindReplaceDocumentAdapter(getDocument()); 36 } 37 38 41 public void startElement(String uri, String localName, String qName, 42 Attributes attributes) throws SAXException { 43 IDocumentNode parent = fDocumentNodeStack.isEmpty() ? null : (IDocumentNode)fDocumentNodeStack.peek(); 44 IDocumentNode node = getDocumentNode(qName, parent); 45 node.setXMLTagName(qName); 46 try { 47 int nodeOffset = getStartOffset(qName); 48 node.setOffset(nodeOffset); 49 IDocument doc = getDocument(); 50 int line = doc.getLineOfOffset(nodeOffset); 51 node.setLineIndent(node.getOffset() - doc.getLineOffset(line)); 52 for (int i = 0; i < attributes.getLength(); i++) { 54 String attName = attributes.getQName(i); 55 String attValue = attributes.getValue(i); 56 IDocumentAttribute attribute = getDocumentAttribute(attName, attValue, node); 57 if (attribute != null) { 58 IRegion region = getAttributeRegion(attName, attValue, nodeOffset); 59 if (region != null) { 60 attribute.setNameOffset(region.getOffset()); 61 attribute.setNameLength(attName.length()); 62 attribute.setValueOffset(region.getOffset() + region.getLength() - 1 - attValue.length()); 63 attribute.setValueLength(attValue.length()); 64 } 65 node.setXMLAttribute(attribute); 66 } 67 } 68 } catch (BadLocationException e) { 69 } 70 appendChildToParent(parent, node); 71 fDocumentNodeStack.push(node); 72 } 73 74 protected void appendChildToParent(IDocumentNode parent, IDocumentNode child) { 75 if (parent != null && child != null) { 76 parent.addChildNode(child); 77 } 78 } 79 80 protected abstract IDocumentNode getDocumentNode(String name, IDocumentNode parent); 81 82 protected abstract IDocumentAttribute getDocumentAttribute(String name, String value, IDocumentNode parent); 83 84 private int getStartOffset(String elementName) throws BadLocationException { 85 int line = fLocator.getLineNumber(); 86 int col = fLocator.getColumnNumber(); 87 IDocument doc = getDocument(); 88 if (col < 0) 89 col = doc.getLineLength(line); 90 String text = doc.get(fHighestOffset + 1, doc.getLineOffset(line) - fHighestOffset - 1); 91 92 ArrayList commentPositions = new ArrayList(); 93 for (int idx = 0; idx < text.length();) { 94 idx = text.indexOf("<!--", idx); if (idx == -1) 96 break; 97 int end = text.indexOf("-->", idx); if (end == -1) 99 break; 100 101 commentPositions.add(new Position(idx, end - idx)); 102 idx = end + 1; 103 } 104 105 int idx = 0; 106 for (; idx < text.length(); idx += 1) { 107 idx = text.indexOf("<" + elementName, idx); if (idx == -1) 109 break; 110 boolean valid = true; 111 for (int i = 0; i < commentPositions.size(); i++) { 112 Position pos = (Position)commentPositions.get(i); 113 if (pos.includes(idx)) { 114 valid = false; 115 break; 116 } 117 } 118 if (valid) 119 break; 120 } 121 if (idx > -1) 122 fHighestOffset += idx + 1; 123 return fHighestOffset; 124 } 125 126 private int getElementLength(IDocumentNode node, int line, int column) throws BadLocationException { 127 int endIndex = node.getOffset(); 128 IDocument doc = getDocument(); 129 int start = Math.max(doc.getLineOffset(line), node.getOffset()); 130 column = doc.getLineLength(line); 131 String lineText= doc.get(start, column - start + doc.getLineOffset(line)); 132 133 int index = lineText.indexOf("</" + node.getXMLTagName() + ">"); if (index == -1) { 135 index= lineText.indexOf("/>"); if (index == -1 ) { 137 endIndex = column; 138 } else { 139 endIndex = index + 2; 140 } 141 } else{ 142 endIndex = index + node.getXMLTagName().length() + 3; 143 } 144 return start + endIndex - node.getOffset(); 145 } 146 147 private IRegion getAttributeRegion(String name, String value, int offset) throws BadLocationException{ 148 IRegion nameRegion = fFindReplaceAdapter.find(offset, name+"\\s*=\\s*\"", true, false, false, true); if (nameRegion != null) { 150 if (getDocument().get(nameRegion.getOffset() + nameRegion.getLength(), value.length()).equals(value)) 151 return new Region(nameRegion.getOffset(), nameRegion.getLength() + value.length() + 1); 152 } 153 return null; 154 } 155 156 157 160 public void endElement(String uri, String localName, String qName) 161 throws SAXException { 162 IDocumentNode node = (IDocumentNode)fDocumentNodeStack.pop(); 163 try { 164 node.setLength(getElementLength(node, fLocator.getLineNumber() - 1, fLocator.getColumnNumber())); 165 setTextNodeOffset(node); 166 } catch (BadLocationException e) { 167 } 168 } 169 170 protected void setTextNodeOffset(IDocumentNode node) throws BadLocationException { 171 IDocumentTextNode textNode = node.getTextNode(); 172 if (textNode != null && textNode.getText() != null) { 173 if (textNode.getText().trim().length() == 0) { 174 node.removeTextNode(); 175 return; 176 } 177 IDocument doc = getDocument(); 178 String text = doc.get(node.getOffset(), node.getLength()); 179 textNode.setOffset(node.getOffset() + text.indexOf(textNode.getText())); 180 text = doc.get(textNode.getOffset(), node.getLength() - textNode.getOffset() + node.getOffset()); 181 int index = text.indexOf('<'); 182 for (index -= 1; index >= 0; index--) { 183 if (!Character.isWhitespace(text.charAt(index))) { 184 index += 1; 185 break; 186 } 187 } 188 textNode.setLength(index); 189 textNode.setText(doc.get(textNode.getOffset(), index)); 190 } 191 } 192 193 196 public void fatalError(SAXParseException e) throws SAXException { 197 generateErrorElementHierarchy(); 198 } 199 200 203 private void generateErrorElementHierarchy() { 204 while (!fDocumentNodeStack.isEmpty()) { 205 ((IDocumentNode)fDocumentNodeStack.pop()).setIsErrorNode(true); 206 } 207 } 208 209 212 public void error(SAXParseException e) throws SAXException { 213 generateErrorElementHierarchy(); 214 } 215 216 219 public void setDocumentLocator(Locator locator) { 220 fLocator = locator; 221 } 222 223 protected abstract IDocument getDocument(); 224 } 225 | Popular Tags |