Package org.fcrepo.server.journal.recoverylog

Source Code of org.fcrepo.server.journal.recoverylog.JournalRecoveryLog

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.journal.recoverylog;

import java.io.IOException;
import java.io.Writer;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import org.fcrepo.server.MultiValueMap;
import org.fcrepo.server.errors.ModuleInitializationException;
import org.fcrepo.server.journal.JournalConstants;
import org.fcrepo.server.journal.JournalException;
import org.fcrepo.server.journal.ServerInterface;
import org.fcrepo.server.journal.entry.ConsumerJournalEntry;
import org.fcrepo.server.journal.entry.JournalEntryContext;
import org.fcrepo.server.journal.helpers.JournalHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* The abstract base for all JournalRecoveryLog classes.
*
* @author Jim Blake
*/
public abstract class JournalRecoveryLog
        implements JournalConstants {

    private static final Logger logger =
            LoggerFactory.getLogger(JournalRecoveryLog.class);

    private static final int LEVEL_LOW = 0;

    private static final int LEVEL_MEDIUM = 1;

    private static final int LEVEL_HIGH = 2;

    protected final ServerInterface server;

    private final int logLevel;

    /**
     * Create an instance of the proper JournalRecoveryLog child class, as
     * determined by the server parameters.
     */
    public static JournalRecoveryLog getInstance(Map<String, String> parameters,
                                                 String role,
                                                 ServerInterface server)
            throws ModuleInitializationException {

        try {
            Object recoveryLog =
                    JournalHelper
                            .createInstanceAccordingToParameter(PARAMETER_JOURNAL_RECOVERY_LOG_CLASSNAME,
                                                                new Class[] {
                                                                        Map.class,
                                                                        String.class,
                                                                        ServerInterface.class},
                                                                new Object[] {
                                                                        parameters,
                                                                        role,
                                                                        server},
                                                                parameters);
            logger.info("JournalRecoveryLog is " + recoveryLog.toString());
            return (JournalRecoveryLog) recoveryLog;
        } catch (JournalException e) {
            throw new ModuleInitializationException("Can't create JournalRecoveryLog",
                                                    role,
                                                    e);
        }
    }

    /**
     * Concrete sub-classes must implement this constructor. Checks the server
     * parameters to find out what Logging Level to use - default is Low.
     */
    protected JournalRecoveryLog(Map<String, String> parameters,
                                 String role,
                                 ServerInterface server)
            throws ModuleInitializationException {
        this.server = server;

        String level = parameters.get(PARAMETER_RECOVERY_LOG_LEVEL);
        if (level == null) {
            logLevel = LEVEL_LOW;
        } else if (VALUE_RECOVERY_LOG_LEVEL_HIGH.equals(level)) {
            logLevel = LEVEL_HIGH;
        } else if (VALUE_RECOVERY_LOG_LEVEL_MEDIUM.equals(level)) {
            logLevel = LEVEL_MEDIUM;
        } else if (VALUE_RECOVERY_LOG_LEVEL_LOW.equals(level)) {
            logLevel = LEVEL_LOW;
        } else {
            throw new ModuleInitializationException("'"
                    + PARAMETER_RECOVERY_LOG_LEVEL + "' parameter must be '"
                    + VALUE_RECOVERY_LOG_LEVEL_LOW + "'(default), '"
                    + VALUE_RECOVERY_LOG_LEVEL_MEDIUM + "' or '"
                    + VALUE_RECOVERY_LOG_LEVEL_HIGH + "'", role);
        }
    }

    /**
     * Concrete sub-classes should probably synchronize this method, since it
     * can be called either from the JournalConsumerThread or from the Server.
     */
    public abstract void log(String message);

    /**
     * Concrete sub-classes should probably synchronize this method, since it
     * can be called either from the JournalConsumerThread or from the Server.
     * For the same reason, they should also provide for the possibility that it
     * will be called multiple times, or that a call to log() will happen after
     * the call to shutdown().
     */
    public abstract void shutdown();

    public void shutdown(String message) {
        log(message);
        shutdown();
    }

    /**
     * Concrete sub-classes should call this method from their constructor, or
     * as soon as the log is ready for writing.
     */
    public void logHeaderInfo(Map<String, String> parameters) {
        StringBuffer buffer = new StringBuffer("Recovery parameters:");
        for (Iterator<String> keys = parameters.keySet().iterator(); keys
                .hasNext();) {
            Object key = keys.next();
            Object value = parameters.get(key);
            buffer.append("\n    ").append(key).append("=").append(value);
        }
        log(buffer.toString());
    }

    /**
     * Format a journal entry for writing to the logger. Take logging level into
     * account.
     */
    public void log(ConsumerJournalEntry journalEntry) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Event: method='").append(journalEntry.getMethodName())
                .append("', ").append(journalEntry.getIdentifier())
                .append("\n");
        if (logLevel == LEVEL_HIGH) {
            JournalEntryContext context = journalEntry.getContext();
            buffer.append("    context=").append(context.getClass().getName())
                    .append("\n");
            buffer.append(writeMapValues("environmentAttributes", context
                    .getEnvironmentAttributes()));
            buffer.append(writeMapValues("subjectAttributes", context
                    .getSubjectAttributes()));
            buffer.append(writeMapValues("actionAttributes", context
                    .getActionAttributes()));
            buffer.append(writeMapValues("resourceAttributes", context
                    .getResourceAttributes()));
            buffer.append(writeMapValues("recoveryAttributes", context
                    .getRecoveryAttributes()));
            buffer.append("        password='*********'\n");
            buffer.append("        noOp=").append(context.getNoOp())
                    .append("\n");
        }
        if (logLevel == LEVEL_HIGH || logLevel == LEVEL_MEDIUM) {
            buffer.append("        now=" + journalEntry.getContext().getNoOp()
                    + "\n");
            buffer.append("    arguments\n");
            Map argumentsMap = journalEntry.getArgumentsMap();
            for (Iterator names = argumentsMap.keySet().iterator(); names
                    .hasNext();) {
                String name = (String) names.next();
                Object value = argumentsMap.get(name);
                if (value instanceof String[]) {
                    buffer.append(writeStringArray(name, (String[]) value));
                } else {
                    buffer.append("        " + name + "='" + value + "'\n");
                }
            }
        }
        log(buffer.toString());
    }

    /**
     * Helper for the {@link #log(ConsumerJournalEntry)} method. Writes the
     * values of a string array
     */
    private String writeStringArray(String name, String[] values) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("        ").append(name).append("=[");
        for (int i = 0; i < values.length; i++) {
            buffer.append("'").append(values[i]).append("'");
            if (i < values.length - 1) {
                buffer.append(", ");
            }
        }
        buffer.append("]\n");
        return buffer.toString();
    }

    /**
     * Helper for the {@link #log(ConsumerJournalEntry)} method. Writes the
     * values of a context multi-map.
     */
    private String writeMapValues(String mapName, MultiValueMap map) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("        " + mapName + "\n");
        for (Iterator names = map.names(); names.hasNext();) {
            String name = (String) names.next();
            buffer.append("            ").append(name).append("\n");
            String[] values = map.getStringArray(name);
            for (String element : values) {
                buffer.append("                ").append(element).append("\n");
            }
        }
        return buffer.toString();
    }

    /**
     * Concrete sub-classes call this method to perform the final formatting if
     * a log entry.
     */
    protected void log(String message, Writer writer) {
        try {
            writer.write(JournalHelper.formatDate(new Date()) + ": " + message
                    + "\n");
        } catch (IOException e) {
            logger.error("Error writing journal log entry", e);
        }
    }

}
TOP

Related Classes of org.fcrepo.server.journal.recoverylog.JournalRecoveryLog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.