diff --git a/src/main/java/info/ronjenkins/slf4bukkit/ColorMapper.java b/src/main/java/info/ronjenkins/slf4bukkit/ColorMapper.java index 506b490..31bc706 100644 --- a/src/main/java/info/ronjenkins/slf4bukkit/ColorMapper.java +++ b/src/main/java/info/ronjenkins/slf4bukkit/ColorMapper.java @@ -16,13 +16,13 @@ */ package info.ronjenkins.slf4bukkit; -import java.util.Map; +import com.google.common.collect.ImmutableMap; import org.bukkit.ChatColor; import org.fusesource.jansi.Ansi; import org.fusesource.jansi.Ansi.Attribute; -import com.google.common.collect.ImmutableMap; +import java.util.Map; /** * Utility class that maps {@link ChatColor} values to their JAnsi equivalents, @@ -32,8 +32,11 @@ import com.google.common.collect.ImmutableMap; */ public final class ColorMapper { + private ColorMapper() { + } + // @formatter:off - private static final Map MAP = ImmutableMap.builder() + private final Map MAP = ImmutableMap.builder() .put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()) .put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString()) .put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString()) @@ -59,20 +62,47 @@ public final class ColorMapper { .build(); // @formatter:on + /** + * Attempts to create a new ColorMapper. + * + * @return a new ColorMapper instance + * @throws UnsupportedByBukkitImplementationException if colorMapping is not supported on the BukkitImplementation on + * which this method is called + */ + public static ColorMapper create() throws UnsupportedByBukkitImplementationException { + try { + return new ColorMapper(); + } catch (Throwable e) { + throw new UnsupportedByBukkitImplementationException(e); + } + + } + /** * Translates {@link ChatColor} directives to their JAnsi equivalents. * - * @param input - * null is coerced to the empty string. + * @param input null is coerced to the empty string. * @return never null. */ - public static String map(final String input) { - if (input == null) { return ""; } + public String map(final String input) { + if (input == null) { + return ""; + } String output = input; - for (final Map.Entry mapping : ColorMapper.MAP.entrySet()) { + for (final Map.Entry mapping : MAP.entrySet()) { output = output.replace(mapping.getKey().toString(), mapping.getValue()); } return output; } + /** + * Thrown when an operation is not supported by the Bukkit implementation the operation runs on. + */ + public static class UnsupportedByBukkitImplementationException extends Exception { + + private UnsupportedByBukkitImplementationException(Throwable e) { + super(e); + } + } + } diff --git a/src/main/java/org/slf4j/impl/BukkitLoggerAdapter.java b/src/main/java/org/slf4j/impl/BukkitLoggerAdapter.java index 9ffb5e9..50d3bb2 100644 --- a/src/main/java/org/slf4j/impl/BukkitLoggerAdapter.java +++ b/src/main/java/org/slf4j/impl/BukkitLoggerAdapter.java @@ -44,17 +44,11 @@ */ package org.slf4j.impl; +import com.google.common.collect.ImmutableMap; + import info.ronjenkins.slf4bukkit.ColorMapper; import info.ronjenkins.slf4bukkit.ColorMarker; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.commons.lang.exception.ExceptionUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -67,7 +61,13 @@ import org.slf4j.helpers.FormattingTuple; import org.slf4j.helpers.MessageFormatter; import org.yaml.snakeyaml.Yaml; -import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** *

@@ -219,11 +219,22 @@ public final class BukkitLoggerAdapter implements Logger { private final String name; // The short name of this simple log instance private transient String shortLogName = null; + private final ThreadLocal mapper; // NOTE: BukkitPluginLoggerAdapter constructor should have only package access // so that only BukkitPluginLoggerFactory be able to create one. BukkitLoggerAdapter(final String name) { this.name = name; + this.mapper = new ThreadLocal() { + @Override + protected ColorMapper initialValue() { + try { + return ColorMapper.create(); + } catch (ColorMapper.UnsupportedByBukkitImplementationException ignore) { + return null; + } + } + }; } /** @@ -352,7 +363,7 @@ public final class BukkitLoggerAdapter implements Logger { * * @param property * the config property where the map exists. - * @param defaultValue + * @param defaultValues * the fallback values returned by this method. * @return never null, always contains one mapping for each {@link Level}, and * contains no null keys/values. Equal to {@code defaultValue} if the @@ -1043,6 +1054,14 @@ public final class BukkitLoggerAdapter implements Logger { // Log the message. logger.log(BukkitLoggerAdapter.slf4jLevelIntToBukkitJULLevel(level), - ColorMapper.map(buf.toString())); + mapColors(buf.toString())); + } + + private String mapColors(String input) { + ColorMapper colorMapper = mapper.get(); + if (colorMapper != null) { + return colorMapper.map(input); + } + return input; } }