package org.codehaus.mojo.jaxb2; import org.apache.maven.plugin.logging.Log; import org.codehaus.mojo.jaxb2.shared.Validate; import java.text.NumberFormat; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; /** * Trivial Maven Log implementation which stores all logged messages * within a SortedMap for later retrieval. * * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a>, jGuru Europe AB */ public class BufferingLog implements Log { public enum LogLevel { DEBUG, INFO, WARN, ERROR, NONE } // Internal state private static final NumberFormat INTEGER_FORMAT = NumberFormat.getIntegerInstance(); private LogLevel minLevel; private final Object lock = new Object(); private SortedMap<String, Throwable> logBuffer; static { setMinimumIntegerDigits(3); } public BufferingLog() { this(LogLevel.INFO); } public BufferingLog(final LogLevel minLevel) { // Check sanity Validate.notNull(minLevel, "minLevel"); // Assign internal state logBuffer = new TreeMap<String, Throwable>(); this.minLevel = minLevel; } /** * @return The minimum LogLevel for which this BufferingLog will record log events. */ public LogLevel getMinimumLogLevel() { return minLevel; } /** * @return The LogBuffer holding all log messages, and their corresponding (optional) Throwable. */ public SortedMap<String, Throwable> getLogBuffer() { return logBuffer; } /** * Retrieves the current LogBuffer, and resets the internal state of this BufferingLog. * * @return The LogBuffer holding all log messages, and their corresponding (optional) Throwable. */ public SortedMap<String, Throwable> getAndResetLogBuffer() { final SortedMap<String, Throwable> toReturn = logBuffer; synchronized (lock) { this.logBuffer = new TreeMap<String, Throwable>(); } return toReturn; } /** * Assigns the minimum number of Integer digits in the Log format. * * @param minimumIntegerDigits the minimum number of Integer digits in the Log format. */ public static void setMinimumIntegerDigits(final int minimumIntegerDigits) { INTEGER_FORMAT.setMinimumIntegerDigits(minimumIntegerDigits); } /** * @return A Pretty-printed version of the log buffer. */ public String getPrettyPrintedLog() { final StringBuilder builder = new StringBuilder(); for (Map.Entry<String, Throwable> current : logBuffer.entrySet()) { builder.append("\n").append(current.getKey()); final Throwable error = current.getValue(); if (error != null) { builder.append(" [" + error.getMessage() + "]: " + error.getClass().getSimpleName()); } } // All done. return builder.toString(); } /** * {@inheritDoc} */ public void debug(CharSequence content, Throwable error) { addLogEntry(LogLevel.DEBUG, content, error); } /** * {@inheritDoc} */ public void debug(CharSequence content) { debug(content, null); } /** * {@inheritDoc} */ public void debug(Throwable error) { debug("", error); } /** * {@inheritDoc} */ public void info(CharSequence content, Throwable error) { addLogEntry(LogLevel.INFO, content, error); } /** * {@inheritDoc} */ public void info(CharSequence content) { info(content, null); } /** * {@inheritDoc} */ public void info(Throwable error) { info("", error); } /** * {@inheritDoc} */ public void warn(CharSequence content, Throwable error) { addLogEntry(LogLevel.WARN, content, error); } /** * {@inheritDoc} */ public void warn(CharSequence content) { warn(content, null); } /** * {@inheritDoc} */ public void warn(Throwable error) { warn("", error); } /** * {@inheritDoc} */ public void error(final CharSequence content, final Throwable error) { addLogEntry(LogLevel.ERROR, content, error); } /** * {@inheritDoc} */ public void error(CharSequence content) { error(content, null); } /** * {@inheritDoc} */ public void error(final Throwable error) { error("", error); } /** * {@inheritDoc} */ public boolean isDebugEnabled() { return isLogEnabledFor(LogLevel.DEBUG); } /** * {@inheritDoc} */ public boolean isInfoEnabled() { return isLogEnabledFor(LogLevel.INFO); } /** * {@inheritDoc} */ public boolean isWarnEnabled() { return isLogEnabledFor(LogLevel.WARN); } /** * {@inheritDoc} */ public boolean isErrorEnabled() { return isLogEnabledFor(LogLevel.ERROR); } // // Private helpers // private void addLogEntry(final LogLevel level, final CharSequence message, final Throwable throwable) { synchronized (lock) { if (isLogEnabledFor(level)) { final int index = logBuffer.size(); final String logMessage = "" + INTEGER_FORMAT.format(index) + ": (" + level + ") " + message; logBuffer.put(logMessage, throwable); } } } private boolean isLogEnabledFor(final LogLevel level) { return level.compareTo(minLevel) >= 0; } }