com.gargoylesoftware.htmlunit.WebConsole.java Source code

Java tutorial

Introduction

Here is the source code for com.gargoylesoftware.htmlunit.WebConsole.java

Source

/*
 * Copyright (c) 2002-2016 Gargoyle Software Inc.
 *
 * Licensed 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
 * http://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 com.gargoylesoftware.htmlunit;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class can be used to print messages to the logger. The first parameter
 * can be a message-object containing format specifiers such as ("%o", "%s",
 * "%d", "%i", "%f"). The logging methods are null-safe, so if the number of
 * format specifiers and the numbers of parameters don't match, no exception is thrown.
 *
 * The default logger uses Apache Commons Logging.
 *
 * @author Andrea Martino
 */
public class WebConsole {

    /**
     * A simple logging interface abstracting logging APIs.
     */
    public interface Logger {

        /**
         * Is trace logging currently enabled?
         * <p>
         * Call this method to prevent having to perform expensive operations
         * (for example, <code>String</code> concatenation)
         * when the log level is more than trace.
         *
         * @return true if trace is enabled in the underlying logger.
         */
        boolean isTraceEnabled();

        /**
         * Logs a message with trace log level.
         *
         * @param message log this message
         */
        void trace(final Object message);

        /**
         * Is debug logging currently enabled?
         * <p>
         * Call this method to prevent having to perform expensive operations
         * (for example, <code>String</code> concatenation)
         * when the log level is more than debug.
         *
         * @return true if debug is enabled in the underlying logger.
         */
        boolean isDebugEnabled();

        /**
         * Logs a message with debug log level.
         *
         * @param message log this message
         */
        void debug(final Object message);

        /**
         * Is info logging currently enabled?
         * <p>
         * Call this method to prevent having to perform expensive operations
         * (for example, <code>String</code> concatenation)
         * when the log level is more than info.
         *
         * @return true if info is enabled in the underlying logger.
         */
        boolean isInfoEnabled();

        /**
         * Logs a message with info log level.
         *
         * @param message log this message
         */
        void info(final Object message);

        /**
         * Is warn logging currently enabled?
         * <p>
         * Call this method to prevent having to perform expensive operations
         * (for example, <code>String</code> concatenation)
         * when the log level is more than warn.
         *
         * @return true if warn is enabled in the underlying logger.
         */
        boolean isWarnEnabled();

        /**
         * Logs a message with warn log level.
         *
         * @param message log this message
         */
        void warn(final Object message);

        /**
         * Is error logging currently enabled?
         * <p>
         * Call this method to prevent having to perform expensive operations
         * (for example, <code>String</code> concatenation)
         * when the log level is more than error.
         *
         * @return true if error is enabled in the underlying logger.
         */
        boolean isErrorEnabled();

        /**
         * Logs a message with error log level.
         *
         * @param message log this message
         */
        void error(final Object message);
    }

    /**
     * This interface can be implemented by clients that want to customize
     * the way parameters and objects are logged.
     */
    public interface Formatter {
        /**
         * Function that is used to print an object to the console.
         * @param o object to be printed
         * @return a string representation of the passed object
         */
        String printObject(Object o);

        /**
         * Function that is used to print an object as string using
         * format specifiers.
         * @param o object to be printed using string format specifiers
         * @return a string representation of the passed object
         */
        String parameterAsString(Object o);

        /**
         * Function that is used to print an object as integer using
         * format specifiers.
         * @param o object to be printed using integer format specifiers
         * @return a string representation of the passed object
         */
        String parameterAsInteger(Object o);

        /**
         * Function that is used to print an object as float using
         * format specifiers.
         * @param o object to be printed using float format specifiers
         * @return a string representation of the passed object
         */
        String parameterAsFloat(Object o);
    }

    private Formatter formatter_ = new DefaultFormatter();
    private Logger logger_ = new DefaultLogger();

    /**
     * Sets the Formatter.
     * @param formatter the formatter
     */
    public void setFormatter(final Formatter formatter) {
        formatter_ = formatter;
    }

    /**
     * Returns the current Formatter.
     * @return the Formatter
     */
    public Formatter getFormatter() {
        return formatter_;
    }

    /**
     * Sets the Logger_.
     * @param logger the logger
     */
    public void setLogger(final Logger logger) {
        logger_ = logger;
    }

    /**
     * Returns the current Logger.
     * @return the logger
     */
    public Logger getLogger() {
        return logger_;
    }

    /**
     * Prints the passed objects using logger trace level.
     * @param args the logging parameters
     */
    public void trace(final Object... args) {
        if (logger_.isTraceEnabled()) {
            logger_.trace(process(args));
        }
    }

    /**
     * Prints the passed objects using logger debug level.
     * @param args the logging parameters
     */
    public void debug(final Object... args) {
        if (logger_.isDebugEnabled()) {
            logger_.debug(process(args));
        }
    }

    /**
     * Prints the passed objects using logger info level.
     * @param args the logging parameters
     */
    public void info(final Object... args) {
        if (logger_.isInfoEnabled()) {
            logger_.info(process(args));
        }
    }

    /**
     * Prints the passed objects using logger warn level.
     * @param args the logging parameters
     */
    public void warn(final Object... args) {
        if (logger_.isWarnEnabled()) {
            logger_.warn(process(args));
        }
    }

    /**
     * Prints the passed objects using logger error level.
     * @param args the logging parameters
     */
    public void error(final Object... args) {
        if (logger_.isErrorEnabled()) {
            logger_.error(process(args));
        }
    }

    /**
     * This method is used by all the public method to process the passed
     * parameters.
     *
     * If the last parameter implements the Formatter interface, it will be
     * used to format the parameters and print the object.
     * @param objs the logging parameters
     * @return a String to be printed using the logger
     */
    private String process(final Object[] objs) {
        if (objs == null) {
            return "null";
        }

        final StringBuffer sb = new StringBuffer();
        final LinkedList<Object> args = new LinkedList<>(Arrays.asList(objs));

        final Formatter formatter = getFormatter();

        if (args.size() > 1 && args.get(0) instanceof String) {
            final StringBuilder msg = new StringBuilder((String) args.remove(0));
            int startPos = msg.indexOf("%");

            while (startPos > -1 && startPos < msg.length() - 1 && args.size() > 0) {
                if (startPos != 0 && msg.charAt(startPos - 1) == '%') {
                    // double %
                    msg.replace(startPos, startPos + 1, "");
                } else {
                    final char type = msg.charAt(startPos + 1);
                    String replacement = null;
                    switch (type) {
                    case 'o':
                    case 's':
                        replacement = formatter.parameterAsString(pop(args));
                        break;
                    case 'd':
                    case 'i':
                        replacement = formatter.parameterAsInteger(pop(args));
                        break;
                    case 'f':
                        replacement = formatter.parameterAsFloat(pop(args));
                        break;
                    default:
                        break;
                    }
                    if (replacement != null) {
                        msg.replace(startPos, startPos + 2, replacement);
                        startPos = startPos + replacement.length();
                    } else {
                        startPos++;
                    }
                }
                startPos = msg.indexOf("%", startPos);
            }
            sb.append(msg);
        }

        for (final Object o : args) {
            if (sb.length() != 0) {
                sb.append(' ');
            }
            sb.append(formatter.printObject(o));
        }
        return sb.toString();
    }

    /**
     * This method removes and returns the first (i.e. at index 0) element in
     * the passed list if it exists. Otherwise, null is returned.
     * @param list the
     * @return the first object in the list or null
     */
    private static Object pop(final List<Object> list) {
        return list.isEmpty() ? null : list.remove(0);
    }

    /**
     * This class is the default formatter used by WebConsole.
     */
    private static class DefaultFormatter implements Formatter {

        @Override
        public String printObject(final Object o) {
            return parameterAsString(o);
        }

        @Override
        public String parameterAsString(final Object o) {
            if (o != null) {
                return o.toString();
            }
            return "null";
        }

        @Override
        public String parameterAsInteger(final Object o) {
            if (o instanceof Number) {
                return Integer.toString(((Number) o).intValue());
            } else if (o instanceof String) {
                try {
                    return Integer.toString(Integer.parseInt((String) o));
                } catch (final NumberFormatException e) {
                    // Swallow the exception and return below
                }
            }
            return "NaN";
        }

        @Override
        public String parameterAsFloat(final Object o) {
            if (o instanceof Number) {
                return Float.toString(((Number) o).floatValue());
            } else if (o instanceof String) {
                try {
                    return Float.toString(Float.parseFloat((String) o));
                } catch (final NumberFormatException e) {
                    // Swallow the exception and return below
                }
            }
            return "NaN";
        }
    }

    /**
     * This class is the default logger used by WebConsole.
     */
    private static class DefaultLogger implements Logger {
        /** Logging support. */
        private static final Log LOG = LogFactory.getLog(WebConsole.class);

        @Override
        public boolean isTraceEnabled() {
            return LOG.isTraceEnabled();
        }

        @Override
        public void trace(final Object message) {
            if (LOG.isTraceEnabled()) {
                LOG.trace(message);
            }
        }

        @Override
        public boolean isDebugEnabled() {
            return LOG.isDebugEnabled();
        }

        @Override
        public void debug(final Object message) {
            if (LOG.isDebugEnabled()) {
                LOG.debug(message);
            }
        }

        @Override
        public boolean isInfoEnabled() {
            return LOG.isInfoEnabled();
        }

        @Override
        public void info(final Object message) {
            LOG.info(message);
        }

        @Override
        public boolean isWarnEnabled() {
            return LOG.isWarnEnabled();
        }

        @Override
        public void warn(final Object message) {
            LOG.warn(message);
        }

        @Override
        public boolean isErrorEnabled() {
            return LOG.isErrorEnabled();
        }

        @Override
        public void error(final Object message) {
            LOG.error(message);
        }
    }
}