2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.tools.common;
23 import java.io.PrintStream;
24 import java.util.ArrayList;
25 import java.util.List;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.text.StrBuilder;
28 import org.slf4j.ext.XLoggerFactory;
29 import org.slf4j.helpers.MessageFormatter;
32 * A console for printing messages with functionality similar to loggers. The class provides a static instance for all
33 * parts of an application. The default configuration is to not collect errors or warnings. The default types being
34 * activated are errors, warnings, and info messages.
36 * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
38 public final class Console {
39 /** The console as static object. */
40 public static final Console CONSOLE = new Console();
42 /** Type for a quiet console, no messages being printed. */
43 public static final int TYPE_QUIET = 0;
45 /** Type for printing error messages. */
46 public static final int TYPE_ERROR = 0b0001;
48 /** Type for printing warning messages. */
49 public static final int TYPE_WARNING = 0b0010;
51 /** Type for printing information messages. */
52 public static final int TYPE_INFO = 0b0100;
54 /** Type for printing progress messages. */
55 public static final int TYPE_PROGRESS = 0b1000;
57 /** Type for printing debug messages. */
58 public static final int TYPE_DEBUG = 0b001_0000;
60 /** Type for printing trace messages. */
61 public static final int TYPE_TRACE = 0b010_0000;
63 /** Type for printing stack traces of caught exceptions. */
64 public static final int TYPE_STACKTRACE = 0b110_0000;
66 /** Type for a verbose console, activating all message types. */
67 public static final int TYPE_VERBOSE = 0b111_1111;
69 /** Configuration for a collecting error messages. */
70 public static final int CONFIG_COLLECT_ERRORS = 0b0001;
72 /** Configuration for a collecting warning messages. */
73 public static final int CONFIG_COLLECT_WARNINGS = 0b0010;
75 // Input and output streams
76 private static final PrintStream ERR_STREAM = System.err;
78 /** The setting for message types, set using type flags. */
81 /** The console configuration, set using configuration flags. */
82 private int configuration;
84 /** A name for the application, if set used as prefix for messages. */
85 private String appName;
87 /** The list of errors, filled if error collection is activates. */
88 private final List<String> errors;
90 /** The list of warnings, filled if warning collection is activates. */
91 private final List<String> warnings;
94 * Creates a new console. The constructor is private since the class provides static access to an instance. The
95 * default for types is verbose.
101 errors = new ArrayList<>();
102 warnings = new ArrayList<>();
106 * Sets the application name.
108 * @param appName new application name, use <code>null</code> to reset the application name, a non-blank string for
109 * a new name, blank strings are ignored
111 public void setAppName(final String appName) {
112 if (appName == null) {
114 } else if (!StringUtils.isBlank(appName)) {
115 this.appName = appName;
120 * Returns the application name.
122 * @return application name, null if not set, non-blank string otherwise
124 public String getAppName() {
131 * @param type the type to activate
133 public void activate(final int type) {
134 types = types | type;
138 * Deactivates a type.
140 * @param type type to deactivate
142 public void deActivate(final int type) {
143 types = types & ~type;
147 * Sets the type to the given type, effectively deactivating all other types.
149 * @param type new type
151 public void set(final int type) {
156 * Sets the type to the given types, effectively deactivating all other types.
158 * @param ts array of types to set
160 public void set(final int... ts) {
162 for (final int type : ts) {
168 * Configures the console. Use the configuration flags in combination for the required configuration. For instance,
169 * to collect errors and warnings use <code>CONFIG_COLLECT_ERRORS | CONFIG_COLLECT_WARNINGS</code>.
171 * @param config the new configuration, overwrites the current configuration, 0 deactivates all settings
173 public void configure(final int config) {
174 this.configuration = config;
178 * Prints an error message with message and objects if {@link #TYPE_ERROR} is set; and increases the error count.
179 * Errors are collected (if configuration is set) and the error counter is increased regardless of the console error
182 * @param message the error message, using the same format as the SLF4J MessageFormatter, nothing done if
184 * @param objects the objects for substitution in the message
186 public void error(final String message, final Object... objects) {
187 if (StringUtils.isBlank(message)) {
191 final StrBuilder err = new StrBuilder();
192 if (appName != null) {
193 err.append(this.getAppName()).append(": ");
195 err.append("error: ");
196 err.append(MessageFormatter.arrayFormat(message, objects).getMessage());
198 if ((types & TYPE_ERROR) == TYPE_ERROR) {
199 ERR_STREAM.println(err.build());
201 if ((configuration & CONFIG_COLLECT_ERRORS) == CONFIG_COLLECT_ERRORS) {
202 errors.add(err.build());
207 * Prints a warning message with message and objects if {@link #TYPE_WARNING} is set; and increases the warning
208 * count. Warnings are collected (if configuration is set) and the warning counter is increased regardless of the
209 * console warning type settings.
211 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
213 * @param objects the objects for substitution in the message
215 public void warn(final String message, final Object... objects) {
216 if (StringUtils.isBlank(message)) {
220 final StrBuilder warn = new StrBuilder();
221 if (appName != null) {
222 warn.append(this.getAppName()).append(": ");
224 warn.append("warning: ");
225 warn.append(MessageFormatter.arrayFormat(message, objects).getMessage());
227 if ((types & TYPE_WARNING) == TYPE_WARNING) {
228 ERR_STREAM.println(warn.build());
230 if ((configuration & CONFIG_COLLECT_WARNINGS) == CONFIG_COLLECT_WARNINGS) {
231 warnings.add(warn.build());
236 * Prints an info message with message and objects if {@link #TYPE_INFO} is set.
238 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
240 * @param objects the objects for substitution in the message
242 public void info(final String message, final Object... objects) {
243 if (StringUtils.isBlank(message)) {
247 if ((types & TYPE_INFO) == TYPE_INFO) {
248 if (appName != null) {
249 ERR_STREAM.print(appName + ": ");
251 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
256 * Prints a progress message with message and objects if {@link #TYPE_PROGRESS} is set.
258 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
260 * @param objects the objects for substitution in the message
262 public void progress(final String message, final Object... objects) {
263 if (StringUtils.isBlank(message)) {
267 if ((types & TYPE_PROGRESS) == TYPE_PROGRESS) {
268 if (appName != null) {
269 ERR_STREAM.print(appName + ": ");
271 ERR_STREAM.print("progress: ");
272 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
277 * Prints a debug message with message and objects if {@link #TYPE_DEBUG} is set.
279 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
281 * @param objects the objects for substitution in the message
283 public void debug(final String message, final Object... objects) {
284 if (StringUtils.isBlank(message)) {
288 if ((types & TYPE_DEBUG) == TYPE_DEBUG) {
289 if (appName != null) {
290 ERR_STREAM.print(appName + ": ");
292 ERR_STREAM.print("debug: ");
293 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
298 * Prints a trace message with message and objects if {@link #TYPE_TRACE} is set.
300 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
302 * @param objects the objects for substitution in the message
304 public void trace(final String message, final Object... objects) {
305 if (StringUtils.isBlank(message)) {
309 if ((types & TYPE_TRACE) == TYPE_TRACE) {
310 if (appName != null) {
311 ERR_STREAM.print(appName + ": ");
313 ERR_STREAM.print("trace: ");
314 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
319 * Prints message, cause, and stack trace for a given exception if {@link #TYPE_STACKTRACE} is set.
321 * @param exception the exception to print, ignored if <code>null</code>
323 public void stacktrace(final Exception exception) {
324 if (exception == null) {
328 if ((types & TYPE_STACKTRACE) == TYPE_STACKTRACE) {
329 if (appName != null) {
330 ERR_STREAM.print(appName + ": ");
332 ERR_STREAM.println(" exception message: " + exception.getMessage());
333 if (exception.getCause() != null) {
334 ERR_STREAM.println(" exception cause: " + exception.getCause());
336 ERR_STREAM.println("for exception stack trace, please refer logs.");
337 XLoggerFactory.getXLogger(Console.class).error("stacktrace", exception);
342 * Resets the error counter and the list of errors.
344 public void resetErrors() {
349 * Resets the warning counter and the list of warnings.
351 public void resetWarnings() {