1 11 package org.eclipse.pde.internal.builders; 12 13 import java.util.*; 14 15 import javax.xml.parsers.*; 16 17 import org.eclipse.core.filebuffers.*; 18 import org.eclipse.core.resources.*; 19 import org.eclipse.core.runtime.*; 20 import org.eclipse.jface.text.*; 21 import org.eclipse.pde.internal.*; 22 import org.eclipse.pde.internal.core.*; 23 import org.w3c.dom.*; 24 import org.xml.sax.*; 25 import org.xml.sax.helpers.*; 26 27 public class XMLErrorReporter extends DefaultHandler { 28 29 class ElementData { 30 int offset; 31 boolean fErrorNode; 32 33 public ElementData(int offset) { 34 this.offset = offset; 35 } 36 } 37 38 39 protected IFile fFile; 40 41 protected IProject fProject; 42 43 private int fErrorCount; 44 45 private IMarkerFactory fMarkerFactory; 46 47 private org.w3c.dom.Document fXMLDocument; 48 49 private IDocument fTextDocument; 50 51 private Stack fElementStack; 52 53 private Element fRootElement; 54 55 private Locator fLocator; 56 57 private int fHighestOffset; 58 59 private HashMap fOffsetTable; 60 61 private FindReplaceDocumentAdapter fFindReplaceAdapter; 62 63 public XMLErrorReporter(IFile file) { 64 ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); 65 try { 66 fFile = file; 67 fProject = file.getProject(); 68 manager.connect(file.getFullPath(), null); 69 fTextDocument = manager.getTextFileBuffer(file.getFullPath()).getDocument(); 70 manager.disconnect(file.getFullPath(), null); 71 fFindReplaceAdapter = new FindReplaceDocumentAdapter(fTextDocument); 72 fOffsetTable = new HashMap(); 73 fElementStack = new Stack(); 74 removeFileMarkers(); 75 } catch (CoreException e) { 76 PDE.log(e); 77 } 78 } 79 80 public IFile getFile() { 81 return fFile; 82 } 83 84 private void addMarker(String message, int lineNumber, int severity) { 85 try { 86 IMarker marker = getMarkerFactory().createMarker(fFile); 87 marker.setAttribute(IMarker.MESSAGE, message); 88 marker.setAttribute(IMarker.SEVERITY, severity); 89 if (lineNumber == -1) 90 lineNumber = 1; 91 marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); 92 if (severity == IMarker.SEVERITY_ERROR) 93 fErrorCount += 1; 94 } catch (CoreException e) { 95 PDECore.logException(e); 96 } 97 } 98 99 private IMarkerFactory getMarkerFactory() { 100 if (fMarkerFactory == null) 101 fMarkerFactory = new SchemaMarkerFactory(); 102 return fMarkerFactory; 103 } 104 105 private void addMarker(SAXParseException e, int severity) { 106 addMarker(e.getMessage(), e.getLineNumber(), severity); 107 } 108 109 public void error(SAXParseException exception) throws SAXException { 110 addMarker(exception, IMarker.SEVERITY_ERROR); 111 generateErrorElementHierarchy(); 112 } 113 114 public void fatalError(SAXParseException exception) throws SAXException { 115 addMarker(exception, IMarker.SEVERITY_ERROR); 116 generateErrorElementHierarchy(); 117 } 118 119 public int getErrorCount() { 120 return fErrorCount; 121 } 122 123 private void removeFileMarkers() { 124 try { 125 fFile.deleteMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO); 126 fFile.deleteMarkers(SchemaMarkerFactory.MARKER_ID, false, 127 IResource.DEPTH_ZERO); 128 } catch (CoreException e) { 129 PDECore.logException(e); 130 } 131 } 132 133 public void report(String message, int line, int severity) { 134 if (severity == CompilerFlags.ERROR) 135 addMarker(message, line, IMarker.SEVERITY_ERROR); 136 else if (severity == CompilerFlags.WARNING) 137 addMarker(message, line, IMarker.SEVERITY_WARNING); 138 } 139 140 public void warning(SAXParseException exception) throws SAXException { 141 addMarker(exception, IMarker.SEVERITY_WARNING); 142 } 143 144 147 public void startDocument() throws SAXException { 148 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 149 try { 150 fXMLDocument = factory.newDocumentBuilder().newDocument(); 151 } catch (ParserConfigurationException e) { 152 } 153 } 154 155 158 public void endDocument() throws SAXException { 159 fXMLDocument.appendChild(fRootElement); 160 } 161 162 165 public void startElement(String uri, String localName, String qName, 166 Attributes attributes) throws SAXException { 167 Element element = fXMLDocument.createElement(qName); 168 for (int i = 0; i < attributes.getLength(); i++) { 169 element.setAttribute(attributes.getQName(i), attributes.getValue(i)); 170 } 171 172 if (fRootElement == null) 173 fRootElement = element; 174 else 175 ((Element)fElementStack.peek()).appendChild(element); 176 fElementStack.push(element); 177 try { 178 if (fTextDocument != null) 179 fOffsetTable.put(element, new ElementData(getStartOffset(qName))); 180 } catch (BadLocationException e) { 181 } 182 } 183 184 187 public void endElement(String uri, String localName, String qName) 188 throws SAXException { 189 fElementStack.pop(); 190 } 191 192 private void generateErrorElementHierarchy() { 193 while (!fElementStack.isEmpty()) { 194 ElementData data = (ElementData) fOffsetTable.get(fElementStack.pop()); 195 if (data != null) 196 data.fErrorNode = true; 197 } 198 } 199 200 201 204 public void characters(char[] characters, int start, int length) 205 throws SAXException { 206 StringBuffer buff = new StringBuffer (); 207 for (int i = 0; i < length; i++) { 208 buff.append(characters[start + i]); 209 } 210 Text text = fXMLDocument.createTextNode(buff.toString()); 211 if (fRootElement == null) 212 fXMLDocument.appendChild(text); 213 else 214 ((Element)fElementStack.peek()).appendChild(text); 215 } 216 217 220 public void setDocumentLocator(Locator locator) { 221 fLocator = locator; 222 } 223 224 private int getStartOffset(String elementName) throws BadLocationException { 225 int line = fLocator.getLineNumber(); 226 int col = fLocator.getColumnNumber(); 227 if (col < 0) 228 col = fTextDocument.getLineLength(line); 229 String text = fTextDocument.get(fHighestOffset + 1, fTextDocument.getLineOffset(line) - fHighestOffset - 1); 230 231 ArrayList commentPositions = new ArrayList(); 232 for (int idx = 0; idx < text.length();) { 233 idx = text.indexOf("<!--", idx); if (idx == -1) 235 break; 236 int end = text.indexOf("-->", idx); if (end == -1) 238 break; 239 240 commentPositions.add(new Position(idx, end - idx)); 241 idx = end + 1; 242 } 243 244 int idx = 0; 245 for (; idx < text.length(); idx += 1) { 246 idx = text.indexOf("<" + elementName, idx); if (idx == -1) 248 break; 249 boolean valid = true; 250 for (int i = 0; i < commentPositions.size(); i++) { 251 Position pos = (Position)commentPositions.get(i); 252 if (pos.includes(idx)) { 253 valid = false; 254 break; 255 } 256 } 257 if (valid) 258 break; 259 } 260 if (idx > -1) 261 fHighestOffset += idx + 1; 262 return fHighestOffset; 263 } 264 265 private int getAttributeOffset(String name, String value, int offset) throws BadLocationException { 266 IRegion nameRegion = fFindReplaceAdapter.find(offset, name+"=\""+getWritableString(value), true, false, false, false); if (nameRegion != null) { 268 return nameRegion.getOffset(); 269 } 270 return -1; 271 } 272 273 private String getWritableString(String source) { 274 StringBuffer buf = new StringBuffer (); 275 for (int i = 0; i < source.length(); i++) { 276 char c = source.charAt(i); 277 switch (c) { 278 case '&' : 279 buf.append("&"); break; 281 case '<' : 282 buf.append("<"); break; 284 case '>' : 285 buf.append(">"); break; 287 case '\'' : 288 buf.append("'"); break; 290 case '\"' : 291 buf.append("""); break; 293 default : 294 buf.append(c); 295 break; 296 } 297 } 298 return buf.toString(); 299 } 300 301 302 protected String getTextContent(Element element) { 303 ElementData data = (ElementData)fOffsetTable.get(element); 304 try { 305 IRegion nameRegion = fFindReplaceAdapter.find(data.offset, "</"+element.getNodeName()+">", true, true, false, false); int offset = data.offset + element.getNodeName().length() + 2; 307 if (nameRegion != null) 308 return fTextDocument.get(offset, nameRegion.getOffset() - offset).trim(); 309 } catch (BadLocationException e) { 310 } 311 return null; 312 } 313 314 315 protected int getLine(Element element) { 316 ElementData data = (ElementData)fOffsetTable.get(element); 317 try { 318 return (data == null) ? 1 : fTextDocument.getLineOfOffset(data.offset) + 1; 319 } catch (Exception e) { 320 return 1; 321 } 322 } 323 324 protected int getLine(Element element, String attName) { 325 ElementData data = (ElementData)fOffsetTable.get(element); 326 try { 327 int offset = getAttributeOffset(attName, element.getAttribute(attName), data.offset); 328 if (offset != -1) 329 return fTextDocument.getLineOfOffset(offset) + 1; 330 } catch (BadLocationException e) { 331 } 332 return getLine(element); 333 } 334 335 public void validateContent(IProgressMonitor monitor) { 336 337 } 338 339 public Element getDocumentRoot() { 340 if (fRootElement != null) 341 fRootElement.normalize(); 342 return fRootElement; 343 } 344 345 346 } 347 | Popular Tags |