aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/de/romjaki/logger/EventHandler.java15
-rw-r--r--src/main/java/de/romjaki/logger/Level.java18
-rw-r--r--src/main/java/de/romjaki/logger/LogEvent.java26
-rw-r--r--src/main/java/de/romjaki/logger/LogHandler.java8
-rw-r--r--src/main/java/de/romjaki/logger/LoggedEvent.java23
-rw-r--r--src/main/java/de/romjaki/logger/Logger.java212
-rw-r--r--src/main/java/de/romjaki/logger/impl/FileLogger.java27
-rw-r--r--src/main/java/de/romjaki/logger/impl/LoggerImpl.java12
-rw-r--r--src/main/java/de/romjaki/logger/impl/StreamLogger.java38
9 files changed, 379 insertions, 0 deletions
diff --git a/src/main/java/de/romjaki/logger/EventHandler.java b/src/main/java/de/romjaki/logger/EventHandler.java
new file mode 100644
index 0000000..8a6855c
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/EventHandler.java
@@ -0,0 +1,15 @@
+package de.romjaki.logger;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({METHOD})
+public @interface EventHandler {
+}
diff --git a/src/main/java/de/romjaki/logger/Level.java b/src/main/java/de/romjaki/logger/Level.java
new file mode 100644
index 0000000..38310ab
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/Level.java
@@ -0,0 +1,18 @@
+package de.romjaki.logger;
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+public enum Level {
+ ALL,
+ FAILURE,
+ ERROR,
+ WARNING,
+ INFO,
+ DEBUG,
+ OFF;
+
+ public boolean logs(Level level) {
+ return this.ordinal() <= level.ordinal();
+ }
+}
diff --git a/src/main/java/de/romjaki/logger/LogEvent.java b/src/main/java/de/romjaki/logger/LogEvent.java
new file mode 100644
index 0000000..e62742c
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/LogEvent.java
@@ -0,0 +1,26 @@
+package de.romjaki.logger;
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+public abstract class LogEvent {
+
+ boolean interrupted = false;
+ Class<?> actor;
+
+ public LogEvent(Class<?> actor) {
+ this.actor = actor;
+ }
+
+ public void interrupt() {
+ interrupted = true;
+ }
+
+ public Class<?> getActor() {
+ return actor;
+ }
+
+ public boolean isInterrupted() {
+ return interrupted;
+ }
+}
diff --git a/src/main/java/de/romjaki/logger/LogHandler.java b/src/main/java/de/romjaki/logger/LogHandler.java
new file mode 100644
index 0000000..5f23e11
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/LogHandler.java
@@ -0,0 +1,8 @@
+package de.romjaki.logger;
+
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+public interface LogHandler {
+}
diff --git a/src/main/java/de/romjaki/logger/LoggedEvent.java b/src/main/java/de/romjaki/logger/LoggedEvent.java
new file mode 100644
index 0000000..143ab0c
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/LoggedEvent.java
@@ -0,0 +1,23 @@
+package de.romjaki.logger;
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+public class LoggedEvent extends LogEvent {
+ private final Level level;
+ private final String text;
+
+ public LoggedEvent(Class<?> clazz, Level level, String text) {
+ super(clazz);
+ this.level = level;
+ this.text = text;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getText() {
+ return text;
+ }
+}
diff --git a/src/main/java/de/romjaki/logger/Logger.java b/src/main/java/de/romjaki/logger/Logger.java
new file mode 100644
index 0000000..bec0121
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/Logger.java
@@ -0,0 +1,212 @@
+package de.romjaki.logger;
+
+import de.romjaki.logger.impl.LoggerImpl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static de.romjaki.logger.Level.*;
+
+/**
+ * Created by RGR on 17.08.2017.
+ */
+public abstract class Logger {
+ private static String format = "[{LEVEL}][{DATE}]{NAME}: {TEXT}";
+ private static ConcurrentMap<String, Logger> loggers = new ConcurrentHashMap<>();
+ private String name;
+ private Level logLevel = WARNING;
+ private Set<LogHandler> handlers = new HashSet<>();
+ private DateFormat localDateFormat = new SimpleDateFormat(format);
+
+ protected Logger() {
+ this("");
+ }
+
+ protected Logger(String name) {
+ this.name = name;
+ }
+
+ public static Logger getLogger(String name) {
+ return loggers.computeIfAbsent(name.toLowerCase(), LoggerImpl::new);
+ }
+
+ public static Logger getLogger() {
+ return getLogger(getCallingClass().getSimpleName());
+ }
+
+ private static Class<?> getCallingClass() {
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ for (int i = 1; i < trace.length; i++) {
+ StackTraceElement ste = trace[i];
+ if (!ste.getClassName().equals(Logger.class.getName()) && ste.getClassName().indexOf("java.lang.Thread") != 0) {
+ try {
+ return Class.forName(ste.getClassName());
+ } catch (ClassNotFoundException e) { // should never happen. THIS CLASS FUCKING CALLED US!
+ e.printStackTrace();
+ }
+ }
+ }
+ return Logger.class; // Apparently we called ourself since we traversed the entire stack without finding any other classes
+ }
+
+ public void setDateFormat(String newFormat) {
+ setDateFormat(new SimpleDateFormat(newFormat));
+ }
+
+ private void setDateFormat(DateFormat dateFormat) {
+ this.localDateFormat = dateFormat;
+ }
+
+ public void addEventHandler(LogHandler handler) {
+ handlers.add(handler);
+ }
+
+ public Level getLogLevel() {
+ return logLevel;
+ }
+
+ public void setLogLevel(Level logLevel) {
+ this.logLevel = logLevel;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void log(Level level, String text) {
+ if (logLevel.logs(level)) {
+ doLog(level, text);
+ }
+ }
+
+ public void logf(Level level, String format, Object... fillIn) {
+ log(level, String.format(format, fillIn));
+ }
+
+ public void info(String text) {
+ log(INFO, text);
+ }
+
+ public void infof(String format, Object... fillIn) {
+ logf(INFO, format, fillIn);
+ }
+
+ public void warn(String text) {
+ log(WARNING, text);
+ }
+
+ public void warnf(String format, Object... fillIn) {
+ logf(WARNING, format, fillIn);
+ }
+
+ public void debug(String text) {
+ log(DEBUG, text);
+ }
+
+ public void debugf(String format, Object... fillIn) {
+ logf(DEBUG, format, fillIn);
+ }
+
+ public void error(String text) {
+ log(ERROR, text);
+ }
+
+ public void errorf(String format, Object... fillIn) {
+ logf(ERROR, format, fillIn);
+ }
+
+ public void failure(String text) {
+ log(FAILURE, text);
+ }
+
+ public void failuref(String format, Object... fillIn) {
+ logf(Level.FAILURE, format, fillIn);
+ }
+
+ public PrintStream getAsPrintStream() {
+ return getAsPrintStream(ALL);
+ }
+
+ public PrintStream getAsPrintStream(Level level) {
+ return getAsPrintStream(level, System.lineSeparator());
+ }
+
+ public PrintStream getAsPrintStream(Level level, String sep) {
+ return new PrintStream(new OutputStream() {
+ StringBuffer buffer = new StringBuffer();
+
+ final Object locker = new Object();
+
+ @Override
+ public void write(int b) throws IOException {
+ char c = (char) b;
+ synchronized (locker) {
+ buffer.append(c);
+ if (buffer.indexOf(sep) != -1) {
+ String[] splits = buffer.toString().split(sep, 2);
+ log(level, splits[0]);
+ if (splits.length > 1) {
+ buffer = new StringBuffer(splits[1].replace(sep, ""));
+ } else {
+ buffer = new StringBuffer();
+ }
+ }
+ }
+ }
+ }, true);
+ }
+
+ public void exception(Throwable t) {
+ t.printStackTrace(getAsPrintStream(ERROR));
+ }
+
+ private void doLog(Level level, String text) {
+ LogEvent event = new LoggedEvent(getCallingClass(), level, text);
+ dispatchEvent(event);
+ if (!event.isInterrupted()) {
+ println(format
+ .replace("{LEVEL}", level.name())
+ .replace("{DATE}", localDateFormat.format(new Date()))
+ .replace("{NAME}", name != null ? name : "")
+ .replace("{TEXT}", text));
+ }
+ }
+
+ protected void println(String text) {
+ print(text + System.lineSeparator());
+ }
+
+ protected abstract void print(String text);
+
+ protected void dispatchEvent(LogEvent event) {
+ handlers.forEach(handler -> dispatchEvent(event, handler));
+ }
+
+ protected void dispatchEvent(LogEvent event, LogHandler handler) {
+ for (Method method : handler.getClass().getMethods()) {
+ invokeSingle(method, event, handler);
+ }
+ }
+
+ private void invokeSingle(Method method, LogEvent event, LogHandler handler) {
+ if (method.isAnnotationPresent(EventHandler.class)) {
+ Class<?>[] args = method.getParameterTypes();
+ if (args.length == 1 && args[0].isInstance(event)) {
+ try {
+ method.invoke(handler, event);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/de/romjaki/logger/impl/FileLogger.java b/src/main/java/de/romjaki/logger/impl/FileLogger.java
new file mode 100644
index 0000000..b7c8f3f
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/impl/FileLogger.java
@@ -0,0 +1,27 @@
+package de.romjaki.logger.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class FileLogger extends StreamLogger {
+ public FileLogger(String name, File file) throws IOException {
+ super(name, new FileOutputStream(createFile(file)));
+ }
+
+ public FileLogger(File file) throws IOException {
+ super(new FileOutputStream(createFile(file)));
+ }
+
+ private static File createFile(File file) throws IOException {
+ if (!file.getParentFile().exists()) {
+ file.getParentFile().mkdirs();
+ }
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ return file;
+ }
+
+
+}
diff --git a/src/main/java/de/romjaki/logger/impl/LoggerImpl.java b/src/main/java/de/romjaki/logger/impl/LoggerImpl.java
new file mode 100644
index 0000000..e581f53
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/impl/LoggerImpl.java
@@ -0,0 +1,12 @@
+package de.romjaki.logger.impl;
+
+
+public class LoggerImpl extends StreamLogger {
+ public LoggerImpl(String name) {
+ super(name, System.out);
+ }
+
+ public LoggerImpl() {
+ super(System.out);
+ }
+}
diff --git a/src/main/java/de/romjaki/logger/impl/StreamLogger.java b/src/main/java/de/romjaki/logger/impl/StreamLogger.java
new file mode 100644
index 0000000..9428dfe
--- /dev/null
+++ b/src/main/java/de/romjaki/logger/impl/StreamLogger.java
@@ -0,0 +1,38 @@
+package de.romjaki.logger.impl;
+
+import de.romjaki.logger.Logger;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+public class StreamLogger extends Logger {
+ private Writer writer;
+
+ public StreamLogger(String name, OutputStream outputStream) {
+ this(name, new OutputStreamWriter(outputStream));
+ }
+
+ public StreamLogger(String name, Writer writer) {
+ super(name);
+ this.writer = writer;
+ }
+
+ public StreamLogger(OutputStream outputStream) {
+ this(new OutputStreamWriter(outputStream));
+ }
+
+ public StreamLogger(Writer writer) {
+ this.writer = writer;
+ }
+
+ @Override
+ protected void print(String text) {
+ try {
+ writer.write(text);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}