151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.util.logging;
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A Formatter provides support for formatting LogRecords.
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Typically each logging Handler will have a Formatter associated
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with it.  The Formatter takes a LogRecord and converts it to
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a string.
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Some formatters (such as the XMLFormatter) need to wrap head
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and tail strings around a set of formatted records. The getHeader
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and getTail methods can be used to obtain these strings.
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic abstract class Formatter {
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Construct a new formatter.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected Formatter() {
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Format the given log record and return the formatted string.
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The resulting formatted String will normally include a
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * localized and formatted version of the LogRecord's message field.
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * It is recommended to use the {@link Formatter#formatMessage}
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * convenience method to localize and format the message field.
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param record the log record to be formatted.
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the formatted log record
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public abstract String format(LogRecord record);
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the header string for a set of formatted records.
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This base class returns an empty string, but this may be
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * overridden by subclasses.
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   h  The target handler (can be null)
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  header string
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getHead(Handler h) {
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return "";
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return the tail string for a set of formatted records.
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This base class returns an empty string, but this may be
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * overridden by subclasses.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param   h  The target handler (can be null)
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  tail string
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String getTail(Handler h) {
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return "";
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Localize and format the message string from a log record.  This
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * method is provided as a convenience for Formatter subclasses to
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * use when they are performing formatting.
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The message string is first localized to a format string using
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the record's ResourceBundle.  (If there is no ResourceBundle,
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or if the message key is not found, then the key is used as the
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * format string.)  The format String uses java.text style
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * formatting.
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <ul>
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li>If there are no parameters, no formatter is used.
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li>Otherwise, if the string contains "{0" then
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *     java.text.MessageFormat  is used to format the string.
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <li>Otherwise no formatting is performed.
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </ul>
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  record  the log record containing the raw message
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return   a localized and formatted message
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public synchronized String formatMessage(LogRecord record) {
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String format = record.getMessage();
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.util.ResourceBundle catalog = record.getResourceBundle();
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (catalog != null) {
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                format = catalog.getString(record.getMessage());
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (java.util.MissingResourceException ex) {
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Drop through.  Use record message as format
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                format = record.getMessage();
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Do the formatting.
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Object parameters[] = record.getParameters();
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (parameters == null || parameters.length == 0) {
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // No parameters.  Just return format string.
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return format;
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Is it a java.text style format?
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Ideally we could match with
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Pattern.compile("\\{\\d").matcher(format).find())
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // However the cost is 14% higher, so we cheaply check for
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // 1 of the first 4 parameters
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (format.indexOf("{0") >= 0 || format.indexOf("{1") >=0 ||
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        format.indexOf("{2") >=0|| format.indexOf("{3") >=0) {
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return java.text.MessageFormat.format(format, parameters);
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return format;
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (Exception ex) {
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Formatting failed: use localized format string.
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return format;
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
148