KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > builders > XMLErrorReporter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

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 JavaDoc 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 JavaDoc 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 JavaDoc 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     /* (non-Javadoc)
145      * @see org.xml.sax.helpers.DefaultHandler#startDocument()
146      */

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     /* (non-Javadoc)
156      * @see org.xml.sax.helpers.DefaultHandler#endDocument()
157      */

158     public void endDocument() throws SAXException {
159         fXMLDocument.appendChild(fRootElement);
160     }
161     
162     /* (non-Javadoc)
163      * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
164      */

165     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc 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     /* (non-Javadoc)
185      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
186      */

187     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc 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     /* (non-Javadoc)
202      * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
203      */

204     public void characters(char[] characters, int start, int length)
205             throws SAXException {
206         StringBuffer JavaDoc buff = new StringBuffer JavaDoc();
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     /* (non-Javadoc)
218      * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
219      */

220     public void setDocumentLocator(Locator locator) {
221         fLocator = locator;
222     }
223     
224     private int getStartOffset(String JavaDoc elementName) throws BadLocationException {
225         int line = fLocator.getLineNumber();
226         int col = fLocator.getColumnNumber();
227         if (col < 0)
228             col = fTextDocument.getLineLength(line);
229         String JavaDoc 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); //$NON-NLS-1$
234
if (idx == -1)
235                 break;
236             int end = text.indexOf("-->", idx); //$NON-NLS-1$
237
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); //$NON-NLS-1$
247
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 JavaDoc name, String JavaDoc value, int offset) throws BadLocationException {
266         IRegion nameRegion = fFindReplaceAdapter.find(offset, name+"=\""+getWritableString(value), true, false, false, false); //$NON-NLS-1$
267
if (nameRegion != null) {
268             return nameRegion.getOffset();
269         }
270         return -1;
271     }
272     
273     private String JavaDoc getWritableString(String JavaDoc source) {
274         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
275         for (int i = 0; i < source.length(); i++) {
276             char c = source.charAt(i);
277             switch (c) {
278                 case '&' :
279                     buf.append("&amp;"); //$NON-NLS-1$
280
break;
281                 case '<' :
282                     buf.append("&lt;"); //$NON-NLS-1$
283
break;
284                 case '>' :
285                     buf.append("&gt;"); //$NON-NLS-1$
286
break;
287                 case '\'' :
288                     buf.append("&apos;"); //$NON-NLS-1$
289
break;
290                 case '\"' :
291                     buf.append("&quot;"); //$NON-NLS-1$
292
break;
293                 default :
294                     buf.append(c);
295                     break;
296             }
297         }
298         return buf.toString();
299     }
300
301     
302     protected String JavaDoc 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); //$NON-NLS-1$ //$NON-NLS-2$
306
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 JavaDoc e) {
320             return 1;
321         }
322     }
323     
324     protected int getLine(Element element, String JavaDoc 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