[main] Attempt to provide the new APIs through the old interface again

This commit is contained in:
Johannes Frohnmeyer 2022-06-23 15:23:35 +02:00
parent e50ddd7d82
commit 63343085d4
Signed by: Johannes
GPG Key ID: E76429612C2929F4
10 changed files with 166 additions and 154 deletions

View File

@ -2,10 +2,10 @@ package io.gitlab.jfronny.commons.log;
import org.slf4j.LoggerFactory;
public class SLF4JLogStrategy implements LogStrategy {
public class SLF4JLogger implements Logger {
private final org.slf4j.Logger logger;
public SLF4JLogStrategy(String name) {
public SLF4JLogger(String name) {
this.logger = LoggerFactory.getLogger(name);
}

View File

@ -9,11 +9,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class SLFLogStrategyTest {
@BeforeEach
void prepare() {
Logger.resetStrategy();
HotSwappingDelegateLogger.resetStrategy();
}
@Test
void testFactory() {
assertEquals(SLF4JLogStrategy.class, Logger.forName("Joe").getDelegate().getClass());
assertEquals(SLF4JLogger.class, HotSwappingDelegateLogger.forName("Joe").getDelegate().getClass());
}
}

View File

@ -2,16 +2,16 @@ package io.gitlab.jfronny.commons.log;
import org.jetbrains.annotations.*;
public class DelegateLogStrategy implements LogStrategy {
public DelegateLogStrategy() {
public class DelegateLogger implements Logger {
public DelegateLogger() {
this(null);
}
public DelegateLogStrategy(LogStrategy delegate) {
public DelegateLogger(Logger delegate) {
this.delegate = delegate;
}
protected LogStrategy delegate;
protected Logger delegate;
@Override
public @Nullable String getName() {
@ -133,7 +133,7 @@ public class DelegateLogStrategy implements LogStrategy {
return delegate.format(msg, t);
}
public LogStrategy getDelegate() {
public Logger getDelegate() {
return delegate;
}
}

View File

@ -0,0 +1,54 @@
package io.gitlab.jfronny.commons.log;
import io.gitlab.jfronny.commons.ref.*;
import io.gitlab.jfronny.commons.reflect.Reflect;
import org.jetbrains.annotations.*;
import java.util.*;
import java.util.function.Function;
public class HotSwappingDelegateLogger extends DelegateLogger {
public static Function<String, Logger> LOGGER_BUILDER;
private static final Set<HotSwappingDelegateLogger> KNOWN_LOGGERS = new WeakSet<>();
static {
resetStrategy();
}
public static void resetStrategy() {
try {
LOGGER_BUILDER = Reflect.<String, Logger>getConstructor("io.gitlab.jfronny.commons.log.SLF4JLogger", String.class)
.orThrow();
} catch (ClassNotFoundException | NoSuchMethodException e) {
// SLF4J logger is unavailable, use java.util.logging
LOGGER_BUILDER = JavaUtilLogger::new;
}
}
public static void updateStrategy(@NotNull Function<String, Logger> factory) {
LOGGER_BUILDER = Objects.requireNonNull(factory);
synchronized (KNOWN_LOGGERS) {
for (HotSwappingDelegateLogger ref : KNOWN_LOGGERS) {
ref.updateStrategy();
}
}
}
public static HotSwappingDelegateLogger forName(@NotNull String name) {
return new HotSwappingDelegateLogger(name);
}
private final String name;
private HotSwappingDelegateLogger(String name) {
this.name = name;
updateStrategy();
synchronized (KNOWN_LOGGERS) {
KNOWN_LOGGERS.add(this);
}
}
private void updateStrategy() {
delegate = LOGGER_BUILDER.apply(name);
}
}

View File

@ -2,10 +2,10 @@ package io.gitlab.jfronny.commons.log;
import java.util.logging.Level;
public class JavaUtilLogStrategy implements LogStrategy {
public class JavaUtilLogger implements Logger {
private final java.util.logging.Logger logger;
public JavaUtilLogStrategy(String name) {
public JavaUtilLogger(String name) {
this.logger = java.util.logging.Logger.getLogger(name);
}

View File

@ -1,92 +0,0 @@
package io.gitlab.jfronny.commons.log;
import io.gitlab.jfronny.commons.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
public interface LogStrategy {
@Nullable String getName();
default void trace(String msg) {
debug(msg);
}
default void trace(String format, Object arg) {
trace(format(format, arg));
}
default void trace(String format, Object... args) {
trace(format(format, args));
}
default void trace(String msg, Throwable t) {
trace(format(msg, t));
}
default void debug(String msg) {
info(msg);
}
default void debug(String format, Object arg) {
debug(format(format, arg));
}
default void debug(String format, Object... args) {
debug(format(format, args));
}
default void debug(String msg, Throwable t) {
debug(format(msg, t));
}
void info(String msg);
default void info(String format, Object arg) {
info(format(format, arg));
}
default void info(String format, Object... args) {
info(format(format, args));
}
default void info(String msg, Throwable t) {
info(format(msg, t));
}
default void warn(String msg) {
info(msg);
}
default void warn(String format, Object arg) {
warn(format(format, arg));
}
default void warn(String format, Object... args) {
warn(format(format, args));
}
default void warn(String msg, Throwable t) {
warn(format(msg, t));
}
default void error(String msg) {
warn(msg);
}
default void error(String format, Object arg) {
error(format(format, arg));
}
default void error(String format, Object... args) {
error(format(format, args));
}
default void error(String msg, Throwable t) {
error(format(msg, t));
}
default String format(String format, Object arg) {
return format.replaceFirst("\\{}", StringFormatter.toString(arg));
}
default String format(String format, Object... args) {
if (args == null || format == null) return format;
for (Object arg : args) {
format = format.replaceFirst("\\{}", StringFormatter.toString(arg));
}
return format;
}
default String format(String msg, Throwable t) {
if (t == null) return msg;
return msg + System.lineSeparator() + t;
}
}

View File

@ -1,54 +1,104 @@
package io.gitlab.jfronny.commons.log;
import io.gitlab.jfronny.commons.ref.*;
import io.gitlab.jfronny.commons.reflect.Reflect;
import org.jetbrains.annotations.*;
import io.gitlab.jfronny.commons.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Objects;
import java.util.function.Function;
public class Logger extends DelegateLogStrategy {
public static Function<String, LogStrategy> LOGGER_BUILDER;
private static final Set<Logger> KNOWN_LOGGERS = new WeakSet<>();
static {
resetStrategy();
public interface Logger {
static Logger forName(@NotNull String name) {
return HotSwappingDelegateLogger.forName(Objects.requireNonNull(name));
}
public static void resetStrategy() {
try {
LOGGER_BUILDER = Reflect.<String, LogStrategy>getConstructor("io.gitlab.jfronny.commons.log.SLF4JLogStrategy", String.class)
.orThrow();
} catch (ClassNotFoundException | NoSuchMethodException e) {
// SLF4J logger is unavailable, use java.util.logging
LOGGER_BUILDER = JavaUtilLogStrategy::new;
static void registerFactory(@NotNull Function<String, Logger> factory) {
HotSwappingDelegateLogger.updateStrategy(Objects.requireNonNull(factory));
}
static void resetFactory() {
HotSwappingDelegateLogger.resetStrategy();
}
@Nullable String getName();
default void trace(String msg) {
debug(msg);
}
default void trace(String format, Object arg) {
trace(format(format, arg));
}
default void trace(String format, Object... args) {
trace(format(format, args));
}
default void trace(String msg, Throwable t) {
trace(format(msg, t));
}
default void debug(String msg) {
info(msg);
}
default void debug(String format, Object arg) {
debug(format(format, arg));
}
default void debug(String format, Object... args) {
debug(format(format, args));
}
default void debug(String msg, Throwable t) {
debug(format(msg, t));
}
void info(String msg);
default void info(String format, Object arg) {
info(format(format, arg));
}
default void info(String format, Object... args) {
info(format(format, args));
}
default void info(String msg, Throwable t) {
info(format(msg, t));
}
default void warn(String msg) {
info(msg);
}
default void warn(String format, Object arg) {
warn(format(format, arg));
}
default void warn(String format, Object... args) {
warn(format(format, args));
}
default void warn(String msg, Throwable t) {
warn(format(msg, t));
}
default void error(String msg) {
warn(msg);
}
default void error(String format, Object arg) {
error(format(format, arg));
}
default void error(String format, Object... args) {
error(format(format, args));
}
default void error(String msg, Throwable t) {
error(format(msg, t));
}
default String format(String format, Object arg) {
return format.replaceFirst("\\{}", StringFormatter.toString(arg));
}
default String format(String format, Object... args) {
if (args == null || format == null) return format;
for (Object arg : args) {
format = format.replaceFirst("\\{}", StringFormatter.toString(arg));
}
return format;
}
public static void updateStrategy(@NotNull Function<String, LogStrategy> factory) {
LOGGER_BUILDER = Objects.requireNonNull(factory);
synchronized (KNOWN_LOGGERS) {
for (Logger ref : KNOWN_LOGGERS) {
ref.updateStrategy();
}
}
}
public static Logger forName(@NotNull String name) {
return new Logger(name);
}
private final String name;
Logger(String name) {
this.name = name;
updateStrategy();
synchronized (KNOWN_LOGGERS) {
KNOWN_LOGGERS.add(this);
}
}
private void updateStrategy() {
delegate = LOGGER_BUILDER.apply(name);
default String format(String msg, Throwable t) {
if (t == null) return msg;
return msg + System.lineSeparator() + t;
}
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.commons.log;
public class NopLogStrategy implements LogStrategy {
public class NopLogger implements Logger {
@Override
public String getName() {
return null;

View File

@ -1,10 +1,10 @@
package io.gitlab.jfronny.commons.log;
public class StdoutLogStrategy implements LogStrategy {
public class StdoutLogger implements Logger {
private final String name;
private final String prefix;
public StdoutLogStrategy(String name) {
public StdoutLogger(String name) {
this.name = name;
this.prefix = "[" + name + "] ";
}

View File

@ -8,19 +8,19 @@ import static org.junit.jupiter.api.Assertions.*;
public class LoggerTest {
@BeforeEach
void prepare() {
Logger.resetStrategy();
Logger.resetFactory();
}
@Test
void testFactory() {
assertEquals(JavaUtilLogStrategy.class, Logger.forName("Joe").getDelegate().getClass());
assertEquals(JavaUtilLogger.class, assertInstanceOf(HotSwappingDelegateLogger.class, Logger.forName("Joe")).getDelegate().getClass());
}
@Test
void testRegisterFactory() {
Logger logger = Logger.forName("Joe");
assertEquals(JavaUtilLogStrategy.class, logger.getDelegate().getClass());
Logger.updateStrategy(s -> new NopLogStrategy());
assertEquals(NopLogStrategy.class, logger.getDelegate().getClass());
HotSwappingDelegateLogger logger = assertInstanceOf(HotSwappingDelegateLogger.class, Logger.forName("Joe"));
assertEquals(JavaUtilLogger.class, logger.getDelegate().getClass());
Logger.registerFactory(s -> new NopLogger());
assertEquals(NopLogger.class, logger.getDelegate().getClass());
}
}