All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openpojo.log.utils.MessageFormatter Maven / Gradle / Ivy

Go to download

This project was born out of a need to validate all POJOs (Plain Old Java Object) are behaving correctly. This project has two main aspects to it: * Make Testing as easy as possible. * Simplifying identity management (hashCode / equals) using annotation.

There is a newer version: 0.7.3
Show newest version
/**
 * Copyright (C) 2010 Osman Shoukry
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this program.  If not, see .
 */
package com.openpojo.log.utils;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * This utility class is used by the logger to format log messages.
 *
 * @author oshoukry
 */
public final class MessageFormatter {
    private static final FieldPosition POSITION = new FieldPosition(0);
    private static final int BUFFER_FACTOR = 8;

    /**
     * This string will be used if the logger is ever called with "null" message.
     */
    static final String DEFAULT_MESSAGE = "No message to be logged, here are the arguments passed:";

    /**
     * This utility method is used by the Logger, and will fall back on a default message if we don't have any.
     *
     * @param message
     *            The message to use with tokens.
     * @param args
     *            The objects to print inside the tokens
     * @return
     *         A formatted string ready for logging.
     */
    public static String format(final String message, final Object... args) {
        if (message == null) {
            return usingCurlyBrackets(DEFAULT_MESSAGE + generateCurlyBracketTokens(args == null ? 0 : args.length),
                                      args);
        }
        return usingCurlyBrackets(message, args);
    }

    /**
     * This method takes a message and arguments in the format of tokens using {#} and substitute those for the objects
     * in the array. (i.e. usingCurlyBrackets("this is a {0} message", "cool") returns "this is a cool message".)
     * for further notes on how the formatting actually works, see {@link java.text.MessageFormat} To Note:
     * 1. Remember that to get a single quote out again from "message" you need to double it. (i.e.
     * "It''s great to be alive" and NOT "It's great to be alive").
     * 2: if you pass in a date object, it doesn't use the date.toString(), but formats it using short date version.
     *
     * @param message
     *            The message to replace its tokens with objects.
     * @param args
     *            The objects to log in the string.
     * @return
     *         Returns a formated string filling all tokens with the objects.
     */
    static String usingCurlyBrackets(final String message, final Object... args) {
        if (message == null) {
            return null;
        }

        Object[] params = formatArgsToStrings(args);

        StringBuffer buf = new StringBuffer(message.length() + (params == null ? 0 : BUFFER_FACTOR * params.length));
        new MessageFormat(message).format(params, buf, POSITION);

        return buf.toString();
    }

    /**
     * This method is responsible for taking arrays turning them into a string. (i.e. if we pass in an Object[][]), it
     * will become and Object[String];
     *
     * @param args
     *            The list of params to scan for arrays out.
     * @return a one level array of objects to format.
     */
    static Object[] formatArgsToStrings(final Object... args) {
        Object[] params = null;
        if (args != null) {
            params = new Object[args.length];
            for (int counter = 0; counter < args.length; counter++) {
                params[counter] = format(args[counter]);
            }
        }
        return params;
    }

    private static final String DEFAULT_FIELDS_FORMAT_PREFIX = "[{";
    private static final String DEFAULT_FIELDS_FORMAT_POSTFIX = "}]";

    /**
     * This is a quick utility that will generate enclosed curly brackets for convenience.
     *
     * @param numberOfTokens
     *            The number of tokens you want to get back.
     * @return a string with tokens that can take in the "args" right away in "usingCurlyBrackets"
     */
    static String generateCurlyBracketTokens(final int numberOfTokens) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int counter = 0; counter < numberOfTokens; counter++) {
            stringBuilder.append(DEFAULT_FIELDS_FORMAT_PREFIX).append(counter).append(DEFAULT_FIELDS_FORMAT_POSTFIX);
        }
        return stringBuilder.toString();
    }

    public static String format(final Object message) {
        if (message == null) {
            return null;
        }

        String formattedMessage = message.toString();

        Class type = message.getClass();
        if (type.isArray()) {
            formattedMessage = Arrays.toString((Object[]) message);
        }
        if (message instanceof Throwable) {
            formattedMessage = format((Throwable) message);
        }
        return formattedMessage;
    }

    private static String format(final Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        throwable.printStackTrace(pw);

        pw.flush();
        LineNumberReader reader = new LineNumberReader(new StringReader(sw.toString()));
        ArrayList lines = new ArrayList();
        try {
            String line = reader.readLine();
            while (line != null) {
                lines.add(line);
                line = reader.readLine();
            }
        } catch (IOException ex) {
            if (ex instanceof InterruptedIOException) {
                Thread.currentThread().interrupt();
            }
            lines.add(ex.toString());
        }
        return lines.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy