/******************************************************************************* * Copyright (C) 2014 Travis Ralston (turt2live) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package com.turt2live.antishare.engine; import com.turt2live.antishare.events.EventDispatcher; import com.turt2live.antishare.events.engine.DevEngineStateChangeEvent; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; /** * Represents the developer engine. This handles all debugging code * as well as integration with external services to ensure the operation * of this API Engine. * * @author turt2live */ // TODO: Unit test public class DevEngine { private static final String FILE_EXCEPTIONS = "exceptions.log"; private static final String FILE_LOGS = "log.log"; private static boolean ENABLED = false; private static File LOG_FOLDER = new File("logs"); private static DevEngine INSTANCE = null; private DevEngine() { } private void write(String line, String filename, boolean writeErrors) { if (line == null || filename == null) throw new IllegalArgumentException("wtf developer"); checkFolders(); SimpleDateFormat format = new SimpleDateFormat(); Date date = new Date(System.currentTimeMillis()); format.setTimeZone(TimeZone.getDefault()); String timestamp = format.format(date); Thread currentThread = Thread.currentThread(); try { BufferedWriter writer = new BufferedWriter(new FileWriter(new File(LOG_FOLDER, filename), true)); writer.write("[" + currentThread.getName() + "/" + currentThread.getId() + "][" + timestamp + "] " + line); writer.newLine(); writer.close(); } catch (IOException e) { if (writeErrors) printError(e); else { System.err.println("Encountered an error writing a file: " + e.getMessage()); e.printStackTrace(); } } } private void printError(Throwable thrown) { StringBuilder data = new StringBuilder(); data.append("Error:: ").append(thrown.getClass().getName()).append(" : ").append(thrown.getMessage()).append('\n'); writeStacktrace(data, thrown.getStackTrace()); writeCause(thrown, data); data.append("-----------------------\n"); write(data.toString(), FILE_EXCEPTIONS, false); // Ensure we don't end up in a stack overflow } private void writeCause(Throwable throwable, StringBuilder builder) { if (throwable == null) return; Throwable cause = throwable.getCause(); if (cause != null) { builder.append("Caused By: \n"); writeStacktrace(builder, cause.getStackTrace()); writeCause(cause, builder); } } private void writeStacktrace(StringBuilder builder, StackTraceElement[] elements) { for (StackTraceElement element : elements) { builder.append('\t').append(element.toString()).append('\n'); } } private void checkFolders() { if (!LOG_FOLDER.exists()) LOG_FOLDER.mkdirs(); } private static DevEngine getInstance() { if (INSTANCE == null) INSTANCE = new DevEngine(); return INSTANCE; } /** * Writes an error to the log file. Does nothing if {@link #isEnabled()} return false * * @param throwable the error to write, cannot be null */ public static void writeError(Throwable throwable) { if (!isEnabled()) return; if (throwable == null) throw new IllegalArgumentException("throwable cannot be null"); getInstance().printError(throwable); } /** * Writes to the log file. Does nothing if {@link #isEnabled()} return false * * @param line the line to write, cannot be null * @param moreLines extra lines to include */ public static void log(String line, String... moreLines) { if (!isEnabled()) return; if (line == null) throw new IllegalArgumentException("line cannot be null"); getInstance().write(line, FILE_LOGS, true); if (moreLines != null) { for (String extra : moreLines) { getInstance().write(extra, FILE_LOGS, true); } } } /** * Sets this developer engine enabled or disabled * * @param enabled true for enabled, false otherwise */ public static void setEnabled(boolean enabled) { ENABLED = enabled; EventDispatcher.dispatch(new DevEngineStateChangeEvent()); } /** * Determines if this developer engine is enabled * * @return true for enabled, false otherwise */ public static boolean isEnabled() { return ENABLED; } /** * Sets the log folder for this DevEngine * * @param directory the new directory, cannot be null */ public static void setLogDirectory(File directory) { if (directory == null) throw new IllegalArgumentException(); LOG_FOLDER = directory; } /** * Gets the current log directory * * @return the current log directory */ public static File getLogDirectory() { return LOG_FOLDER; } }