/*
 * 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
 *
 *     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 org.apache.sis.util.logging;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.regex.Pattern;

import org.apache.sis.util.Debug;


/**
 * An adapter that redirect all JDK logging events to an other logging framework. This
 * class redefines the {@link #severe(String) severe}, {@link #warning(String) warning},
 * {@link #info(String) info}, {@link #config(String) config}, {@link #fine(String) fine},
 * {@link #finer(String) finer} and {@link #finest(String) finest} methods as <em>abstract</em>
 * ones. Subclasses should implement those methods in order to map JDK logging levels to
 * the backend logging framework.
 *
 * <p>All {@link #log(Level,String) log} methods are overridden in order to redirect to one of the
 * above-cited methods. Note that this is the opposite approach than the JDK logging framework
 * one, which implements everything on top of {@link Logger#log(LogRecord)}. This adapter is
 * defined in terms of {@link #severe(String) severe} … {@link #finest(String) finest} methods
 * instead because external frameworks like <a href="http://commons.apache.org/logging/">Commons-logging</a>
 * don't work with {@link LogRecord}, and sometime provides nothing else than convenience methods
 * equivalent to {@link #severe(String) severe} … {@link #finest(String) finest}.</p>
 *
 * <h2>Restrictions</h2>
 * Because the configuration is expected to be fully controlled by the external logging
 * framework, every configuration methods inherited from {@link Logger} are disabled:
 *
 * <ul>
 *   <li>{@link #addHandler(Handler)}
 *       since the handling is performed by the external framework.</li>
 *
 *   <li>{@link #setUseParentHandlers(boolean)}
 *       since this adapter never delegates to the parent handlers. This is consistent with the
 *       previous item and avoid mixing loggings from the external framework with JDK loggings.</li>
 *
 *   <li>{@link #setParent(Logger)}
 *       since this adapter should not inherits any configuration from a parent logger using the
 *       JDK logging framework.</li>
 *
 *   <li>{@link #setFilter(Filter)}
 *       for keeping this {@code LoggerAdapter} simple.</li>
 * </ul>
 *
 * Since {@code LoggerAdapter}s do not hold any configuration by themselves, it is not strictly
 * necessary to {@linkplain java.util.logging.LogManager#addLogger add them to the log manager}.
 * The adapters can be created, garbage-collected and recreated again while preserving their
 * behavior since their configuration is entirely contained in the external logging framework.
 *
 * <h2>Localization</h2>
 * This logger is always created without resource bundles. Localizations shall be done through
 * explicit calls to {@code logrb} or {@link #log(LogRecord)} methods. This is sufficient for
 * SIS needs, which performs all localizations through the later. Note that those methods
 * will be slower in this {@code LoggerAdapter} than the default {@link Logger} because this
 * adapter localizes and formats records immediately instead of letting the {@linkplain Handler}
 * performs this work only if needed.
 *
 * <h2>Logging levels</h2>
 * If a log record {@linkplain Level level} is not one of the predefined ones, then this class
 * maps to the first level below the specified one. For example if a log record has some level
 * between {@link Level#FINE FINE} and {@link Level#FINER FINER}, then the {@link #finer finer}
 * method will be invoked. See {@link #isLoggable(Level)} for implementation tips taking advantage
 * of this rule.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.5
 *
 * @see Logging
 *
 * @since 0.3
 * @module
 */
public abstract class LoggerAdapter extends Logger {
    /**
     * The pattern to use for detecting {@link MessageFormat}.
     */
    private static final Pattern MESSAGE_FORMAT = Pattern.compile("\\{\\d+\\}");

    /**
     * Creates a new logger.
     *
     * @param  name  the logger name.
     */
    protected LoggerAdapter(final String name) {
        super(name, null);
        /*
         * Must invokes the super-class method, because LoggerAdapter overrides it as a no-op.
         */
        super.setUseParentHandlers(false);
        /*
         * Sets the level to ALL as a matter of principle,  but we will never check the level
         * anyway (we will let the external logging framework do its own check). Note that we
         * must invoke the method in the super-class  because we want to set the java logging
         * level, not the external framework level.
         */
        super.setLevel(Level.ALL);
    }

    /**
     * Sets the level for this logger. Subclasses must redirect the call to the external
     * logging framework, or do nothing if the level can not be changed programmatically.
     *
     * @param level  the new value for the log level (may be null).
     */
    @Override
    public abstract void setLevel(Level level);

    /**
     * Returns the level for this logger. Subclasses shall get this level from the
     * external logging framework.
     *
     * @return the logger's level.
     */
    @Override
    public abstract Level getLevel();

    /**
     * Returns the level for {@link #entering(String, String) entering(…)}, {@link #exiting(String, String) exiting(…)}
     * and {@link #throwing(String, String, Throwable) throwing(…)} methods.
     * The default implementation returns {@link Level#FINER}, which is consistent with the
     * value used in the JDK logging framework. Subclasses should override this method if
     * a different debug level is wanted.
     *
     * @return the level to use for debugging information.
     */
    @Debug
    protected Level getDebugLevel() {
        return Level.FINER;
    }

    /**
     * Returns {@code true} if the specified level is loggable.
     *
     * <h4>Implementation tip</h4>
     * Given that {@link Level#intValue} for all predefined levels are documented in the {@link Level}
     * specification and are multiple of 100, given that integer divisions are rounded toward zero and
     * given rule documented in this <a href="#skip-navbar_top">class javadoc</a>, then logging levels
     * can be efficiently mapped to predefined levels using {@code switch} statements as below. This
     * statement has good chances to be compiled to the {@code tableswitch} bytecode rather than
     * {@code lookupswitch} (see
     * <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14942">Compiling
     * Switches</a> in <cite>The Java Virtual Machine Specification</cite>).
     *
     * {@preformat java
     *     public boolean isLoggable(Level level) {
     *         final int n = level.intValue();
     *         switch (n / 100) {
     *             default: {
     *                 // MAX_VALUE is a special value for Level.OFF. Otherwise and
     *                 // if positive, fallthrough since we are greater than SEVERE.
     *                 switch (n) {
     *                     case Integer.MIN_VALUE: return true;  // Level.ALL
     *                     case Integer.MAX_VALUE: return false; // Level.OFF
     *                     default: if (n < 0) return false;
     *                 }
     *             }
     *             case 10: return isSevereEnabled();
     *             case  9: return isWarningEnabled();
     *             case  8: return isInfoEnabled();
     *             case  7: return isConfigEnabled();
     *             case  6: // fallthrough
     *             case  5: return isFineEnabled();
     *             case  4: return isFinerEnabled();
     *             case  3: return isFinestEnabled();
     *             case  2: // fallthrough
     *             case  1: // fallthrough
     *             case  0: return false;
     *         }
     *     }
     * }
     *
     * @param  level  a message logging level.
     * @return {@code true} if the given message level is currently being logged.
     */
    @Override
    public abstract boolean isLoggable(Level level);

    /**
     * Logs a {@link Level#SEVERE SEVERE} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void severe(String message);

    /**
     * Logs a {@link Level#WARNING WARNING} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void warning(String message);

    /**
     * Logs an {@link Level#INFO INFO} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void info(String message);

    /**
     * Logs an {@link Level#CONFIG CONFIG} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void config(String message);

    /**
     * Logs a {@link Level#FINE FINE} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void fine(String message);

    /**
     * Logs a {@link Level#FINER FINER} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void finer(String message);

    /**
     * Logs a {@link Level#FINEST FINEST} message.
     *
     * @param message  the message to log.
     */
    @Override
    public abstract void finest(String message);

    /**
     * Logs a method entry to the {@linkplain #getDebugLevel debug level}. Compared to the
     * default {@link Logger}, this implementation bypass the level check in order to let
     * the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of method that is being entered.
     */
    @Override
    public void entering(final String sourceClass, final String sourceMethod) {
        logp(getDebugLevel(), sourceClass, sourceMethod, "ENTRY");
    }

    /**
     * Logs a method entry to the {@linkplain #getDebugLevel debug level} with one parameter.
     * Compared to the default {@link Logger}, this implementation bypass the level check in
     * order to let the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of method that is being entered.
     * @param param         parameter to the method being entered.
     */
    @Override
    public void entering(String sourceClass, String sourceMethod, Object param) {
        logp(getDebugLevel(), sourceClass, sourceMethod, "ENTRY {0}", param);
    }

    /**
     * Logs a method entry to the {@linkplain #getDebugLevel debug level} with many parameters.
     * Compared to the default {@link Logger}, this implementation bypass the level check in
     * order to let the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of method that is being entered.
     * @param params        array of parameters to the method being entered.
     */
    @Override
    public void entering(final String sourceClass, final String sourceMethod, final Object[] params) {
        final String message;
        if (params == null) {
            message = "ENTRY";
        } else switch (params.length) {
            case 0: message = "ENTRY";         break;
            case 1: message = "ENTRY {0}";     break;
            case 2: message = "ENTRY {0} {1}"; break;
            default: {
                final StringBuilder builder = new StringBuilder("ENTRY");
                for (int i=0; i<params.length; i++) {
                    builder.append(" {").append(i).append('}');
                }
                message = builder.toString();
                break;
            }
        }
        logp(getDebugLevel(), sourceClass, sourceMethod, message, params);
    }

    /**
     * Logs a method return to the {@linkplain #getDebugLevel debug level}. Compared to the
     * default {@link Logger}, this implementation bypass the level check in order to let
     * the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     */
    @Override
    public void exiting(final String sourceClass, final String sourceMethod) {
        logp(getDebugLevel(), sourceClass, sourceMethod, "RETURN");
    }

    /**
     * Logs a method return to the {@linkplain #getDebugLevel debug level}. Compared to the
     * default {@link Logger}, this implementation bypass the level check in order to let
     * the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param result        object that is being returned.
     */
    @Override
    public void exiting(String sourceClass, String sourceMethod, Object result) {
        logp(getDebugLevel(), sourceClass, sourceMethod, "RETURN {0}", result);
    }

    /**
     * Logs a method failure to the {@linkplain #getDebugLevel debug level}. Compared to the
     * default {@link Logger}, this implementation bypass the level check in order to let
     * the backing logging framework do its own check.
     *
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param thrown        the Throwable that is being thrown.
     */
    @Override
    public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
        logp(getDebugLevel(), sourceClass, sourceMethod, "THROW", thrown);
    }

    /**
     * Logs a record. The default implementation delegates to one of the
     * {@link #logrb(Level,String,String,ResourceBundle,String,Object[]) logrb} or
     * {@link #logp(Level,String,String,String)} methods.
     *
     * @param record  the log record to be published.
     */
    @Override
    public void log(final LogRecord record) {
        /*
         * The filter should always be null since we overrode the 'setFilter' method as a no-op.
         * But we check it anyway as matter of principle just in case some subclass overrides the
         * 'getFilter()' method. This is the only method where we can do this check cheaply. Note
         * that this is NOT the check for logging level; Filters are for user-specified criterions.
         */
        final Filter filter = getFilter();
        if (filter != null && !filter.isLoggable(record)) {
            return;
        }
        final Level     level        = record.getLevel();
        final String    sourceClass  = record.getSourceClassName();
        final String    sourceMethod = record.getSourceMethodName();
        final String    message      = record.getMessage();
        final Object[]  params       = record.getParameters();
        final Throwable thrown       = record.getThrown();
        final ResourceBundle bundle  = record.getResourceBundle();
        final boolean useThrown = (thrown != null) && (params == null || params.length == 0);
        if (bundle != null) {
            if (useThrown) {
                logrb(level, sourceClass, sourceMethod, bundle, message, thrown);
            } else {
                logrb(level, sourceClass, sourceMethod, bundle, message, params);
            }
        } else {
            final String bundleName = record.getResourceBundleName();
            if (bundleName != null) {
                if (useThrown) {
                    logrb(level, sourceClass, sourceMethod, bundleName, message, thrown);
                } else {
                    logrb(level, sourceClass, sourceMethod, bundleName, message, params);
                }
            } else {
                if (useThrown) {
                    logp(level, sourceClass, sourceMethod, message, thrown);
                } else {
                    logp(level, sourceClass, sourceMethod, message, params);
                }
            }
        }
    }

    /**
     * Logs a record at the specified level. The default implementation delegates to one of the
     * {@link #severe(String) severe}, {@link #warning(String) warning}, {@link #info(String) info},
     * {@link #config(String) config}, {@link #fine(String) fine}, {@link #finer(String) finer} or
     * {@link #finest(String) finest} methods according the supplied level.
     *
     * @param level    one of the message level identifiers.
     * @param message  the message to log.
     */
    @Override
    @SuppressWarnings("fallthrough")
    public void log(final Level level, final String message) {
        final int n = level.intValue();
        switch (n / 100) {
            default: {
                if (n < 0 || n == Integer.MAX_VALUE) break;
                /*
                 * MAX_VALUE is a special value for Level.OFF. Otherwise and
                 * if positive, fallthrough since we are greater than SEVERE.
                 */
            }
            case 10: severe (message); break;
            case  9: warning(message); break;
            case  8: info   (message); break;
            case  7: config (message); break;
            case  6:
            case  5: fine   (message); break;
            case  4: finer  (message); break;
            case  3: finest (message); break;
            case  2: /* Logging OFF */
            case  1: /* Logging OFF */
            case  0: /* Logging OFF */ break;
        }
    }

    /**
     * Logs a record at the specified level. The default implementation discards the exception
     * and delegates to <code>{@linkplain #log(Level,String) log}(level, message)</code>.
     *
     * @param level    one of the message level identifiers.
     * @param message  the message to log.
     * @param thrown   throwable associated with log message.
     */
    @Override
    public void log(final Level level, final String message, final Throwable thrown) {
        log(level, message);
    }

    /**
     * Logs a record at the specified level. The default implementation delegates to
     * <code>{@linkplain #log(Level,String,Object[]) log}(level, message, params)</code>
     * where the {@code params} array is built from the {@code param} object.
     *
     * @param level    one of the message level identifiers.
     * @param message  the message to log.
     * @param param    parameter to the method being entered.
     */
    @Override
    public void log(final Level level, final String message, final Object param) {
        log(level, message, asArray(param));
    }

    /**
     * Logs a record at the specified level.
     * The default implementation formats the message immediately, then delegates to
     * <code>{@linkplain #log(Level,String) log}(level, message)</code>.
     *
     * @param level    one of the message level identifiers.
     * @param message  the message to log.
     * @param params   array of parameters to the method being entered.
     */
    @Override
    public void log(final Level level, final String message, final Object[] params) {
        log(level, format(message, params));
    }

    /**
     * Logs a record at the specified level. The default implementation discards
     * the source class and source method, then delegates to
     * <code>{@linkplain #log(Level,String) log}(level, message)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param message       the message to log.
     */
    @Override
    public void logp(final Level level, final String sourceClass, final String sourceMethod,
                     final String message)
    {
        log(level, message);
    }

    /**
     * Logs a record at the specified level. The default implementation discards
     * the source class and source method, then delegates to
     * <code>{@linkplain #log(Level,String,Throwable) log}(level, message, thrown)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param message       the message to log.
     * @param thrown        throwable associated with log message.
     */
    @Override
    public void logp(final Level level, final String sourceClass, final String sourceMethod,
                     final String message, final Throwable thrown)
    {
        log(level, message, thrown);
    }

    /**
     * Logs a record at the specified level. The default implementation delegates to
     * <code>{@linkplain #logp(Level,String,String,String,Object[]) logp}(level, sourceClass,
     * sourceMethod, message, params)</code> where the {@code params} array is built from the
     * {@code param} object.
     *
     * <p>Note that {@code sourceClass} and {@code sourceMethod} will be discarded unless the
     * target {@link #logp(Level,String,String,String) logp} method has been overridden.</p>
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param message       the message to log.
     * @param param         parameter to the method being entered.
     */
    @Override
    public void logp(final Level level, final String sourceClass, final String sourceMethod,
                     final String message, final Object param)
    {
        logp(level, sourceClass, sourceMethod, message, asArray(param));
    }

    /**
     * Logs a record at the specified level. The default implementation formats the message
     * immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String)
     * logp}(level, sourceClass, sourceMethod, message)</code>.
     *
     * <p>Note that {@code sourceClass} and {@code sourceMethod} will be discarded unless the
     * target {@link #logp(Level,String,String,String) logp} method has been overridden.</p>
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param message       the message to log.
     * @param params        array of parameters to the method being entered.
     */
    @Override
    public void logp(final Level level, final String sourceClass, final String sourceMethod,
                     final String message, final Object[] params)
    {
        logp(level, sourceClass, sourceMethod, format(message, params));
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String,
     * Object[]) logp}(level, sourceClass, sourceMethod, message, params)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundle        the resource bundle for localizing the message, or {@code null}.
     * @param message       the message to log.
     * @param params        array of parameters to the method being entered.
     *
     * @since 0.5
     */
    @Override
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final ResourceBundle bundle, final String message, final Object... params)
    {
        logp(level, sourceClass, sourceMethod, localize(bundle, message), params);
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String,
     * Throwable) logp}(level, sourceClass, sourceMethod, message, thrown)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundle        the resource bundle for localizing the message, or {@code null}.
     * @param message       the message to log.
     * @param thrown        throwable associated with log message.
     *
     * @since 0.5
     */
    @Override
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final ResourceBundle bundle, final String message, final Throwable thrown)
    {
        logp(level, sourceClass, sourceMethod, localize(bundle, message), thrown);
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String)
     * logp}(level, sourceClass, sourceMethod, message)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundleName    name of resource bundle to localize message, or {@code null}.
     * @param message       the message to log.
     *
     * @deprecated JDK 8 has deprecated this method.
     */
    @Override
    @Deprecated
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final String bundleName, final String message)
    {
        logp(level, sourceClass, sourceMethod, localize(bundleName, message));
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String,
     * Throwable) logp}(level, sourceClass, sourceMethod, message, thrown)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundleName    name of resource bundle to localize message, or {@code null}.
     * @param message       the message to log.
     * @param thrown        throwable associated with log message.
     *
     * @deprecated JDK 8 has deprecated this method.
     */
    @Override
    @Deprecated
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final String bundleName, final String message, final Throwable thrown)
    {
        logp(level, sourceClass, sourceMethod, localize(bundleName, message), thrown);
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String,
     * Object) logp}(level, sourceClass, sourceMethod, message, param)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundleName    name of resource bundle to localize message, or {@code null}.
     * @param message       the message to log.
     * @param param         parameter to the method being entered.
     *
     * @deprecated JDK 8 has deprecated this method.
     */
    @Override
    @Deprecated
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final String bundleName, final String message, final Object param)
    {
        logp(level, sourceClass, sourceMethod, localize(bundleName, message), param);
    }

    /**
     * Logs a localizable record at the specified level. The default implementation localizes the
     * message immediately, then delegates to <code>{@linkplain #logp(Level,String,String,String,
     * Object[]) logp}(level, sourceClass, sourceMethod, message, params)</code>.
     *
     * @param level         one of the message level identifiers.
     * @param sourceClass   name of class that issued the logging request.
     * @param sourceMethod  name of the method.
     * @param bundleName    name of resource bundle to localize message, or {@code null}.
     * @param message       the message to log.
     * @param params        array of parameters to the method being entered.
     *
     * @deprecated JDK 8 has deprecated this method.
     */
    @Override
    @Deprecated
    public void logrb(final Level level, final String sourceClass, final String sourceMethod,
                      final String bundleName, final String message, final Object[] params)
    {
        logp(level, sourceClass, sourceMethod, localize(bundleName, message), params);
    }

    /**
     * Do nothing since this logger adapter does not supports handlers.
     * The configuration should be fully controlled by the external logging framework
     * (e.g. <a href="http://commons.apache.org/logging/">Commons-logging</a>) instead,
     * which is not expected to use {@link Handler} objects.
     *
     * @param handler  a logging handler, ignored in default implementation.
     */
    @Override
    public void addHandler(Handler handler) {
    }

    /**
     * Do nothing since this logger adapter does not support handlers.
     *
     * @param handler  a logging handler, ignored in default implementation.
     */
    @Override
    public void removeHandler(Handler handler) {
    }

    /**
     * Do nothing since this logger never use parent handlers. This is consistent
     * with {@link #addHandler} not allowing to add any handlers, and avoid mixing
     * loggings from the external framework with JDK loggings.
     *
     * @param useParentHandlers  ignored in default implementation.
     */
    @Override
    public void setUseParentHandlers(boolean useParentHandlers) {
    }

    /**
     * Do nothing since this logger adapter does not support arbitrary parents.
     * More specifically, it should not inherits any configuration from a parent
     * logger using the JDK logging framework.
     *
     * @param parent  ignored in default implementation.
     */
    @Override
    public void setParent(Logger parent) {
    }

    /**
     * Do nothing since this logger adapter does not support filters.  It is difficult to query
     * efficiently the filter in this {@code LoggerAdapter} architecture (e.g. we would need to
     * make sure that {@link Filter#isLoggable} is invoked only once even if a {@code log} call
     * is cascaded into many other {@code log} calls, and this test must works in multi-threads
     * environment).
     *
     * @param filter  ignored in default implementation.
     */
    @Override
    public void setFilter(Filter filter) {
    }

    /**
     * Wraps the specified object in an array. This is a helper method for
     * {@code log(…, Object)} methods that delegate their work to {@code log(…, Object[])}
     */
    private static Object[] asArray(final Object param) {
        return (param != null) ? new Object[] {param} : null;
    }

    /**
     * Formats the specified message. This is a helper method for
     * {@code log(…, Object[])} methods that delegate their work to {@code log(…)}
     */
    private static String format(String message, final Object[] params) {
        if (params != null && params.length != 0) {
            if (MESSAGE_FORMAT.matcher(message).find()) try {
                message = MessageFormat.format(message, params);
            } catch (IllegalArgumentException e) {
                /*
                 * The default Formatter.messageFormat implementation ignores this exception
                 * and uses the pattern as the message, so we mimic its behavior here.
                 */
            }
        }
        return message;
    }

    /**
     * Localizes the specified message. This is a helper method for
     * {@code logrb(…)} methods that delegate their work to {@code logp(…)}
     */
    private static String localize(final String bundleName, String message) {
        if (bundleName != null) try {
            message = ResourceBundle.getBundle(bundleName).getString(message);
        } catch (MissingResourceException e) {
            /*
             * The default Formatter.messageFormat implementation ignores this exception
             * and uses the bundle key as the message, so we mimic its behavior here.
             */
        }
        return message;
    }

    /**
     * Localizes the specified message. This is a helper method for
     * {@code logrb(…)} methods that delegate their work to {@code logp(…)}
     */
    private static String localize(final ResourceBundle bundle, String message) {
        if (bundle != null) try {
            message = bundle.getString(message);
        } catch (MissingResourceException e) {
            /*
             * The default Formatter.messageFormat implementation ignores this exception
             * and uses the bundle key as the message, so we mimic its behavior here.
             */
        }
        return message;
    }
}
