package org.wahlzeit.services; import org.wahlzeit.model.Client; import org.wahlzeit.model.UserManager; import org.wahlzeit.model.UserSession; import java.io.PrintWriter; import java.io.StringWriter; /** * Builder class for log messages, that ensures that log messages are all formatted equally. * * Google App Engine as a PaaS has certain restrictions depending their services, hence a default Java logging * <code>Formatter</code> could not be used * * (see https://stackoverflow.com/questions/30345665/how-to-customize-logging-for-google-app-engine-java). * * @review */ public class LogBuilder { protected static final String LEVEL = "level"; protected static final String USER_LEVEL = "ul"; protected static final String SYSTEM_LEVEL = "sl"; protected static final String SESSION = "session"; protected static final String CLIENT = "client"; protected static final String MESSAGE = "message"; protected static final String ACTION = "action"; protected static final String NAME_VALUE_SEPARATOR = "="; protected static final String INFO_SEPARATOR = ", "; protected static final String EXCEPTION_REASON = "exception reason"; protected static final String STACKTRACE = "stacktrace"; protected StringBuilder logMessage; protected LogBuilder() { logMessage = new StringBuilder(); } // create-methods -------------------------------------------------------------------------------------------------- /** * @methodtype factory * * Creates a LogBuilder Object and adds the Level (user level), the current <code>HttpSession</code>, and the * clients name. */ public static LogBuilder createUserMessage() { return doCreateMessage(USER_LEVEL); } /** * @methodtype factory * * Primitive Method that creates a LogBuilder Object and adds the Level, the current <code>HttpSession</code>, and * the clients name. */ protected static LogBuilder doCreateMessage(String level) { LogBuilder result = new LogBuilder(); Session session = SessionManager.getThreadLocalSession(); String sessionName; String clientName; if (session != null) { sessionName = session.getName(); Client client = UserManager.getInstance().getClientById(session.getClientId()); if (client != null) { clientName = client.getNickName(); } else { clientName = UserSession.ANONYMOUS_CLIENT; } } else { sessionName = Session.NO_SESSION; clientName = UserSession.ANONYMOUS_CLIENT; } result.add(LEVEL + NAME_VALUE_SEPARATOR + level); result.add(SESSION + NAME_VALUE_SEPARATOR + sessionName); result.add(CLIENT + NAME_VALUE_SEPARATOR + clientName); return result; } /** * @methodtype set */ protected void add(String logMessagePart) { assert logMessage != null; if (logMessage.length() == 0) { logMessage.append(logMessagePart); } else { logMessage.append(INFO_SEPARATOR); logMessage.append(logMessagePart); } } // add-methods ----------------------------------------------------------------------------------------------------- /** * @methodtype factory * * Creates a LogBuilder Object and adds the Level (system level), the current <code>HttpSession</code>, and the * clients name. */ public static LogBuilder createSystemMessage() { return doCreateMessage(SYSTEM_LEVEL); } /** * @methodtype mutate * * Adds the following to the LogMessage: ", <name>=<value>". */ public LogBuilder addParameter(String name, int value) { add(name + NAME_VALUE_SEPARATOR + String.valueOf(value)); return this; } /** * @methodtype mutate * * Adds the following to the LogMessage: ", <name>=<value>". */ public LogBuilder addParameter(String name, boolean value) { add(name + NAME_VALUE_SEPARATOR + String.valueOf(value)); return this; } /** * @methodtype mutate * * Adds the following to the LogMessage: ", <name>=<value>". */ public LogBuilder addParameter(String name, String value) { add(name + NAME_VALUE_SEPARATOR + value); return this; } /** * @methodtype mutate * * Adds the following to the LogMessage: ", <name>=<value>.toString()". */ public LogBuilder addParameter(String name, Object value) { add(name + NAME_VALUE_SEPARATOR + value.toString()); return this; } /** * @methodtype mutate * * Adds the message to the LogMessage: ", <message>". */ public LogBuilder addMessage(String message) { add(message); return this; } /** * @methodtype mutate * * Adds the stacktrace and the <code>exceptionMessage</code> to the log message. */ public LogBuilder addException(String exceptionMessage, Throwable throwable) { add(EXCEPTION_REASON + NAME_VALUE_SEPARATOR + exceptionMessage); StringWriter sw = new StringWriter(); throwable.printStackTrace(new PrintWriter(sw)); add(STACKTRACE + NAME_VALUE_SEPARATOR + sw.toString()); return this; } // build-method ---------------------------------------------------------------------------------------------------- /** * @methodtype mutate * * Adds the info that the action is performed the log message: "action=<action>". */ public LogBuilder addAction(String action) { add(ACTION + NAME_VALUE_SEPARATOR + action); return this; } // hidden setter and getter methods -------------------------------------------------------------------------------- /** * @methodtype conversion * * Puts everything together that has been added to the LogMessage before. */ @Override public String toString() { assert logMessage != null; assert logMessage.length() > 0; return logMessage.toString(); } }