/*
* The MIT License
*
* Copyright 2012 Massive Dynamics.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package biz.massivedynamics.modger;
import biz.massivedynamics.modger.formatter.Formatter;
import biz.massivedynamics.modger.formatter.message.SingleLineMessageFormatter;
import biz.massivedynamics.modger.formatter.throwable.GenericThrowableFormatter;
import biz.massivedynamics.modger.message.Message;
import biz.massivedynamics.modger.message.MessageType;
import biz.massivedynamics.modger.message.filter.MessageFilter;
import biz.massivedynamics.modger.message.filter.impl.BlankMessageFilter;
import biz.massivedynamics.modger.message.filter.impl.MessageTypeFilter;
import biz.massivedynamics.modger.message.handler.MessageHandler;
import biz.massivedynamics.modger.message.handler.impl.SystemOutputMessageHandler;
import java.util.ArrayList;
import java.util.Arrays;
/**
* A class that defines a logger
*
* @author Cruz Bishop
* @since 1.0.0.0
*/
public class Logger implements Cloneable {
/**
* Creates a new logger
*
* @param name The name to use
* @since 1.0.0.0
*/
public Logger(String name) {
this(name, new SingleLineMessageFormatter(), new GenericThrowableFormatter(), new SystemOutputMessageHandler());
}
/**
* Creates a logger with the specified message formatter
*
* @param name The name to use
* @param messageFormatter The message formatter to use
* @since 1.0.0.0
*/
public Logger(String name, Formatter<Message, Message> messageFormatter) {
this(name, messageFormatter, new GenericThrowableFormatter(), new SystemOutputMessageHandler());
}
/**
* Creates a logger with the specified formatters
*
* @param name The name to use
* @param messageFormatter The message formatter to use
* @param throwableFormatter The throwable formatter to use
* @since 1.0.0.0
*/
public Logger(String name, Formatter<Message, Message> messageFormatter,
Formatter<Throwable, String> throwableFormatter) {
this(name, messageFormatter, throwableFormatter, new SystemOutputMessageHandler());
}
/**
* Creates a logger with the specified message handlers and formatter
*
* @param name The name to use
* @param messageFormatter The message formatter to use
* @param handlers The message handlers to use
* @since 1.0.0.0
*/
public Logger(String name, Formatter<Message, Message> messageFormatter, MessageHandler... handlers) {
this(name, messageFormatter, new GenericThrowableFormatter(), new SystemOutputMessageHandler());
}
/**
* Creates a logger with the specified message handlers and formatter
*
* @param name The name to use
* @param messageFormatter The message formatter to use
* @param throwableFormatter The throwable formatter to use
* @param handlers The handlers to use
* @since 1.0.0.0
*/
public Logger(String name, Formatter<Message, Message> messageFormatter,
Formatter<Throwable, String> throwableFormatter,
MessageHandler... handlers) {
//Add the handlers
this.handlers.addAll(Arrays.asList(handlers));
//Set up the default filters
this.filters.add(new BlankMessageFilter());
this.filters.add(new MessageTypeFilter());
//Set the message formatter
this.messageFormatter = messageFormatter;
//Set the throwable formatter
this.throwableFormatter = throwableFormatter;
//Set the name
this.name = name;
}
/**
* The name to use when logging
*
* @since 1.0.0.0
*/
private String name;
/**
* Gets the name
*
* @return The name
* @since 1.0.0.0
*/
public String getName() {
return this.name;
}
/**
* Sets the name
*
* @param name The name to use
* @since 1.0.0.0
*/
public void setName(String name) {
this.name = name;
}
/**
* The list of message handlers
*
* @since 1.0.0.0
*/
private ArrayList<MessageHandler> handlers = new ArrayList<>();
/**
* Gets the list of message handlers
*
* @return The list of message handlers
* @since 1.0.0.0
*/
public ArrayList<MessageHandler> getHandlers() {
return this.handlers;
}
/**
* The list of message filters
*
* @since 1.0.0.0
*/
private ArrayList<MessageFilter> filters = new ArrayList<>();
/**
* Gets the list of message filters
*
* @return The filters
* @since 1.0.0.0
*/
public ArrayList<MessageFilter> getFilters() {
return this.filters;
}
/**
* The message formatter
*
* @since 1.0.0.0
*/
private Formatter<Message, Message> messageFormatter;
/**
* Gets the message formatter
*
* @return The message formatter
* @since 1.0.0.0
*/
public Formatter getMessageFormatter() {
return this.messageFormatter;
}
/**
* Sets the message formatter
*
* @param formatter The formatter to use
* @since 1.0.0.0
*/
public void setMessageFormatter(Formatter formatter) {
this.messageFormatter = formatter;
}
/**
* The throwable formatter
*
* @since 1.0.0.0
*/
private Formatter<Throwable, String> throwableFormatter;
/**
* Gets the throwable formatter
*
* @return The throwable formatter
* @since 1.0.0.0
*/
public Formatter getThrowableFormatter() {
return this.throwableFormatter;
}
/**
* Sets the throwable formatter
*
* @param formatter The formatter to use
* @since 1.0.0.0
*/
public void setThrowableFormatter(Formatter formatter) {
this.throwableFormatter = formatter;
}
/**
* A method that submits a message and throwable
*
* @param message The message to submit
* @param throwable The throwable to also submit
* @since 1.0.0.0
*/
private void submitMessage(Message message, Throwable throwable) {
//First, format the throwable
String formattedThrowable = this.throwableFormatter.format(throwable);
//Then append it to the message
message.setMessage(message.getMessage() + Modger.getLineSeparator() + formattedThrowable);
//And automatically reformat
this.submitMessage(message);
}
/**
* A method that submits a message
*
* @param message The message to submit
* @since 1.0.0.0
*/
private void submitMessage(Message message) {
for (MessageFilter filter : this.filters) {
//See if a filter deems that a message is unacceptable
if (!filter.isAcceptable(message)) {
//Nope. Return without doing anything!
return;
}
}
//Format the message
message = this.messageFormatter.format(message);
//Loop through each handler
for (MessageHandler handler : this.handlers) {
//Try to handle the message
try {
handler.submit(message);
} catch (Exception e) {
//We can't really do anything
//except continue and hope that the message is handled.
//Sending another message could slip by a filter and cause an endless loop
//BAD!
continue;
}
}
}
/**
* Submits a trace message
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitTrace(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.TRACE));
}
}
/**
* Submits a debug message
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitDebug(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.DEBUG));
}
}
/**
* Submits information
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitInformation(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.INFORMATION));
}
}
/**
* Submits a message
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitMessage(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.REGULAR));
}
}
/**
* Submits a warning
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitWarning(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.WARNING));
}
}
/**
* Submits a warning which has a throwable attached
*
* @param message The message to submit
* @param throwable The throwable
* @since 1.0.0.0
*/
public void submitWarning(String message, Throwable throwable) {
this.submitMessage(new Message(this, message, MessageType.WARNING), throwable);
}
/**
* Submits an error
*
* @param messages The messages to submit
* @since 1.0.0.0
*/
public void submitError(String... messages) {
for (String message : messages) {
this.submitMessage(new Message(this, message, MessageType.ERROR));
}
}
/**
* Submits an error which has a throwable attached
*
* @param message The message to submit
* @param throwable The throwable
* @since 1.0.0.0
*/
public void submitError(String message, Throwable throwable) {
this.submitMessage(new Message(this, message, MessageType.ERROR), throwable);
}
/**
* Clones this logger, but creates a new name
*
* @param name The name to use
* @return The logger
* @since 1.0.0.0
*/
public Logger clone(String name) {
//Clone this logger
Logger clonedLogger = this.clone();
//Set the name
clonedLogger.setName(name);
//And return the cloned logger
return clonedLogger;
}
/**
* Clones this logger
*
* @return The cloned logger
* @since 1.0.0.0
*/
@Override
public Logger clone() {
Logger clonedLogger = new Logger(this.getName(),
this.getMessageFormatter(),
this.getThrowableFormatter());
//Reset and set the handlers
clonedLogger.getHandlers().clear();
clonedLogger.getHandlers().addAll(this.getHandlers());
//Reset and set the filters
clonedLogger.getFilters().clear();
clonedLogger.getFilters().addAll(this.getFilters());
//And return the new logger
return clonedLogger;
}
}