0

Only use ColorMapper if jansi is present, ignore it if not

This change allows slf4bukkit to run on Bukkit implementations without jansi by making ColorMapper optional: If it cannot be initialized, colors are not mapped. Instead this may (or may not) be done by the Bukkit implementation, that alos handles the logging system everything the output of slf4bukkit is to.
This commit is contained in:
TheE
2017-07-15 00:28:56 +02:00
parent e68d229674
commit 50c1303034
2 changed files with 68 additions and 19 deletions

View File

@@ -16,13 +16,13 @@
*/ */
package info.ronjenkins.slf4bukkit; package info.ronjenkins.slf4bukkit;
import java.util.Map; import com.google.common.collect.ImmutableMap;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.fusesource.jansi.Ansi; import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Attribute; 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, * 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 { public final class ColorMapper {
private ColorMapper() {
}
// @formatter:off // @formatter:off
private static final Map<ChatColor, String> MAP = ImmutableMap.<ChatColor, String>builder() private final Map<ChatColor, String> MAP = ImmutableMap.<ChatColor, String>builder()
.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()) .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_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()) .put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString())
@@ -59,20 +62,47 @@ public final class ColorMapper {
.build(); .build();
// @formatter:on // @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. * Translates {@link ChatColor} directives to their JAnsi equivalents.
* *
* @param input * @param input null is coerced to the empty string.
* null is coerced to the empty string.
* @return never null. * @return never null.
*/ */
public static String map(final String input) { public String map(final String input) {
if (input == null) { return ""; } if (input == null) {
return "";
}
String output = input; String output = input;
for (final Map.Entry<ChatColor, String> mapping : ColorMapper.MAP.entrySet()) { for (final Map.Entry<ChatColor, String> mapping : MAP.entrySet()) {
output = output.replace(mapping.getKey().toString(), mapping.getValue()); output = output.replace(mapping.getKey().toString(), mapping.getValue());
} }
return output; 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);
}
}
} }

View File

@@ -44,17 +44,11 @@
*/ */
package org.slf4j.impl; package org.slf4j.impl;
import com.google.common.collect.ImmutableMap;
import info.ronjenkins.slf4bukkit.ColorMapper; import info.ronjenkins.slf4bukkit.ColorMapper;
import info.ronjenkins.slf4bukkit.ColorMarker; 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.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@@ -67,7 +61,13 @@ import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter; import org.slf4j.helpers.MessageFormatter;
import org.yaml.snakeyaml.Yaml; 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;
/** /**
* <p> * <p>
@@ -219,11 +219,22 @@ public final class BukkitLoggerAdapter implements Logger {
private final String name; private final String name;
// The short name of this simple log instance // The short name of this simple log instance
private transient String shortLogName = null; private transient String shortLogName = null;
private final ThreadLocal<ColorMapper> mapper;
// NOTE: BukkitPluginLoggerAdapter constructor should have only package access // NOTE: BukkitPluginLoggerAdapter constructor should have only package access
// so that only BukkitPluginLoggerFactory be able to create one. // so that only BukkitPluginLoggerFactory be able to create one.
BukkitLoggerAdapter(final String name) { BukkitLoggerAdapter(final String name) {
this.name = name; this.name = name;
this.mapper = new ThreadLocal<ColorMapper>() {
@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 * @param property
* the config property where the map exists. * the config property where the map exists.
* @param defaultValue * @param defaultValues
* the fallback values returned by this method. * the fallback values returned by this method.
* @return never null, always contains one mapping for each {@link Level}, and * @return never null, always contains one mapping for each {@link Level}, and
* contains no null keys/values. Equal to {@code defaultValue} if the * contains no null keys/values. Equal to {@code defaultValue} if the
@@ -1043,6 +1054,14 @@ public final class BukkitLoggerAdapter implements Logger {
// Log the message. // Log the message.
logger.log(BukkitLoggerAdapter.slf4jLevelIntToBukkitJULLevel(level), 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;
} }
} }