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