/*
 * Copyright 2009-2010 The MICE Project Team.
 * Licensed under the MICE s.r.l.
 * End User License Agreement
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.micegroup.it/voila/license.html
 */
package it.mice.voila.runtime.log4j;

import java.util.ArrayList;

import org.apache.log4j.spi.LoggingEvent;

/**
 * Logger provider che opportunamente pluggato tramite Log4J, consente di storicizzare gli audit records
 * direttamente nella tabella di sicurezza: Security Operation Log.
 */
public abstract class AbstractAuditLoggerJdbcAppender extends org.apache.log4j.AppenderSkeleton
        implements org.apache.log4j.Appender {
    /**
     * size of LoggingEvent buffer before writting to the database.
     * Default is 1.
     */
    protected int bufferSize = 1;
    /**
     * ArrayList holding the buffer of Logging Events.
     */
    protected ArrayList<LoggingEvent> buffer;
    /**
     * Helper object for clearing out the buffer
     */
    protected ArrayList<LoggingEvent> removes;

    public AbstractAuditLoggerJdbcAppender() {
        super();
        buffer = new ArrayList<LoggingEvent>(bufferSize);
        removes = new ArrayList<LoggingEvent>(bufferSize);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.log4j.Appender#close()
     */
    public void close() {
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.log4j.Appender#requiresLayout()
     */
    public boolean requiresLayout() {
        return false;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
     */
    @Override
    protected void append(LoggingEvent event) {
        event.getNDC();
        event.getThreadName();
        // Get a copy of this thread's MDC.
        event.getMDCCopy();
        event.getRenderedMessage();
        event.getThrowableStrRep();
        buffer.add(event);
        if (buffer.size() >= bufferSize)
            flushBuffer();
    }

    /**
     * loops through the buffer of LoggingEvents, gets a
     * sql string from getLogStatement() and sends it to execute().
     * Errors are sent to the errorHandler.
     *
     * If a statement fails the LoggingEvent stays in the buffer!
     */
    public abstract void flushBuffer();

    /**
     * By default getLogStatement sends the event to the required Layout object.
     * The layout will format the given pattern into a workable SQL string.
     *
     * Overriding this provides direct access to the LoggingEvent
     * when constructing the logging statement.
     *
     */
    protected String getLogStatement(LoggingEvent event) {
        return event.getRenderedMessage();
    }
}