KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openlaszlo > compiler > CompilationError


1 /* *****************************************************************************
2  * CompilationError.java
3  * ****************************************************************************/

4
5 /* J_LZ_COPYRIGHT_BEGIN *******************************************************
6 * Copyright 2001-2004 Laszlo Systems, Inc. All Rights Reserved. *
7 * Use is subject to license terms. *
8 * J_LZ_COPYRIGHT_END *********************************************************/

9
10 package org.openlaszlo.compiler;
11 import java.io.File JavaDoc;
12 import java.util.*;
13 import org.jdom.Element;
14 import org.jdom.JDOMException;
15 import org.xml.sax.SAXParseException JavaDoc;
16 import org.openlaszlo.utils.ChainedException;
17 import org.openlaszlo.xml.internal.XMLUtils;
18 import org.openlaszlo.sc.parser.ParseException;
19
20 /** Represents an error that occurred during the invocation of the
21  * interface compiler.
22  */

23 public class CompilationError extends RuntimeException JavaDoc {
24     /** The name of the file within which the error occurred. */
25     private String JavaDoc mPathname = null;
26     /** The line number of the error, or null. */
27     private Integer JavaDoc mLineNumber = null;
28     /** The line number of the error, or null. */
29     private Integer JavaDoc mColumnNumber = null;
30     /** The element at which the error occurred, or null. */
31     private Element mElement = null;
32     private String JavaDoc mAttribute = null;
33     /** Prefix to remove from pathnames. */
34     private String JavaDoc mFileBase = "";
35     private List errors = new Vector();
36
37     /** A suggested solution for an error */
38     private String JavaDoc solutionMessage = "";
39
40     /** Set this to true to throw compilation errors that have a
41      * cause, instead of wrapping them in instances of
42      * CompilationError. This is useful for debugging the
43      * compiler. */

44     public static boolean ThrowCompilationErrors = false;
45
46     /** Constructs an instance.
47      * @param message a string
48      */

49     public CompilationError(String JavaDoc message) {
50         super(message);
51     }
52
53     /** Constructs an instance.
54      * @param message a string
55      * @param element the element within which the error occurred
56      */

57     public CompilationError(String JavaDoc message, Element element) {
58         super(message);
59         initElement(element, null);
60     }
61
62     /** Constructs an instance.
63      * @param element the element within which the error occurred
64      * @param cause the chained cause of the error
65      */

66     public CompilationError(Element element, Throwable JavaDoc cause) {
67         super(getCauseMessage(cause));
68         initElement(element, cause);
69     }
70
71     public CompilationError(Element element, String JavaDoc attribute,
72                             Throwable JavaDoc cause) {
73         super(getCauseMessage(cause));
74         initElement(element, attribute, cause);
75     }
76
77     
78     public CompilationError(Throwable JavaDoc cause, String JavaDoc solution) {
79         this(cause);
80         this.solutionMessage = solution;
81     }
82
83     /** Constructs an instance.
84      * @param cause the chained cause of the error
85      */

86     public CompilationError(Throwable JavaDoc cause) {
87         super(getCauseMessage(cause));
88         SAXParseException JavaDoc se = null; // is there a SAXParseException with more location info?
89
if (cause instanceof JDOMException) {
90             JDOMException je = (JDOMException) cause;
91             if (je.getCause() instanceof SAXParseException JavaDoc) {
92                  se = (SAXParseException JavaDoc) je.getCause();
93             }
94         } else if (cause instanceof SAXParseException JavaDoc) {
95                 se = (SAXParseException JavaDoc) cause;
96         }
97         if (se != null) {
98             initPathname(se.getPublicId());
99             setLineNumber(se.getLineNumber());
100             setColumnNumber(se.getColumnNumber());
101         }
102     }
103
104     /** The constructors use this. */
105     private static String JavaDoc getCauseMessage(Throwable JavaDoc cause) {
106         if (ThrowCompilationErrors) {
107             cause.printStackTrace();
108             throw new ChainedException(cause);
109         }
110         if (cause instanceof JDOMException &&
111             ((JDOMException) cause).getCause() != null)
112             cause = ((JDOMException) cause).getCause();
113         String JavaDoc message = cause.getMessage();
114         if (cause instanceof java.io.FileNotFoundException JavaDoc) {
115             return "file not found: " + message;
116         } else if (cause instanceof java.lang.NumberFormatException JavaDoc) {
117             return "invalid number: " + message;
118         } else if (cause instanceof org.openlaszlo.compiler.ViewSchema.ColorFormatException) {
119             return "invalid color: " + message;
120         } else if (cause instanceof ParseException JavaDoc) {
121             return ((ParseException JavaDoc) cause).getMessage(false);
122         } else {
123             /*String name = cause.getClass().getName();
124             if (name.lastIndexOf('.') > 0)
125                 name = name.substring(name.lastIndexOf('.')+1);
126             if (name.indexOf('$') < 0)
127             message = name + ": " + message;*/

128             return message;
129         }
130     }
131
132     public void attachErrors(List errors) {
133         this.errors.addAll(errors);
134     }
135     
136     /** Set the 'solution message', a hint as to what might have
137         caused this error.
138         @param solution a helpful message to be appended to the error message
139      */

140     public void setSolution(String JavaDoc sol) {
141         this.solutionMessage = sol;
142     }
143
144     /** Initializes this instance's element to the specified
145      * parameter. May be called at most once, and only if the element
146      * wasn't initialized in the constructor.
147      * @param element the element at which the error occurred
148      */

149
150     void initElement(Element element) {
151         initElement(element, null);
152     }
153
154     void initElement(Element element, Throwable JavaDoc cause) {
155         if (this.mElement != null && mElement != element) {
156             throw new IllegalStateException JavaDoc("initElement called twice, on " +
157                                             mElement + " and " + element);
158         }
159         this.mElement = element;
160         this.initPathname(Parser.getSourceMessagePathname(element));
161
162         // Prefer the script compiler's suggestion of what line number
163
// the error occurred on
164
if (cause instanceof ParseException JavaDoc) {
165             this.setLineNumber(((ParseException JavaDoc) cause).getBeginLine());
166             this.setColumnNumber(((ParseException JavaDoc) cause).getBeginColumn());
167         } else {
168             this.setLineNumber(Parser.getSourceLocation(element, Parser.LINENO).intValue());
169             this.setColumnNumber(Parser.getSourceLocation(element, Parser.COLNO).intValue());
170         }
171     }
172
173     void initElement(Element element, String JavaDoc attribute, Throwable JavaDoc cause) {
174         initElement(element, cause);
175         this.mAttribute = attribute;
176     }
177
178     /** Returns the element at which the error occurred.
179      * @return the element at which the error occurred
180      */

181     public Element getElement()
182     {
183         return this.mElement;
184     }
185
186     public String JavaDoc getSolutionMessage() {
187         return solutionMessage;
188     }
189
190     public void setFileBase(String JavaDoc fileBase) {
191         this.mFileBase = fileBase;
192     }
193     
194     /** Initializes this instance's pathname to the specified
195      * parameter. May be called at most once, and only if the pathname
196      * wasn't initialized in the constructor.
197      * @param pathname the name of the file at which the error occurred
198      */

199     public void initPathname(String JavaDoc pathname) {
200         if (mPathname != null && mPathname.intern() != pathname.intern()) {
201             throw new IllegalStateException JavaDoc("initPathname called twice, on " +
202                                             mPathname + " and " + pathname);
203         }
204         this.mPathname = pathname;
205     }
206
207     /** Returns the name of the file within which this error
208      * occurred.
209      * @return the name of the file within which the error occurred
210      */

211     public String JavaDoc getPathname() {
212         return mPathname;
213     }
214
215     // TODO: [2003-01-16] Once ScriptElementCompiler is fixed not to
216
// use this method, it can be removed.
217
public void setPathname(String JavaDoc pathname) {
218         mPathname = pathname;
219     }
220
221     /** Returns the column number at which this error occurred, or null
222      * if this can't be determined.
223      * @return the line number at which the error occurred
224     */

225     public Integer JavaDoc getColumnNumber() {
226         return mColumnNumber;
227     }
228
229     public void setColumnNumber(int columnNumber) {
230         mColumnNumber = new Integer JavaDoc(columnNumber);
231     }
232
233     public void initColumnNumber(int columnNumber) {
234         if (mColumnNumber != null && mColumnNumber.intValue() != columnNumber)
235             throw new IllegalStateException JavaDoc("initColumnNumber called twice, on " +
236                                             mColumnNumber + " and " + columnNumber);
237         setColumnNumber(columnNumber);
238     }
239
240     /** Returns the line number at which this error occurred, or null
241      * if this can't be determined.
242      * @return the line number at which the error occurred
243     */

244     public Integer JavaDoc getLineNumber() {
245         return mLineNumber;
246     }
247
248     public void setLineNumber(int lineNumber) {
249         mLineNumber = new Integer JavaDoc(lineNumber);
250     }
251
252     public void initLineNumber(int lineNumber) {
253         if (mLineNumber != null && mLineNumber.intValue() != lineNumber)
254             throw new IllegalStateException JavaDoc("initLineNumber called twice, on " +
255                                             mLineNumber + " and " + lineNumber);
256         setLineNumber(lineNumber);
257     }
258
259     /** Return a message describing the error.
260      * @param base pathname prefix to strip out from error messages
261      * @return a message describing the error
262      */

263     public String JavaDoc getMessage (File JavaDoc base) {
264         return getMessage(base.getAbsolutePath() + File.separator);
265     }
266
267     /** Return a message describing the error.
268      * @param base pathname prefix to strip out from error messages
269      * @return a message describing the error
270      */

271     public String JavaDoc getMessage (String JavaDoc base) {
272         String JavaDoc errmsg = _getMessage();
273
274         if (base != null && errmsg.startsWith(base)) {
275             // remove base string prefix
276
return errmsg.substring(base.length());
277         } else {
278             return errmsg;
279         }
280     }
281
282
283     /** Return a message describing the error.
284      * @return a message describing the error
285      */

286     private String JavaDoc _getMessage() {
287         String JavaDoc message = "";
288         if (mPathname != null && !super.getMessage().startsWith(mPathname)) {
289             message += mPathname + ":";
290             if (mLineNumber != null) {
291                 message += mLineNumber + ":";
292                 if (mColumnNumber != null) {
293                     message += mColumnNumber + ":";
294                 }
295             }
296             message += " ";
297         }
298
299         String JavaDoc errorText = super.getMessage();
300         // super.getMessage() seems to be returning null for Tomcat
301
// xerces/JDOM errors [hqm 11-2003]
302
if (errorText == null) {
303             errorText = "";
304         }
305         if (!solutionMessage.equals("") &&
306             !errorText.equals("") &&
307             !errorText.endsWith(".") && !errorText.endsWith(". ")) {
308             errorText += ". ";
309         }
310         if (!solutionMessage.equals("") &&
311             !errorText.endsWith(" ")) {
312             errorText += " ";
313         }
314         return message + errorText + getSolutionMessage();
315     }
316
317     public String JavaDoc getMessage() {
318         return getMessage(mFileBase + File.separator);
319     }
320     
321     public String JavaDoc toHTML() {
322         // todo: properly quote the filename
323
String JavaDoc sourceFile = getPathname();
324         String JavaDoc message = getMessage();
325         String JavaDoc solution = "<font color=\"green\">" + getSolutionMessage() + "</font>";
326         if (sourceFile != null && message.startsWith(sourceFile)) {
327             message = "<A HREF=\"" + sourceFile + "\">" + sourceFile + "</A>" +
328                 message.substring(sourceFile.length());
329         }
330         return "<HTML><HEAD>" +
331             "<TITLE>" + "Compilation Error" + "</TITLE>" +
332             "</HEAD><BODY>" + message + "<p>" + solution +
333             "</BODY></HTML>";
334     }
335     
336     public String JavaDoc toXML() {
337         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
338         buffer.append("<error>");
339         buffer.append(XMLUtils.escapeXml(getMessage()));
340         for (Iterator iter = errors.iterator(); iter.hasNext(); )
341             buffer.append(((CompilationError) iter.next()).toXML());
342         buffer.append("</error>");
343         return buffer.toString();
344     }
345
346     /**
347      * @return the error message w/out the filename and line, col numbers
348      * XXX This doesn't seem to work.
349      */

350     public String JavaDoc getErrorMessage() {
351         return super.getMessage();
352     }
353 }
354
Popular Tags