KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > html > parsers > tidy > TidyErrorHandler


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: TidyErrorHandler.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.xmlc.html.parsers.tidy;
25
26 import gnu.regexp.RE;
27 import gnu.regexp.REException;
28 import gnu.regexp.REMatch;
29 import gnu.regexp.RESyntax;
30
31 import java.io.PrintWriter JavaDoc;
32
33 import org.enhydra.xml.io.ErrorReporter;
34 import org.enhydra.xml.xmlc.XMLCError;
35 import org.enhydra.xml.xmlc.misc.LineNumberMap;
36
37
38 /**
39  * Class for intercepting Tidy error output and doing custom error handing.
40  * This is a PrintWrite that overrides all public methods to do our own
41  * handling. It parses output looking for errors an warnings and passes them
42  * to the XMLC error handler. This is hack, hopefully Tidy.parse will get
43  * real error callbacks. It will break if tidy is ever localized.
44  */

45 class TidyErrorHandler extends PrintWriter JavaDoc {
46     /**
47      * Actual output stream.
48      */

49     private ErrorReporter fReporter;
50
51     /**
52      * Name of file being parsed.
53      */

54     private String JavaDoc fFileName;
55
56     /**
57      * If not null, we are using SSIReader and this is the mapping back to the
58      * original line numbers. Used to translate line numbers to source files.
59      */

60     private LineNumberMap fLineNumberMap;
61
62     /**
63      * Line buffer. Use to hold message until end of line.
64      */

65     private StringBuffer JavaDoc fOutbuf = new StringBuffer JavaDoc();
66
67     /**
68      * Regular expression for parsing warning/error lines.
69      * Result subexpressions are:
70      * 1 - line number
71      * 2 - "Warning", "Error" or "" (the empty string seems to be a tidy
72      * bug).
73      * 3 - message
74      * If these change, processWarnError must change.
75      *
76      */

77     private static final String JavaDoc WARN_ERROR_REGEXP =
78         "^line ([0-9,]+) column [0-9,]+ - (Warning:|Error:|) (.*)$";
79
80     /**
81      * Warning string value that is matched in WARN_ERROR_REGEXP.
82      */

83     private static final String JavaDoc WARN_MSG = "Warning:";
84
85     /**
86      * Compiler warning/error regexp.
87      */

88     private static final RE fWarnErrorRE;
89
90     /**
91      * Regular expressions defining lines to discard.
92      */

93     private static final String JavaDoc[] DISCARD_REGEXPS = {
94         ".*Tidy \\(vers.*\\) Parsing.*",
95         ".*\\\".*\\\" appears to be.*",
96         ".*warnings/errors were found.*",
97         ".*warnings or errors were found.*",
98         ".*This document has errors that must be fixed before.*",
99         ".*Document content looks like.*"
100     };
101
102     /**
103      * Compiled expressions defining lines to discard.
104      */

105     private static final RE[] fDiscardREs;
106
107     static {
108         // Compile regular expressions.
109
try {
110             fWarnErrorRE = new RE(WARN_ERROR_REGEXP, 0,
111                                   RESyntax.RE_SYNTAX_POSIX_EXTENDED);
112
113             fDiscardREs = new RE[DISCARD_REGEXPS.length];
114             for (int idx = 0; idx < DISCARD_REGEXPS.length; idx++) {
115                 fDiscardREs[idx] = new RE(DISCARD_REGEXPS[idx],
116                                           RE.REG_MULTILINE,
117                                           RESyntax.RE_SYNTAX_POSIX_EXTENDED);
118             }
119         } catch (REException except) {
120             throw new XMLCError(except);
121         }
122     }
123
124     /**
125      * Constructor.
126      */

127     public TidyErrorHandler(ErrorReporter reporter,
128                             String JavaDoc fileName,
129                             LineNumberMap lineNumberMap) {
130         // All print methods are overridden, so super is not actually used.
131
super(System.err);
132         fReporter = reporter;
133         fFileName = fileName;
134         fLineNumberMap = lineNumberMap;
135     }
136
137     /**
138      * Convert string containing a Tidy integer, which might contain a `,'
139      * to a number.
140      */

141     private int convertTidyInt(String JavaDoc intStr) {
142         // Remove commas
143
char[] strBuf = new char[intStr.length()];
144         int cIdx = 0;
145         for (int sIdx = 0; sIdx < intStr.length(); sIdx++) {
146             char c = intStr.charAt(sIdx);
147             if (c != ',') {
148                 strBuf[cIdx++] = c;
149             }
150         }
151         return Integer.valueOf(new String JavaDoc(strBuf, 0 ,cIdx)).intValue();
152     }
153
154     /**
155      * Process an warning or error match.
156      */

157     private void processWarnError(REMatch match) {
158         String JavaDoc fileName = fFileName;
159         int lineNum = convertTidyInt(match.toString(1));
160         if (fLineNumberMap != null) {
161             // Translate to source file and line
162
LineNumberMap.Line line = fLineNumberMap.getLineFromLineNum(lineNum);
163             fileName = line.getFileName();
164             lineNum = line.getLineNum();
165         }
166
167         String JavaDoc which = match.toString(2);
168         String JavaDoc msg = match.toString(3);
169
170         // Treat lack of `Error' `Warn' as a warning
171
if (which.equals(WARN_MSG) || (which.length() == 0)) {
172             fReporter.warning(msg, fileName, lineNum);
173         } else {
174             fReporter.error(msg, fileName, lineNum);
175         }
176     }
177
178     /**
179      * Process completed line.
180      */

181     private void processLine() {
182         REMatch match = fWarnErrorRE.getMatch(fOutbuf);
183         if (match != null) {
184             processWarnError(match);
185         } else {
186             // See if this should be discarded
187
int idx;
188             for (idx = 0; idx < fDiscardREs.length; idx++) {
189                 if (fDiscardREs[idx].isMatch(fOutbuf)) {
190                     break;
191                 }
192             }
193             if (idx == fDiscardREs.length) {
194                 // Didn't match a discard pattern, output it.
195
fReporter.warning("XMLC did not detect this Tidy message: "
196                                   + fOutbuf);
197             }
198         }
199             
200         fOutbuf.setLength(0);
201     }
202
203     /**
204      * Flush the stream.
205      */

206     public void flush() {
207     }
208
209     /**
210      * Close the stream.
211      */

212     public void close() {
213     }
214
215     /**
216      * Flush the stream and check its error state.
217      */

218     public boolean checkError() {
219         return false;
220     }
221
222     /**
223      * Write a single character.
224      */

225     public void write(int c) {
226         fOutbuf.append(c);
227     }
228
229     /**
230      * Write a portion of an array of characters.
231      */

232     public void write(char buf[], int off, int len) {
233         fOutbuf.append(buf, off, len);
234     }
235
236     /**
237      * Write a portion of a string.
238      */

239     public void write(String JavaDoc s, int off, int len) {
240         fOutbuf.append(s.substring(off, off+len));
241     }
242
243     /**
244      * Write a string.
245      */

246     public void write(String JavaDoc s) {
247         fOutbuf.append(s);
248     }
249
250     /**
251      * Finish the line.
252      */

253     public void println() {
254         processLine();
255     }
256
257     /**
258      * Print a boolean, and then finish the line.
259      */

260     public void println(boolean x) {
261         fOutbuf.append(x);
262         processLine();
263     }
264
265     /**
266      * Print a character, and then finish the line.
267      */

268     public void println(char x) {
269         fOutbuf.append(x);
270         processLine();
271     }
272
273     /**
274      * Print an integer, and then finish the line.
275      */

276     public void println(int x) {
277         fOutbuf.append(x);
278         processLine();
279     }
280
281     /**
282      * Print a long, and then finish the line.
283      */

284     public void println(long x) {
285         fOutbuf.append(x);
286         processLine();
287     }
288
289     /**
290      * Print a float, and then finish the line.
291      */

292     public void println(float x) {
293         fOutbuf.append(x);
294         processLine();
295     }
296
297     /**
298      * Print a double, and then finish the line.
299      */

300     public void println(double x) {
301         fOutbuf.append(x);
302         processLine();
303     }
304
305     /**
306      * Print an array of characters, and then finish the line.
307      */

308     public void println(char x[]) {
309         fOutbuf.append(x);
310         processLine();
311     }
312
313     /**
314      * Print a String, and then finish the line.
315      */

316     public void println(String JavaDoc x) {
317         fOutbuf.append(x);
318         processLine();
319     }
320
321     /**
322      * Print an Object, and then finish the line.
323      */

324     public void println(Object JavaDoc x) {
325         fOutbuf.append(x);
326         processLine();
327     }
328 }
329
Popular Tags