6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javadoc;
27
28 import java.io.PrintWriter;
29 import java.util.Locale;
30 import java.util.ResourceBundle;
31
32 import com.sun.javadoc.*;
33 import com.sun.tools.javac.util.Context;
34 import com.sun.tools.javac.util.JCDiagnostic;
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
36 import com.sun.tools.javac.util.JavacMessages;
37 import com.sun.tools.javac.util.Log;
38
39 /**
40 * Utility for integrating with javadoc tools and for localization.
41 * Handle Resources. Access to error and warning counts.
42 * Message formatting.
43 * <br>
44 * Also provides implementation for DocErrorReporter.
45 *
46 * <p><b>This is NOT part of any supported API.
47 * If you write code that depends on this, you do so at your own risk.
48 * This code and its internal interfaces are subject to change or
49 * deletion without notice.</b>
50 *
51 * @see java.util.ResourceBundle
52 * @see java.text.MessageFormat
53 * @author Neal Gafter (rewrite)
54 */
55 public class Messager extends Log implements DocErrorReporter {
56 public static final SourcePosition NOPOS = null;
57
58 /** Get the current messager, which is also the compiler log. */
59 public static Messager instance0(Context context) {
60 Log instance = context.get(logKey);
61 if (instance == null || !(instance instanceof Messager))
62 throw new InternalError("no messager instance!");
63 return (Messager)instance;
64 }
65
66 public static void preRegister(Context context,
67 final String programName) {
68 context.put(logKey, new Context.Factory<Log>() {
69 public Log make(Context c) {
70 return new Messager(c,
71 programName);
72 }
73 });
74 }
75 public static void preRegister(Context context,
76 final String programName,
77 final PrintWriter errWriter,
78 final PrintWriter warnWriter,
79 final PrintWriter noticeWriter) {
80 context.put(logKey, new Context.Factory<Log>() {
81 public Log make(Context c) {
82 return new Messager(c,
83 programName,
84 errWriter,
85 warnWriter,
86 noticeWriter);
87 }
88 });
89 }
90
91 public class ExitJavadoc extends Error {
92 private static final long serialVersionUID = 0;
93 }
94
95 final String programName;
96
97 private Locale locale;
98 private final JavacMessages messages;
99 private final JCDiagnostic.Factory javadocDiags;
100
101 /** The default writer for diagnostics
102 */
103 static final PrintWriter defaultErrWriter = new PrintWriter(System.err);
104 static final PrintWriter defaultWarnWriter = new PrintWriter(System.err);
105 static final PrintWriter defaultNoticeWriter = new PrintWriter(System.out);
106
107 /**
108 * Constructor
109 * @param programName Name of the program (for error messages).
110 */
111 protected Messager(Context context, String programName) {
112 this(context, programName, defaultErrWriter, defaultWarnWriter, defaultNoticeWriter);
113 }
114
115 /**
116 * Constructor
117 * @param programName Name of the program (for error messages).
118 * @param errWriter Stream for error messages
119 * @param warnWriter Stream for warnings
120 * @param noticeWriter Stream for other messages
121 */
122 @SuppressWarnings("deprecation")
123 protected Messager(Context context,
124 String programName,
125 PrintWriter errWriter,
126 PrintWriter warnWriter,
127 PrintWriter noticeWriter) {
128 super(context, errWriter, warnWriter, noticeWriter);
129 messages = JavacMessages.instance(context);
130 messages.add(locale -> ResourceBundle.getBundle("com.sun.tools.javadoc.resources.javadoc",
131 locale));
132 javadocDiags = new JCDiagnostic.Factory(messages, "javadoc");
133 this.programName = programName;
134
135 }
136
137 public void setLocale(Locale locale) {
138 this.locale = locale;
139 }
140
141 /**
142 * get and format message string from resource
143 *
144 * @param key selects message from resource
145 * @param args arguments for the message
146 */
147 String getText(String key, Object... args) {
148 return messages.getLocalizedString(locale, key, args);
149 }
150
151 /**
152 * Print error message, increment error count.
153 * Part of DocErrorReporter.
154 *
155 * @param msg message to print
156 */
157 public void printError(String msg) {
158 printError(null, msg);
159 }
160
161 /**
162 * Print error message, increment error count.
163 * Part of DocErrorReporter.
164 *
165 * @param pos the position where the error occurs
166 * @param msg message to print
167 */
168 public void printError(SourcePosition pos, String msg) {
169 if (diagListener != null) {
170 report(DiagnosticType.ERROR, pos, msg);
171 return;
172 }
173
174 if (nerrors < MaxErrors) {
175 String prefix = (pos == null) ? programName : pos.toString();
176 errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg);
177 errWriter.flush();
178 prompt();
179 nerrors++;
180 }
181 }
182
183 /**
184 * Print warning message, increment warning count.
185 * Part of DocErrorReporter.
186 *
187 * @param msg message to print
188 */
189 public void printWarning(String msg) {
190 printWarning(null, msg);
191 }
192
193 /**
194 * Print warning message, increment warning count.
195 * Part of DocErrorReporter.
196 *
197 * @param pos the position where the error occurs
198 * @param msg message to print
199 */
200 public void printWarning(SourcePosition pos, String msg) {
201 if (diagListener != null) {
202 report(DiagnosticType.WARNING, pos, msg);
203 return;
204 }
205
206 if (nwarnings < MaxWarnings) {
207 String prefix = (pos == null) ? programName : pos.toString();
208 warnWriter.println(prefix + ": " + getText("javadoc.warning") +" - " + msg);
209 warnWriter.flush();
210 nwarnings++;
211 }
212 }
213
214 /**
215 * Print a message.
216 * Part of DocErrorReporter.
217 *
218 * @param msg message to print
219 */
220 public void printNotice(String msg) {
221 printNotice(null, msg);
222 }
223
224 /**
225 * Print a message.
226 * Part of DocErrorReporter.
227 *
228 * @param pos the position where the error occurs
229 * @param msg message to print
230 */
231 public void printNotice(SourcePosition pos, String msg) {
232 if (diagListener != null) {
233 report(DiagnosticType.NOTE, pos, msg);
234 return;
235 }
236
237 if (pos == null)
238 noticeWriter.println(msg);
239 else
240 noticeWriter.println(pos + ": " + msg);
241 noticeWriter.flush();
242 }
243
244 /**
245 * Print error message, increment error count.
246 *
247 * @param key selects message from resource
248 */
249 public void error(SourcePosition pos, String key, Object... args) {
250 printError(pos, getText(key, args));
251 }
252
253 /**
254 * Print warning message, increment warning count.
255 *
256 * @param key selects message from resource
257 */
258 public void warning(SourcePosition pos, String key, Object... args) {
259 printWarning(pos, getText(key, args));
260 }
261
262 /**
263 * Print a message.
264 *
265 * @param key selects message from resource
266 */
267 public void notice(String key, Object... args) {
268 printNotice(getText(key, args));
269 }
270
271 /**
272 * Return total number of errors, including those recorded
273 * in the compilation log.
274 */
275 public int nerrors() { return nerrors; }
276
277 /**
278 * Return total number of warnings, including those recorded
279 * in the compilation log.
280 */
281 public int nwarnings() { return nwarnings; }
282
286 public void exitNotice() {
287 if (nerrors > 0) {
288 notice((nerrors > 1) ? "main.errors" : "main.error",
289 "" + nerrors);
290 }
291 if (nwarnings > 0) {
292 notice((nwarnings > 1) ? "main.warnings" : "main.warning",
293 "" + nwarnings);
294 }
295 }
296
297 /**
298 * Force program exit, e.g., from a fatal error.
299 * <p>
300 * TODO: This method does not really belong here.
301 */
302 public void exit() {
303 throw new ExitJavadoc();
304 }
305
306 private void report(DiagnosticType type, SourcePosition pos, String msg) {
307 switch (type) {
308 case ERROR:
309 case WARNING:
310 Object prefix = (pos == null) ? programName : pos;
311 report(javadocDiags.create(type, null, null, "msg", prefix, msg));
312 break;
313
314 case NOTE:
315 String key = (pos == null) ? "msg" : "pos.msg";
316 report(javadocDiags.create(type, null, null, key, pos, msg));
317 break;
318
319 default:
320 throw new IllegalArgumentException(type.toString());
321 }
322 }
323 }
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.javadoc.internal.tool;
27
28
29 import java.io.PrintWriter;
30 import java.util.Locale;
31 import java.util.ResourceBundle;
32
33 import javax.lang.model.element.Element;
34 import javax.tools.Diagnostic.Kind;
35
36 import jdk.javadoc.doclet.Reporter;
37 import com.sun.source.tree.CompilationUnitTree;
38 import com.sun.source.util.DocSourcePositions;
39 import com.sun.source.util.DocTreePath;
40 import com.sun.source.util.TreePath;
41 import com.sun.tools.javac.api.JavacTrees;
42 import com.sun.tools.javac.tree.JCTree;
43 import com.sun.tools.javac.util.Context;
44 import com.sun.tools.javac.util.JCDiagnostic;
45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
46 import com.sun.tools.javac.util.JavacMessages;
47 import com.sun.tools.javac.util.Log;
48
49 /**
50 * Utility for integrating with javadoc tools and for localization.
51 * Handle Resources. Access to error and warning counts.
52 * Message formatting.
53 * <br>
54 * Also provides implementation for DocErrorReporter.
55 *
56 * <p><b>This is NOT part of any supported API.
57 * If you write code that depends on this, you do so at your own risk.
58 * This code and its internal interfaces are subject to change or
59 * deletion without notice.</b>
60 *
61 * @see java.util.ResourceBundle
62 * @see java.text.MessageFormat
63 * @author Neal Gafter (rewrite)
64 */
65 public class Messager extends Log implements Reporter {
66 final Context context;
67
68 /** Get the current messager, which is also the compiler log. */
69 public static Messager instance0(Context context) {
70 Log instance = context.get(logKey);
71 if (instance == null || !(instance instanceof Messager))
72 throw new InternalError("no messager instance!");
73 return (Messager)instance;
74 }
75
76 public static void preRegister(Context context,
77 final String programName) {
78 context.put(logKey, new Context.Factory<Log>() {
79 public Log make(Context c) {
80 return new Messager(c, programName);
81 }
82 });
83 }
84
85 public static void preRegister(Context context, final String programName,
86 final PrintWriter outWriter, final PrintWriter errWriter) {
87 context.put(logKey, new Context.Factory<Log>() {
88 public Log make(Context c) {
89 return new Messager(c, programName, outWriter, errWriter);
90 }
91 });
92 }
93
94 @Override
95 public void print(Kind kind, String msg) {
96 switch (kind) {
97 case ERROR:
98 printError(msg);
99 return;
100 case WARNING:
101 case MANDATORY_WARNING:
102 printWarning(msg);
103 return;
104 default:
105 printNotice(msg);
106 return;
107 }
108 }
109
110 @Override
111 public void print(Kind kind, DocTreePath path, String msg) {
112 switch (kind) {
113 case ERROR:
114 printError(path, msg);
115 return;
116 case WARNING:
117 case MANDATORY_WARNING:
118 printWarning(path, msg);
119 return;
120 default:
121 printWarning(path, msg);
122 return;
123 }
124 }
125
126 @Override
127 public void print(Kind kind, Element e, String msg) {
128 switch (kind) {
129 case ERROR:
130 printError(e, msg);
131 return;
132 case WARNING:
133 case MANDATORY_WARNING:
134 printWarning(e, msg);
135 return;
136 default:
137 printWarning(e, msg);
138 return;
139 }
140 }
141
142 public class ExitJavadoc extends Error {
143 private static final long serialVersionUID = 0;
144 }
145
146 final String programName;
147
148 private Locale locale;
149 private final JavacMessages messages;
150 private final JCDiagnostic.Factory javadocDiags;
151
152 /** The default writer for diagnostics
153 */
154 static final PrintWriter defaultOutWriter = new PrintWriter(System.out);
155 static final PrintWriter defaultErrWriter = new PrintWriter(System.err);
156
157 /**
158 * Constructor
159 * @param programName Name of the program (for error messages).
160 */
161 public Messager(Context context, String programName) {
162 this(context, programName, defaultOutWriter, defaultErrWriter);
163 }
164
165 /**
166 * Constructor
167 * @param programName Name of the program (for error messages).
168 * @param outWriter Stream for notices etc.
169 * @param errWriter Stream for errors and warnings
170 */
171 @SuppressWarnings("deprecation")
172 public Messager(Context context, String programName, PrintWriter outWriter, PrintWriter errWriter) {
173 super(context, errWriter, errWriter, outWriter);
174 messages = JavacMessages.instance(context);
175 messages.add(locale -> ResourceBundle.getBundle("jdk.javadoc.internal.tool.resources.javadoc",
176 locale));
177 javadocDiags = new JCDiagnostic.Factory(messages, "javadoc");
178 this.programName = programName;
179 this.context = context;
180 locale = Locale.getDefault();
181 }
182
183 public void setLocale(Locale locale) {
184 this.locale = locale;
185 }
186
187 /**
188 * get and format message string from resource
189 *
190 * @param key selects message from resource
191 * @param args arguments for the message
192 */
193 String getText(String key, Object... args) {
194 return messages.getLocalizedString(locale, key, args);
195 }
196
197 private String getDiagSource(DocTreePath path) {
198 if (path == null) {
199 return programName;
200 }
201 JavacTrees trees = JavacTrees.instance(context);
202 DocSourcePositions sourcePositions = trees.getSourcePositions();
203 CompilationUnitTree cu = path.getTreePath().getCompilationUnit();
204 long spos = sourcePositions.getStartPosition(cu, path.getDocComment(), path.getLeaf());
205 long lineNumber = cu.getLineMap().getLineNumber(spos);
206 String fname = cu.getSourceFile().getName();
207 String posString = fname + ":" + lineNumber;
208 return posString;
209 }
210
211 private String getDiagSource(Element e) {
212 if (e == null) {
213 return programName;
214 }
215 JavacTrees trees = JavacTrees.instance(context);
216 TreePath path = trees.getPath(e);
217 DocSourcePositions sourcePositions = trees.getSourcePositions();
218 JCTree tree = trees.getTree(e);
219 CompilationUnitTree cu = path.getCompilationUnit();
220 long spos = sourcePositions.getStartPosition(cu, tree);
221 long lineNumber = cu.getLineMap().getLineNumber(spos);
222 String fname = cu.getSourceFile().getName();
223 String posString = fname + ":" + lineNumber;
224 return posString;
225 }
226
227 /**
228 * Print error message, increment error count.
229 * Part of DocErrorReporter.
230 *
231 * @param msg message to print
232 */
233 public void printError(String msg) {
234 printError((DocTreePath)null, msg);
235 }
236
237 public void printError(DocTreePath path, String msg) {
238 String prefix = getDiagSource(path);
239 if (diagListener != null) {
240 report(DiagnosticType.ERROR, prefix, msg);
241 return;
242 }
243 incrementErrorCount(prefix, msg);
244 }
245
246 public void printError(Element e, String msg) {
247 String prefix = getDiagSource(e);
248 if (diagListener != null) {
249 report(DiagnosticType.ERROR, prefix, msg);
250 return;
251 }
252 incrementErrorCount(prefix, msg);
253 }
254
255 private void incrementErrorCount(String prefix, String msg) {
256 if (nerrors < MaxErrors) {
257 errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg);
258 errWriter.flush();
259 prompt();
260 nerrors++;
261 }
262 }
263
264 /**
265 * Print warning message, increment warning count.
266 * Part of DocErrorReporter.
267 *
268 * @param msg message to print
269 */
270 public void printWarning(String msg) {
271 printWarning((DocTreePath)null, msg);
272 }
273
274 public void printWarning(DocTreePath path, String msg) {
275 String prefix = getDiagSource(path);
276 if (diagListener != null) {
277 report(DiagnosticType.WARNING, prefix, msg);
278 return;
279 }
280 incrementWarningCount(prefix, msg);
281 }
282
283 public void printWarning(Element e, String msg) {
284 String prefix = getDiagSource(e);
285 if (diagListener != null) {
286 report(DiagnosticType.WARNING, prefix, msg);
287 return;
288 }
289 incrementWarningCount(prefix, msg);
290 }
291
292 private void incrementWarningCount(String prefix, String msg) {
293 if (nwarnings < MaxWarnings) {
294 warnWriter.println(prefix + ": " + getText("javadoc.warning") + " - " + msg);
295 warnWriter.flush();
296 nwarnings++;
297 }
298 }
299
300 /**
301 * Print a message.
302 * Part of DocErrorReporter.
303 *
304 * @param msg message to print
305 */
306 public void printNotice(String msg) {
307 printNotice((DocTreePath)null, msg);
308 }
309
310 public void printNotice(DocTreePath path, String msg) {
311 String prefix = getDiagSource(path);
312 if (diagListener != null) {
313 report(DiagnosticType.NOTE, null, prefix + ": " + msg);
314 return;
315 }
316
317 if (path == null) {
318 noticeWriter.println(msg);
319 } else {
320 noticeWriter.println(prefix + ": " + msg);
321 }
322 noticeWriter.flush();
323 }
324
325 public void printNotice(Element e, String msg) {
326 String pos = getDiagSource(e);
327 if (diagListener != null) {
328 report(DiagnosticType.NOTE, pos, msg);
329 return;
330 }
331
332 if (e == null) {
333 noticeWriter.println(msg);
334 } else {
335 noticeWriter.println(pos + ": " + msg);
336 }
337 noticeWriter.flush();
338 }
339
340 /**
341 * Print error message, increment error count.
342 *
343 * @param key selects message from resource
344 */
345 public void error(Element e, String key, Object... args) {
346 printError(e, getText(key, args));
347 }
348
349 /**
350 * Print error message, increment error count.
351 *
352 * @param key selects message from resource
353 */
354 public void error(DocTreePath path, String key, Object... args) {
355 printError(path, getText(key, args));
356 }
357
358 public void error(String key, Object... args) {
359 printError((Element)null, getText(key, args));
360 }
361
362 public void warning(String key, Object... args) {
363 printWarning((Element)null, getText(key, args));
364 }
365
366 /**
367 * Print warning message, increment warning count.
368 *
369 * @param key selects message from resource
370 */
371 public void warning(Element e, String key, Object... args) {
372 printWarning(e, getText(key, args));
373 }
374
375 /**
376 * Print warning message, increment warning count.
377 *
378 * @param key selects message from resource
379 */
380 public void warning(DocTreePath path, String key, Object... args) {
381 printWarning(path, getText(key, args));
382 }
383
384 /**
385 * Print a message.
386 *
387 * @param key selects message from resource
388 */
389 public void notice(String key, Object... args) {
390 printNotice(getText(key, args));
391 }
392
393 /**
394 * Return total number of errors, including those recorded
395 * in the compilation log.
396 */
397 public int nerrors() { return nerrors; }
398
399 /**
400 * Return total number of warnings, including those recorded
401 * in the compilation log.
402 */
403 public int nwarnings() { return nwarnings; }
404
408 public void exitNotice() {
409 if (nerrors > 0) {
410 notice((nerrors > 1) ? "main.errors" : "main.error",
411 "" + nerrors);
412 }
413 if (nwarnings > 0) {
414 notice((nwarnings > 1) ? "main.warnings" : "main.warning",
415 "" + nwarnings);
416 }
417 }
418
419 /**
420 * Force program exit, e.g., from a fatal error.
421 * <p>
422 * TODO: This method does not really belong here.
423 */
424 public void exit() {
425 throw new ExitJavadoc();
426 }
427
428 private void report(DiagnosticType type, String pos, String msg) {
429 switch (type) {
430 case ERROR:
431 case WARNING:
432 Object prefix = (pos == null) ? programName : pos;
433 report(javadocDiags.create(type, null, null, "msg", prefix, msg));
434 break;
435
436 case NOTE:
437 String key = (pos == null) ? "msg" : "pos.msg";
438 report(javadocDiags.create(type, null, null, key, pos, msg));
439 break;
440
441 default:
442 throw new IllegalArgumentException(type.toString());
443 }
444 }
445 }
|