Thu, 10 Oct 2013 16:16:20 +0200
8026250: Logging nullpointer bugfix and javadoc warnings
Reviewed-by: hannesw, jlaskey, sundar
1 /*
2 * Copyright (c) 2010, 2013, 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 */
26 package jdk.nashorn.internal.runtime;
28 import java.io.PrintWriter;
29 import java.util.logging.Level;
30 import java.util.logging.Logger;
31 import jdk.nashorn.internal.runtime.options.Options;
33 /**
34 * Wrapper class for Logging system. This is how you are supposed to register a logger and use it
35 */
37 public final class DebugLogger {
38 private final Logger logger;
39 private final boolean isEnabled;
41 private int indent;
43 private static final int INDENT_SPACE = 4;
45 /**
46 * Constructor
47 *
48 * @param loggerName name of logger - this is the unique key with which it can be identified
49 */
50 public DebugLogger(final String loggerName) {
51 this(loggerName, null);
52 }
54 /**
55 * Constructor
56 *
57 * A logger can be paired with a property, e.g. {@code --log:codegen:info} is equivalent to {@code -Dnashorn.codegen.log}
58 *
59 * @param loggerName name of logger - this is the unique key with which it can be identified
60 * @param property system property activating the logger on {@code info} level
61 */
62 public DebugLogger(final String loggerName, final String property) {
63 if (property != null && Options.getBooleanProperty(property)) {
64 this.logger = Logging.getOrCreateLogger(loggerName, Level.INFO);
65 } else {
66 this.logger = Logging.getLogger(loggerName);
67 }
68 assert logger != null;
69 this.isEnabled = getLevel() != Level.OFF;
70 }
72 /**
73 * Do not currently support chaining this with parent logger. Logger level null
74 * means disabled
75 * @return level
76 */
77 private Level getLevel() {
78 return logger.getLevel() == null ? Level.OFF : logger.getLevel();
79 }
81 /**
82 * Get the output writer for the logger. Loggers always default to
83 * stderr for output as they are used mainly to output debug info
84 *
85 * Can be inherited so this should not be static.
86 *
87 * @return print writer for log output.
88 */
89 @SuppressWarnings("static-method")
90 public PrintWriter getOutputStream() {
91 return Context.getCurrentErr();
92 }
94 /**
95 * Check if the logger is enabled
96 * @return true if enabled
97 */
98 public boolean isEnabled() {
99 return isEnabled;
100 }
102 /**
103 * If you want to change the indent level of your logger, call indent with a new position.
104 * Positions start at 0 and are increased by one for a new "tab"
105 *
106 * @param pos indent position
107 */
108 public void indent(final int pos) {
109 if (isEnabled) {
110 indent += pos * INDENT_SPACE;
111 }
112 }
114 /**
115 * Add an indent position
116 */
117 public void indent() {
118 indent += INDENT_SPACE;
119 }
121 /**
122 * Unindent a position
123 */
124 public void unindent() {
125 indent -= INDENT_SPACE;
126 if (indent < 0) {
127 indent = 0;
128 }
129 }
131 /**
132 * Check if the logger is above of the level of detail given
133 * @see java.util.logging.Level
134 *
135 * @param level logging level
136 * @return true if level is above the given one
137 */
138 public boolean levelAbove(final Level level) {
139 return getLevel().intValue() > level.intValue();
140 }
142 /**
143 * Shorthand for outputting a log string as log level {@link java.util.logging.Level#FINEST} on this logger
144 * @param str the string to log
145 */
146 public void finest(final String str) {
147 log(Level.FINEST, str);
148 }
150 /**
151 * Shorthand for outputting a log string as log level
152 * {@link java.util.logging.Level#FINEST} on this logger
153 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
154 */
155 public void finest(final Object... objs) {
156 log(Level.FINEST, objs);
157 }
159 /**
160 * Shorthand for outputting a log string as log level
161 * {@link java.util.logging.Level#FINER} on this logger
162 * @param str the string to log
163 */
164 public void finer(final String str) {
165 log(Level.FINER, str);
166 }
168 /**
169 * Shorthand for outputting a log string as log level
170 * {@link java.util.logging.Level#FINER} on this logger
171 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
172 */
173 public void finer(final Object... objs) {
174 log(Level.FINER, objs);
175 }
177 /**
178 * Shorthand for outputting a log string as log level
179 * {@link java.util.logging.Level#FINE} on this logger
180 * @param str the string to log
181 */
182 public void fine(final String str) {
183 log(Level.FINE, str);
184 }
186 /**
187 * Shorthand for outputting a log string as log level
188 * {@link java.util.logging.Level#FINE} on this logger
189 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
190 */
191 public void fine(final Object... objs) {
192 log(Level.FINE, objs);
193 }
195 /**
196 * Shorthand for outputting a log string as log level
197 * {@link java.util.logging.Level#CONFIG} on this logger
198 * @param str the string to log
199 */
200 public void config(final String str) {
201 log(Level.CONFIG, str);
202 }
204 /**
205 * Shorthand for outputting a log string as log level
206 * {@link java.util.logging.Level#CONFIG} on this logger
207 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
208 */
209 public void config(final Object... objs) {
210 log(Level.CONFIG, objs);
211 }
213 /**
214 * Shorthand for outputting a log string as log level
215 * {@link java.util.logging.Level#INFO} on this logger
216 * @param str the string to log
217 */
218 public void info(final String str) {
219 log(Level.INFO, str);
220 }
222 /**
223 * Shorthand for outputting a log string as log level
224 * {@link java.util.logging.Level#FINE} on this logger
225 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
226 */
227 public void info(final Object... objs) {
228 log(Level.INFO, objs);
229 }
231 /**
232 * Shorthand for outputting a log string as log level
233 * {@link java.util.logging.Level#WARNING} on this logger
234 * @param str the string to log
235 */
236 public void warning(final String str) {
237 log(Level.WARNING, str);
238 }
240 /**
241 * Shorthand for outputting a log string as log level
242 * {@link java.util.logging.Level#FINE} on this logger
243 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
244 */
245 public void warning(final Object... objs) {
246 log(Level.WARNING, objs);
247 }
249 /**
250 * Shorthand for outputting a log string as log level
251 * {@link java.util.logging.Level#SEVERE} on this logger
252 * @param str the string to log
253 */
254 public void severe(final String str) {
255 log(Level.SEVERE, str);
256 }
258 /**
259 * Shorthand for outputting a log string as log level
260 * {@link java.util.logging.Level#FINE} on this logger
261 * @param objs object array to log - use this to perform lazy concatenation to avoid unconditional toString overhead
262 */
263 public void severe(final Object... objs) {
264 log(Level.SEVERE, objs);
265 }
267 /**
268 * Output log line on this logger at a given level of verbosity
269 * @see java.util.logging.Level
270 *
271 * @param level minimum log level required for logging to take place
272 * @param str string to log
273 */
274 public void log(final Level level, final String str) {
275 if (isEnabled) {
276 final StringBuilder sb = new StringBuilder();
277 for (int i = 0 ; i < indent ; i++) {
278 sb.append(' ');
279 }
280 sb.append(str);
281 logger.log(level, sb.toString());
282 }
283 }
285 /**
286 * Output log line on this logger at a given level of verbosity
287 * @see java.util.logging.Level
288 *
289 * @param level minimum log level required for logging to take place
290 * @param objs objects for which to invoke toString and concatenate to log
291 */
292 public void log(final Level level, final Object... objs) {
293 if (isEnabled) {
294 final StringBuilder sb = new StringBuilder();
295 for (int i = 0 ; i < indent ; i++) {
296 sb.append(' ');
297 }
298 for (final Object obj : objs) {
299 sb.append(obj);
300 }
301 logger.log(level, sb.toString());
302 }
303 }
304 }