/* Copyright (c) 2002 Oracle Corporation. All Rights Reserved. */
package oracle.portal.log;

import java.util.List;
import java.util.Collection;
import java.util.Iterator;

import oracle.portal.utils.NameValue;
import oracle.webdb.utils.SimpleStringBuffer;

/**
 * MessageContext is a logging utility class that accepts context information
 * you want included with each log message and formats messages for output.
 *
 * <p>This class accepts any number of {@link oracle.portal.utils.NameValue} 
 * objects that represent the context information. The context string is 
 * constructed by appending the context information together in a format 
 * defined by the implementation. The format used by the base implementation is
 * 
 * <p><code>[&ltname1&gt=&ltvalue1&gt, &ltname2&gt=&ltvalue2&gt...]</code>
 */
public class MessageContext
{
    private static final String NULL_STRING = "(null)";
    private static final String EMPTY_STRING = "(empty string)";
    /**
     * the pre-constructed context string to be used when formatting message
     */
    private String mContextStr;


    /**
     * Constructor.
     *
     * MessageContext builds the context string during object initialization to
     * minimize the amount of work that must be done when formatting a message.
     * This implementation uses the name and value elements of each
     * {@link oracle.portal.utils.NameValue} when constructing the context 
     * message. 
     *
     * @param contextEntries an array of <code>NameValue</code> objects
     * representing the context information.
     */
    public MessageContext(NameValue[] contextEntries)
    {
        if (contextEntries == null || contextEntries.length == 0)
        {
            return;
        }
        
        SimpleStringBuffer buf = new SimpleStringBuffer(200);
        buf.append("[");
        
        NameValue nextEntry;
        String name, value;
        boolean firstEntry = true;
        for(int i=0; i < contextEntries.length; i++)
        {
            nextEntry = contextEntries[i];
            // make sure we have a name to print
            if (nextEntry == null || 
                nextEntry.getName() == null || 
                nextEntry.getName().equals(""))
            {
                continue;
            }

            if (!firstEntry)
            {
                buf.append(", ");
            }
            buf.append(nextEntry.getName());
            buf.append("=");
            buf.append(formatValue(nextEntry.getValue()));
            firstEntry = false;
        }
        buf.append("] ");
        setContext(buf.toString());
    }

    /**
     * Formats a message by adding context information prior to logging. 
     * 
     * @param msg the message that needs to be logged
     * @return the formatted message
     */
    public String formatMessage(String msg)
    {
        if (getContext() == null)
        {
            return msg;
        }

        SimpleStringBuffer buf = new SimpleStringBuffer(400);
        buf.append(getContext());
        buf.append(msg);
        return buf.toString();
    }

    /**
     * Sets the context string to be used when formatting a message
     * 
     * @param context the context information to be added to a message by
     *        <@link #formatMessage>
     */
    protected void setContext(String context)
    {
        mContextStr = context;
    }

    /**
     * Gets the context string to be used when formatting a message
     * 
     * @return the context information to be added to a message by
     *         <@link #formatMessage>
     */
    protected String getContext()
    {
        return mContextStr;
    }

    /**
     * formats a value before including it in the formatted context string.
     *
     * Default implementation replaces NULL and "" with readable values
     * 
     * @return formatted value
     */
    protected String formatValue(String value)
    {
        if (value == null || value.equals(""))
        {
            return NULL_STRING;
        }
        else if (value.equals(""))
        {
            return EMPTY_STRING;
        }
        return value;
    }
}
