001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1998.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-1999
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: * Norris Boyd
026: * Kurt Westerfeld
027: *
028: * Alternatively, the contents of this file may be used under the terms of
029: * the GNU General Public License Version 2 or later (the "GPL"), in which
030: * case the provisions of the GPL are applicable instead of those above. If
031: * you wish to allow use of your version of this file only under the terms of
032: * the GPL and not to allow others to use your version of this file under the
033: * MPL, indicate your decision by deleting the provisions above and replacing
034: * them with the notice and other provisions required by the GPL. If you do
035: * not delete the provisions above, a recipient may use your version of this
036: * file under either the MPL or the GPL.
037: *
038: * ***** END LICENSE BLOCK ***** */
039:
040: package org.mozilla.javascript.tools;
041:
042: import org.mozilla.javascript.*;
043:
044: import java.text.MessageFormat;
045: import java.io.*;
046: import java.util.*;
047:
048: /**
049: * Error reporter for tools.
050: *
051: * Currently used by both the shell and the compiler.
052: */
053: public class ToolErrorReporter implements ErrorReporter {
054:
055: public ToolErrorReporter(boolean reportWarnings) {
056: this (reportWarnings, System.err);
057: }
058:
059: public ToolErrorReporter(boolean reportWarnings, PrintStream err) {
060: this .reportWarnings = reportWarnings;
061: this .err = err;
062: }
063:
064: /**
065: * Look up the message corresponding to messageId in the
066: * org.mozilla.javascript.tools.shell.resources.Messages property file.
067: * For internationalization support.
068: */
069: public static String getMessage(String messageId) {
070: return getMessage(messageId, (Object[]) null);
071: }
072:
073: public static String getMessage(String messageId, String argument) {
074: Object[] args = { argument };
075: return getMessage(messageId, args);
076: }
077:
078: public static String getMessage(String messageId, Object arg1,
079: Object arg2) {
080: Object[] args = { arg1, arg2 };
081: return getMessage(messageId, args);
082: }
083:
084: public static String getMessage(String messageId, Object[] args) {
085: Context cx = Context.getCurrentContext();
086: Locale locale = cx == null ? Locale.getDefault() : cx
087: .getLocale();
088:
089: // ResourceBundle does cacheing.
090: ResourceBundle rb = ResourceBundle.getBundle(
091: "org.mozilla.javascript.tools.resources.Messages",
092: locale);
093:
094: String formatString;
095: try {
096: formatString = rb.getString(messageId);
097: } catch (java.util.MissingResourceException mre) {
098: throw new RuntimeException(
099: "no message resource found for message property "
100: + messageId);
101: }
102:
103: if (args == null) {
104: return formatString;
105: } else {
106: MessageFormat formatter = new MessageFormat(formatString);
107: return formatter.format(args);
108: }
109: }
110:
111: private static String getExceptionMessage(RhinoException ex) {
112: String msg;
113: if (ex instanceof JavaScriptException) {
114: msg = getMessage("msg.uncaughtJSException", ex.details());
115: } else if (ex instanceof EcmaError) {
116: msg = getMessage("msg.uncaughtEcmaError", ex.details());
117: } else if (ex instanceof EvaluatorException) {
118: msg = ex.details();
119: } else {
120: msg = ex.toString();
121: }
122: return msg;
123: }
124:
125: public void warning(String message, String sourceName, int line,
126: String lineSource, int lineOffset) {
127: if (!reportWarnings)
128: return;
129: reportErrorMessage(message, sourceName, line, lineSource,
130: lineOffset, true);
131: }
132:
133: public void error(String message, String sourceName, int line,
134: String lineSource, int lineOffset) {
135: hasReportedErrorFlag = true;
136: reportErrorMessage(message, sourceName, line, lineSource,
137: lineOffset, false);
138: }
139:
140: public EvaluatorException runtimeError(String message,
141: String sourceName, int line, String lineSource,
142: int lineOffset) {
143: return new EvaluatorException(message, sourceName, line,
144: lineSource, lineOffset);
145: }
146:
147: public boolean hasReportedError() {
148: return hasReportedErrorFlag;
149: }
150:
151: public boolean isReportingWarnings() {
152: return this .reportWarnings;
153: }
154:
155: public void setIsReportingWarnings(boolean reportWarnings) {
156: this .reportWarnings = reportWarnings;
157: }
158:
159: public static void reportException(ErrorReporter er,
160: RhinoException ex) {
161: if (er instanceof ToolErrorReporter) {
162: ((ToolErrorReporter) er).reportException(ex);
163: } else {
164: String msg = getExceptionMessage(ex);
165: er.error(msg, ex.sourceName(), ex.lineNumber(), ex
166: .lineSource(), ex.columnNumber());
167: }
168: }
169:
170: public void reportException(RhinoException ex) {
171: if (ex instanceof WrappedException) {
172: WrappedException we = (WrappedException) ex;
173: we.printStackTrace(err);
174: } else {
175: String lineSeparator = SecurityUtilities
176: .getSystemProperty("line.separator");
177: String msg = getExceptionMessage(ex) + lineSeparator
178: + ex.getScriptStackTrace();
179: reportErrorMessage(msg, ex.sourceName(), ex.lineNumber(),
180: ex.lineSource(), ex.columnNumber(), false);
181: }
182: }
183:
184: private void reportErrorMessage(String message, String sourceName,
185: int line, String lineSource, int lineOffset,
186: boolean justWarning) {
187: if (line > 0) {
188: String lineStr = String.valueOf(line);
189: if (sourceName != null) {
190: Object[] args = { sourceName, lineStr, message };
191: message = getMessage("msg.format3", args);
192: } else {
193: Object[] args = { lineStr, message };
194: message = getMessage("msg.format2", args);
195: }
196: } else {
197: Object[] args = { message };
198: message = getMessage("msg.format1", args);
199: }
200: if (justWarning) {
201: message = getMessage("msg.warning", message);
202: }
203: err.println(messagePrefix + message);
204: if (null != lineSource) {
205: err.println(messagePrefix + lineSource);
206: err.println(messagePrefix + buildIndicator(lineOffset));
207: }
208: }
209:
210: private String buildIndicator(int offset) {
211: StringBuffer sb = new StringBuffer();
212: for (int i = 0; i < offset - 1; i++)
213: sb.append(".");
214: sb.append("^");
215: return sb.toString();
216: }
217:
218: private final String messagePrefix = "js: ";
219: private boolean hasReportedErrorFlag;
220: private boolean reportWarnings;
221: private PrintStream err;
222: }
|