| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| package org.apache.ivy.util; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Stack; |
| |
| /** |
| * A {@link MessageLogger} implementation delegating the work to the current top logger on a stack. |
| * <p> |
| * When the logger stack is empty, it delegates the work to a default logger, which by default is |
| * the {@link Message#getDefaultLogger()}. |
| * </p> |
| * <p> |
| * {@link #pushLogger(MessageLogger)} should be called to delegate to a new logger, and |
| * {@link #popLogger()} should be called when the context of this logger is finished. |
| * </p> |
| */ |
| public class MessageLoggerEngine implements MessageLogger { |
| private final ThreadLocal<Stack<MessageLogger>> loggerStacks = new ThreadLocal<>(); |
| |
| private MessageLogger defaultLogger = null; |
| |
| private List<String> problems = new ArrayList<>(); |
| |
| private List<String> warns = new ArrayList<>(); |
| |
| private List<String> errors = new ArrayList<>(); |
| |
| private Stack<MessageLogger> getLoggerStack() { |
| Stack<MessageLogger> stack = loggerStacks.get(); |
| if (stack == null) { |
| stack = new Stack<>(); |
| loggerStacks.set(stack); |
| } |
| return stack; |
| } |
| |
| public MessageLoggerEngine() { |
| } |
| |
| /** |
| * Sets the logger used when the stack is empty. |
| * |
| * @param defaultLogger |
| * the logger to use when the stack is empty. |
| */ |
| public void setDefaultLogger(MessageLogger defaultLogger) { |
| this.defaultLogger = defaultLogger; |
| } |
| |
| /** |
| * Push a logger on the stack. |
| * |
| * @param logger |
| * the logger to push. Must not be <code>null</code>. |
| */ |
| public void pushLogger(MessageLogger logger) { |
| Checks.checkNotNull(logger, "logger"); |
| getLoggerStack().push(logger); |
| } |
| |
| /** |
| * Pops a logger from the logger stack. |
| * <p> |
| * Does nothing if the logger stack is empty |
| * </p> |
| */ |
| public void popLogger() { |
| if (!getLoggerStack().isEmpty()) { |
| getLoggerStack().pop(); |
| } |
| } |
| |
| /** |
| * Returns the current logger, or the default one if there is no logger in the stack |
| * |
| * @return the current logger, or the default one if there is no logger in the stack |
| */ |
| public MessageLogger peekLogger() { |
| if (getLoggerStack().isEmpty()) { |
| return getDefaultLogger(); |
| } |
| return getLoggerStack().peek(); |
| } |
| |
| private MessageLogger getDefaultLogger() { |
| // we don't store the logger returned by Message.getDefaultLogger() to always stay in sync |
| // as long as our default logger has not been set explicitly with setDefaultLogger() |
| return defaultLogger == null ? Message.getDefaultLogger() : defaultLogger; |
| } |
| |
| // consolidated methods |
| public void warn(String msg) { |
| peekLogger().warn(msg); |
| problems.add("WARN: " + msg); |
| warns.add(msg); |
| } |
| |
| public void error(String msg) { |
| peekLogger().error(msg); |
| problems.add("\tERROR: " + msg); |
| errors.add(msg); |
| } |
| |
| public List<String> getErrors() { |
| return errors; |
| } |
| |
| public List<String> getProblems() { |
| return problems; |
| } |
| |
| public List<String> getWarns() { |
| return warns; |
| } |
| |
| public void sumupProblems() { |
| MessageLoggerHelper.sumupProblems(this); |
| clearProblems(); |
| } |
| |
| public void clearProblems() { |
| getDefaultLogger().clearProblems(); |
| for (MessageLogger l : getLoggerStack()) { |
| l.clearProblems(); |
| } |
| problems.clear(); |
| errors.clear(); |
| warns.clear(); |
| } |
| |
| public void setShowProgress(boolean progress) { |
| getDefaultLogger().setShowProgress(progress); |
| // updates all loggers in the stack |
| for (MessageLogger l : getLoggerStack()) { |
| l.setShowProgress(progress); |
| } |
| } |
| |
| public boolean isShowProgress() { |
| // testing the default logger is enough, all loggers should be in sync |
| return getDefaultLogger().isShowProgress(); |
| } |
| |
| // delegation methods |
| |
| public void debug(String msg) { |
| peekLogger().debug(msg); |
| } |
| |
| public void deprecated(String msg) { |
| peekLogger().deprecated(msg); |
| } |
| |
| public void endProgress() { |
| peekLogger().endProgress(); |
| } |
| |
| public void endProgress(String msg) { |
| peekLogger().endProgress(msg); |
| } |
| |
| public void info(String msg) { |
| peekLogger().info(msg); |
| } |
| |
| public void rawinfo(String msg) { |
| peekLogger().rawinfo(msg); |
| } |
| |
| public void log(String msg, int level) { |
| peekLogger().log(msg, level); |
| } |
| |
| public void progress() { |
| peekLogger().progress(); |
| } |
| |
| public void rawlog(String msg, int level) { |
| peekLogger().rawlog(msg, level); |
| } |
| |
| public void verbose(String msg) { |
| peekLogger().verbose(msg); |
| } |
| |
| } |