Messager.java revision 3560:bbf4cfc235bd
1/*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
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
26package com.sun.tools.javadoc.main;
27
28import java.io.PrintWriter;
29import java.util.Locale;
30import java.util.ResourceBundle;
31
32import com.sun.javadoc.*;
33import com.sun.tools.javac.util.Context;
34import com.sun.tools.javac.util.JCDiagnostic;
35import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
36import com.sun.tools.javac.util.JavacMessages;
37import 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@Deprecated
56public class Messager extends Log implements DocErrorReporter {
57    public static final SourcePosition NOPOS = null;
58
59    /** Get the current messager, which is also the compiler log. */
60    public static Messager instance0(Context context) {
61        Log instance = context.get(logKey);
62        if (instance == null || !(instance instanceof Messager))
63            throw new InternalError("no messager instance!");
64        return (Messager)instance;
65    }
66
67    public static void preRegister(Context context,
68                                   final String programName) {
69        context.put(logKey, new Context.Factory<Log>() {
70            public Log make(Context c) {
71                return new Messager(c,
72                                    programName);
73            }
74        });
75    }
76    public static void preRegister(Context context,
77                                   final String programName,
78                                   final PrintWriter errWriter,
79                                   final PrintWriter warnWriter,
80                                   final PrintWriter noticeWriter) {
81        context.put(logKey, new Context.Factory<Log>() {
82            public Log make(Context c) {
83                return new Messager(c,
84                                    programName,
85                                    errWriter,
86                                    warnWriter,
87                                    noticeWriter);
88            }
89        });
90    }
91
92    public class ExitJavadoc extends Error {
93        private static final long serialVersionUID = 0;
94    }
95
96    final String programName;
97
98    private Locale locale;
99    private final JavacMessages messages;
100    private final JCDiagnostic.Factory javadocDiags;
101
102    /** The default writer for diagnostics
103     */
104    static final PrintWriter defaultErrWriter = new PrintWriter(System.err);
105    static final PrintWriter defaultWarnWriter = new PrintWriter(System.err);
106    static final PrintWriter defaultNoticeWriter = new PrintWriter(System.out);
107
108    /**
109     * Constructor
110     * @param programName  Name of the program (for error messages).
111     */
112    protected Messager(Context context, String programName) {
113        this(context, programName, defaultErrWriter, defaultWarnWriter, defaultNoticeWriter);
114    }
115
116    /**
117     * Constructor
118     * @param programName  Name of the program (for error messages).
119     * @param errWriter    Stream for error messages
120     * @param warnWriter   Stream for warnings
121     * @param noticeWriter Stream for other messages
122     */
123    @SuppressWarnings("deprecation")
124    protected Messager(Context context,
125                       String programName,
126                       PrintWriter errWriter,
127                       PrintWriter warnWriter,
128                       PrintWriter noticeWriter) {
129        super(context, errWriter, warnWriter, noticeWriter);
130        messages = JavacMessages.instance(context);
131        messages.add(locale -> ResourceBundle.getBundle("com.sun.tools.javadoc.resources.javadoc",
132                                                         locale));
133        javadocDiags = new JCDiagnostic.Factory(messages, "javadoc");
134        this.programName = programName;
135
136    }
137
138    public void setLocale(Locale locale) {
139        this.locale = locale;
140    }
141
142    /**
143     * get and format message string from resource
144     *
145     * @param key selects message from resource
146     * @param args arguments for the message
147     */
148    String getText(String key, Object... args) {
149        return messages.getLocalizedString(locale, key, args);
150    }
151
152    /**
153     * Print error message, increment error count.
154     * Part of DocErrorReporter.
155     *
156     * @param msg message to print
157     */
158    public void printError(String msg) {
159        printError(null, msg);
160    }
161
162    /**
163     * Print error message, increment error count.
164     * Part of DocErrorReporter.
165     *
166     * @param pos the position where the error occurs
167     * @param msg message to print
168     */
169    public void printError(SourcePosition pos, String msg) {
170        if (diagListener != null) {
171            report(DiagnosticType.ERROR, pos, msg);
172            return;
173        }
174
175        if (nerrors < MaxErrors) {
176            String prefix = (pos == null) ? programName : pos.toString();
177            PrintWriter errWriter = getWriter(WriterKind.ERROR);
178            errWriter.println(prefix + ": " + getText("javadoc.error") + " - " + msg);
179            errWriter.flush();
180            prompt();
181            nerrors++;
182        }
183    }
184
185    /**
186     * Print warning message, increment warning count.
187     * Part of DocErrorReporter.
188     *
189     * @param msg message to print
190     */
191    public void printWarning(String msg) {
192        printWarning(null, msg);
193    }
194
195    /**
196     * Print warning message, increment warning count.
197     * Part of DocErrorReporter.
198     *
199     * @param pos the position where the error occurs
200     * @param msg message to print
201     */
202    public void printWarning(SourcePosition pos, String msg) {
203        if (diagListener != null) {
204            report(DiagnosticType.WARNING, pos, msg);
205            return;
206        }
207
208        if (nwarnings < MaxWarnings) {
209            String prefix = (pos == null) ? programName : pos.toString();
210            PrintWriter warnWriter = getWriter(WriterKind.WARNING);
211            warnWriter.println(prefix +  ": " + getText("javadoc.warning") +" - " + msg);
212            warnWriter.flush();
213            nwarnings++;
214        }
215    }
216
217    /**
218     * Print a message.
219     * Part of DocErrorReporter.
220     *
221     * @param msg message to print
222     */
223    public void printNotice(String msg) {
224        printNotice(null, msg);
225    }
226
227    /**
228     * Print a message.
229     * Part of DocErrorReporter.
230     *
231     * @param pos the position where the error occurs
232     * @param msg message to print
233     */
234    public void printNotice(SourcePosition pos, String msg) {
235        if (diagListener != null) {
236            report(DiagnosticType.NOTE, pos, msg);
237            return;
238        }
239
240        PrintWriter noticeWriter = getWriter(WriterKind.NOTICE);
241        if (pos == null)
242            noticeWriter.println(msg);
243        else
244            noticeWriter.println(pos + ": " + msg);
245        noticeWriter.flush();
246    }
247
248    /**
249     * Print error message, increment error count.
250     *
251     * @param key selects message from resource
252     */
253    public void error(SourcePosition pos, String key, Object... args) {
254        printError(pos, getText(key, args));
255    }
256
257    /**
258     * Print warning message, increment warning count.
259     *
260     * @param key selects message from resource
261     */
262    public void warning(SourcePosition pos, String key, Object... args) {
263        printWarning(pos, getText(key, args));
264    }
265
266    /**
267     * Print a message.
268     *
269     * @param key selects message from resource
270     */
271    public void notice(String key, Object... args) {
272        printNotice(getText(key, args));
273    }
274
275    /**
276     * Return total number of errors, including those recorded
277     * in the compilation log.
278     */
279    public int nerrors() { return nerrors; }
280
281    /**
282     * Return total number of warnings, including those recorded
283     * in the compilation log.
284     */
285    public int nwarnings() { return nwarnings; }
286
287    /**
288     * Print exit message.
289     */
290    public void exitNotice() {
291        if (nerrors > 0) {
292            notice((nerrors > 1) ? "main.errors" : "main.error",
293                   "" + nerrors);
294        }
295        if (nwarnings > 0) {
296            notice((nwarnings > 1) ?  "main.warnings" : "main.warning",
297                   "" + nwarnings);
298        }
299    }
300
301    /**
302     * Force program exit, e.g., from a fatal error.
303     * <p>
304     * TODO: This method does not really belong here.
305     */
306    public void exit() {
307        throw new ExitJavadoc();
308    }
309
310    private void report(DiagnosticType type, SourcePosition pos, String msg) {
311        switch (type) {
312            case ERROR:
313            case WARNING:
314                Object prefix = (pos == null) ? programName : pos;
315                report(javadocDiags.create(type, null, null, "msg", prefix, msg));
316                break;
317
318            case NOTE:
319                String key = (pos == null) ? "msg" : "pos.msg";
320                report(javadocDiags.create(type, null, null, key, pos, msg));
321                break;
322
323            default:
324                throw new IllegalArgumentException(type.toString());
325        }
326    }
327}
328