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;
27 import org.apache.commons.lang3.StringUtils;
28 import org.apache.commons.text.StrBuilder;
29 import org.slf4j.ext.XLoggerFactory;
30 import org.slf4j.helpers.MessageFormatter;
33 * A console for printing messages with functionality similar to loggers. The class provides a static instance for all
34 * parts of an application. The default configuration is to not collect errors or warnings. The default types being
35 * activated are errors, warnings, and info messages.
37 * @author Sven van der Meer (sven.van.der.meer@ericsson.com)
39 public final class Console {
40 /** The console as static object. */
41 public static final Console CONSOLE = new Console();
43 /** Type for a quiet console, no messages being printed. */
44 public static final int TYPE_QUIET = 0;
46 /** Type for printing error messages. */
47 public static final int TYPE_ERROR = 0b0001;
49 /** Type for printing warning messages. */
50 public static final int TYPE_WARNING = 0b0010;
52 /** Type for printing information messages. */
53 public static final int TYPE_INFO = 0b0100;
55 /** Type for printing progress messages. */
56 public static final int TYPE_PROGRESS = 0b1000;
58 /** Type for printing debug messages. */
59 public static final int TYPE_DEBUG = 0b001_0000;
61 /** Type for printing trace messages. */
62 public static final int TYPE_TRACE = 0b010_0000;
64 /** Type for printing stack traces of caught exceptions. */
65 public static final int TYPE_STACKTRACE = 0b110_0000;
67 /** Type for a verbose console, activating all message types. */
68 public static final int TYPE_VERBOSE = 0b111_1111;
70 /** Configuration for a collecting error messages. */
71 public static final int CONFIG_COLLECT_ERRORS = 0b0001;
73 /** Configuration for a collecting warning messages. */
74 public static final int CONFIG_COLLECT_WARNINGS = 0b0010;
76 // Input and output streams
77 private static final PrintStream ERR_STREAM = System.err;
79 /** The setting for message types, set using type flags. */
82 /** The console configuration, set using configuration flags. */
83 private int configuration;
85 /** A name for the application, if set used as prefix for messages. */
86 private String appName;
88 /** The list of errors, filled if error collection is activates. */
89 private final List<String> errors;
91 /** The list of warnings, filled if warning collection is activates. */
92 private final List<String> warnings;
95 * Creates a new console. The constructor is private since the class provides static access to an instance. The
96 * default for types is verbose.
102 errors = new ArrayList<>();
103 warnings = new ArrayList<>();
107 * Sets the application name.
109 * @param appName new application name, use <code>null</code> to reset the application name, a non-blank string for
110 * a new name, blank strings are ignored
112 public void setAppName(final String appName) {
113 if (appName == null) {
115 } else if (!StringUtils.isBlank(appName)) {
116 this.appName = appName;
121 * Returns the application name.
123 * @return application name, null if not set, non-blank string otherwise
125 public String getAppName() {
132 * @param type the type to activate
134 public void activate(final int type) {
135 types = types | type;
139 * Deactivates a type.
141 * @param type type to deactivate
143 public void deActivate(final int type) {
144 types = types & ~type;
148 * Sets the type to the given type, effectively deactivating all other types.
150 * @param type new type
152 public void set(final int type) {
157 * Sets the type to the given types, effectively deactivating all other types.
159 * @param ts array of types to set
161 public void set(final int... ts) {
163 for (final int type : ts) {
169 * Configures the console. Use the configuration flags in combination for the required configuration. For instance,
170 * to collect errors and warnings use <code>CONFIG_COLLECT_ERRORS | CONFIG_COLLECT_WARNINGS</code>.
172 * @param config the new configuration, overwrites the current configuration, 0 deactivates all settings
174 public void configure(final int config) {
175 this.configuration = config;
179 * Prints an error message with message and objects if {@link #TYPE_ERROR} is set; and increases the error count.
180 * Errors are collected (if configuration is set) and the error counter is increased regardless of the console error
183 * @param message the error message, using the same format as the SLF4J MessageFormatter, nothing done if
185 * @param objects the objects for substitution in the message
187 public void error(final String message, final Object... objects) {
188 if (StringUtils.isBlank(message)) {
192 final StrBuilder err = new StrBuilder();
193 if (appName != null) {
194 err.append(this.getAppName()).append(": ");
196 err.append("error: ");
197 err.append(MessageFormatter.arrayFormat(message, objects).getMessage());
199 if ((types & TYPE_ERROR) == TYPE_ERROR) {
200 ERR_STREAM.println(err.build());
202 if ((configuration & CONFIG_COLLECT_ERRORS) == CONFIG_COLLECT_ERRORS) {
203 errors.add(err.build());
208 * Prints a warning message with message and objects if {@link #TYPE_WARNING} is set; and increases the warning
209 * count. Warnings are collected (if configuration is set) and the warning counter is increased regardless of the
210 * console warning type settings.
212 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
214 * @param objects the objects for substitution in the message
216 public void warn(final String message, final Object... objects) {
217 if (StringUtils.isBlank(message)) {
221 final StrBuilder warn = new StrBuilder();
222 if (appName != null) {
223 warn.append(this.getAppName()).append(": ");
225 warn.append("warning: ");
226 warn.append(MessageFormatter.arrayFormat(message, objects).getMessage());
228 if ((types & TYPE_WARNING) == TYPE_WARNING) {
229 ERR_STREAM.println(warn.build());
231 if ((configuration & CONFIG_COLLECT_WARNINGS) == CONFIG_COLLECT_WARNINGS) {
232 warnings.add(warn.build());
237 * Prints an info message with message and objects if {@link #TYPE_INFO} is set.
239 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
241 * @param objects the objects for substitution in the message
243 public void info(final String message, final Object... objects) {
244 if (StringUtils.isBlank(message)) {
248 if ((types & TYPE_INFO) == TYPE_INFO) {
249 if (appName != null) {
250 ERR_STREAM.print(appName + ": ");
252 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
257 * Prints a progress message with message and objects if {@link #TYPE_PROGRESS} is set.
259 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
261 * @param objects the objects for substitution in the message
263 public void progress(final String message, final Object... objects) {
264 if (StringUtils.isBlank(message)) {
268 if ((types & TYPE_PROGRESS) == TYPE_PROGRESS) {
269 if (appName != null) {
270 ERR_STREAM.print(appName + ": ");
272 ERR_STREAM.print("progress: ");
273 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
278 * Prints a debug message with message and objects if {@link #TYPE_DEBUG} is set.
280 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
282 * @param objects the objects for substitution in the message
284 public void debug(final String message, final Object... objects) {
285 if (StringUtils.isBlank(message)) {
289 if ((types & TYPE_DEBUG) == TYPE_DEBUG) {
290 if (appName != null) {
291 ERR_STREAM.print(appName + ": ");
293 ERR_STREAM.print("debug: ");
294 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
299 * Prints a trace message with message and objects if {@link #TYPE_TRACE} is set.
301 * @param message the warning message, using the same format as the SLF4J MessageFormatter, nothing done if
303 * @param objects the objects for substitution in the message
305 public void trace(final String message, final Object... objects) {
306 if (StringUtils.isBlank(message)) {
310 if ((types & TYPE_TRACE) == TYPE_TRACE) {
311 if (appName != null) {
312 ERR_STREAM.print(appName + ": ");
314 ERR_STREAM.print("trace: ");
315 ERR_STREAM.println(MessageFormatter.arrayFormat(message, objects).getMessage());
320 * Prints message, cause, and stack trace for a given exception if {@link #TYPE_STACKTRACE} is set.
322 * @param exception the exception to print, ignored if <code>null</code>
324 public void stacktrace(final Exception exception) {
325 if (exception == null) {
329 if ((types & TYPE_STACKTRACE) == TYPE_STACKTRACE) {
330 if (appName != null) {
331 ERR_STREAM.print(appName + ": ");
333 ERR_STREAM.println(" exception message: " + exception.getMessage());
334 if (exception.getCause() != null) {
335 ERR_STREAM.println(" exception cause: " + exception.getCause());
337 ERR_STREAM.println("for exception stack trace, please refer logs.");
338 XLoggerFactory.getXLogger(Console.class).error("stacktrace", exception);
343 * Resets the error counter and the list of errors.
345 public void resetErrors() {
350 * Resets the warning counter and the list of warnings.
352 public void resetWarnings() {