Skip to content

Commit

Permalink
Some refactoring of pattern config
Browse files Browse the repository at this point in the history
  • Loading branch information
agentgt committed Apr 22, 2024
1 parent 717a526 commit c12739d
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static LogEncoderRegistry of() {

final class DefaultEncoderRegistry implements LogEncoderRegistry {

protected final Map<String, EncoderProvider> providers = new ConcurrentHashMap<>();
private final Map<String, EncoderProvider> providers = new ConcurrentHashMap<>();

private static URI normalize(URI uri) {
String scheme = uri.getScheme();
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/io/jstach/rainbowgum/LogProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ public interface LogProperties {
*/
static final String NAME = "name";

/**
* For properties keys that are parameterized with {@value #NAME} the name often used
* if not specified is: {@value #DEFAULT_NAME}.
*/
static final String DEFAULT_NAME = "default";

/**
* Logging output prefix for configuration.
*/
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/io/jstach/rainbowgum/LogRouter.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ sealed interface Router extends LogRouter, LogEventLogger {
/**
* The router name given if no router is explicitly declared.
*/
public static final String DEFAULT_ROUTER_NAME = "default";
public static final String DEFAULT_ROUTER_NAME = LogProperties.DEFAULT_NAME;

/**
* Level resolver.
Expand Down
47 changes: 22 additions & 25 deletions core/src/main/java/io/jstach/rainbowgum/ServiceRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@

/**
* A simple service locator for initialization purposes and external services provided by
* plugins.
* plugins. <strong> If there is no suitable <code>name</code> for the service use
* {@value #DEFAULT_SERVICE_NAME}. </strong>
*/
public sealed interface ServiceRegistry extends AutoCloseable permits DefaultServiceRegistry {

/**
* Services that do not have multiple options or need a default should use
* {@value #DEFAULT_SERVICE_NAME}.
*/
static final String DEFAULT_SERVICE_NAME = LogProperties.DEFAULT_NAME;

/**
* Creates an empty service registry.
* @return registry.
Expand All @@ -28,29 +35,30 @@ public static ServiceRegistry of() {
* Puts a service.
* @param <T> service type.
* @param type type.
* @param service service instance.
* @param name name of service.
* @param service service instance.
*/
public <T> void put(Class<T> type, T service, String name);
public <T> void put(Class<T> type, String name, T service);

/**
* Puts a service.
* @param <T> service type.
* @param type type.
* @param supplier service instance.
* @return service.
* @param service service instance.
*/
public <T> T putIfAbsent(Class<T> type, Supplier<T> supplier);
default <T> void put(Class<T> type, T service) {
put(type, DEFAULT_SERVICE_NAME, service);
}

/**
* Puts a service with name "".
* Puts a service.
* @param <T> service type.
* @param type type.
* @param service service instance.
* @param name name of the service.
* @param supplier service instance.
* @return service.
*/
default <T> void put(Class<T> type, T service) {
put(type, service, "");
}
public <T> T putIfAbsent(Class<T> type, String name, Supplier<T> supplier);

/**
* Finds a service or null.
Expand All @@ -62,17 +70,6 @@ default <T> void put(Class<T> type, T service) {
@SuppressWarnings("exports")
public <T> @Nullable T findOrNull(Class<T> type, String name);

/**
* Finds a service or null.
* @param <T> service type.
* @param type service class.
* @return service or <code>null</code>.
*/
@SuppressWarnings("exports")
default <T> @Nullable T findOrNull(Class<T> type) {
return findOrNull(type, "");
}

/**
* Finds <strong>all</strong> services of a specific type.
* @param <T> service type.
Expand Down Expand Up @@ -122,7 +119,7 @@ final class DefaultServiceRegistry implements ServiceRegistry {
private final CopyOnWriteArrayList<AutoCloseable> closeables = new CopyOnWriteArrayList<>();

@Override
public <T> void put(Class<T> type, T service, String name) {
public <T> void put(Class<T> type, String name, T service) {
if (service == null) {
throw new NullPointerException("service");
}
Expand All @@ -145,8 +142,8 @@ public <T> List<T> find(Class<T> type) {

@SuppressWarnings("unchecked")
@Override
public <T> T putIfAbsent(Class<T> type, Supplier<T> supplier) {
var t = (T) services.computeIfAbsent(new ServiceKey(type, ""), k -> Objects.requireNonNull(supplier.get()));
public <T> T putIfAbsent(Class<T> type, String name, Supplier<T> supplier) {
var t = (T) services.computeIfAbsent(new ServiceKey(type, name), k -> Objects.requireNonNull(supplier.get()));
return t;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public List<LogProperties> provideProperties(ServiceRegistry registry) {
@Override
public boolean configure(LogConfig config) {
var registry = config.serviceRegistry();
var props = registry.findOrNull(AvajeProperties.class);
var props = registry.findOrNull(AvajeProperties.class, ServiceRegistry.DEFAULT_SERVICE_NAME);
if (props != null) {
props.configuration.onChange(e -> {
config.changePublisher().publish();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package io.jstach.rainbowgum.pattern.format;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream;

import io.jstach.rainbowgum.LogFormatter;
import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogProperty;
import io.jstach.rainbowgum.LogProvider;
import io.jstach.rainbowgum.ServiceRegistry;
import io.jstach.rainbowgum.pattern.format.PatternFormatterFactory.CompositeFactory;
import io.jstach.rainbowgum.pattern.format.PatternFormatterFactory.KeywordFactory;
import io.jstach.rainbowgum.pattern.internal.Node;
import io.jstach.rainbowgum.pattern.internal.Parser;
import io.jstach.rainbowgum.pattern.internal.ScanException;
import io.jstach.rainbowgum.pattern.internal.Node.CompositeNode;
import io.jstach.rainbowgum.pattern.internal.Node.End;
import io.jstach.rainbowgum.pattern.internal.Node.FormattingNode;
import io.jstach.rainbowgum.pattern.internal.Node.KeywordNode;
import io.jstach.rainbowgum.pattern.internal.Node.LiteralNode;
import io.jstach.rainbowgum.pattern.internal.Parser;
import io.jstach.rainbowgum.pattern.internal.ScanException;

/**
* Compiles a pattern into a formatter.
Expand All @@ -33,6 +41,43 @@ public static Builder builder() {
return new Builder();
}

/**
* Creates a pattern compiler provider from a builder lambda.
* @param consumer builder will be provided to the consumer.
* @return provider of pattern compiler.
*/
public static LogProvider<PatternCompiler> of(Consumer<Builder> consumer) {
return (name, config) -> {
var services = config.serviceRegistry();
var registry = findService(services, PatternRegistry.class, name, LogProperties.DEFAULT_NAME)
.orElseGet(() -> PatternRegistry.of());
var patternConfig = findService(services, PatternConfig.class, name, LogProperties.DEFAULT_NAME)
.orElseGet(() -> {
boolean ansiDisable = LogProperty.Property.builder() //
.toBoolean() //
.orElse(false) //
.build(LogProperties.GLOBAL_ANSI_DISABLE_PROPERTY) //
.get(config.properties()) //
.value();
var b = PatternConfig.builder().fromProperties(config.properties());
if (ansiDisable) {
b.ansiDisabled(true);
}
return b.build();
});
Builder b = builder();
b.patternRegistry(registry);
b.patternConfig(patternConfig);
consumer.accept(b);
return b.build();
};
}

private static <T> Optional<T> findService(ServiceRegistry services, Class<T> c, String... names) {
Stream<String> sn = Stream.of(names);
return sn.flatMap(s -> Stream.ofNullable(services.findOrNull(c, s))).findFirst();
}

/**
* Builder for {@link PatternCompiler}.
*/
Expand All @@ -43,7 +88,6 @@ public final static class Builder {
private PatternConfig patternConfig;

private Builder() {

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import io.jstach.rainbowgum.LogConfig;
import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.ServiceRegistry;
import io.jstach.rainbowgum.spi.RainbowGumServiceProvider.Configurator;

/**
Expand All @@ -23,7 +24,7 @@ public sealed interface PatternConfig extends Configurator {
/**
* Formatter properties prefix
*/
public static final String PATTERN_CONFIG_PREFIX = LogProperties.ROOT_PREFIX + "pattern.config.";
public static final String PATTERN_CONFIG_PREFIX = LogProperties.ROOT_PREFIX + "pattern.config.{name}.";

/**
* Default zoneId if not specified.
Expand Down Expand Up @@ -51,7 +52,18 @@ public sealed interface PatternConfig extends Configurator {
* registered at config time easily.
*/
public static PatternConfigBuilder builder() {
return new PatternConfigBuilder();
return builder(LogProperties.DEFAULT_NAME);
}

/**
* Creates a builder to create formatter config.
* @param name for property resolution: {@value #PATTERN_CONFIG_PREFIX}.
* @return builder.
* @apiNote {@link PatternConfig} implements {@link Configurator} so it can be
* registered at config time easily.
*/
public static PatternConfigBuilder builder(String name) {
return new PatternConfigBuilder(name);
}

/**
Expand Down Expand Up @@ -87,7 +99,7 @@ public static PatternConfig ofUniversal() {

@Override
default boolean configure(LogConfig config) {
config.serviceRegistry().put(PatternConfig.class, this);
config.serviceRegistry().put(PatternConfig.class, ServiceRegistry.DEFAULT_SERVICE_NAME, this);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import io.jstach.rainbowgum.LogConfig;
import io.jstach.rainbowgum.LogEncoder;
import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogProperty;
import io.jstach.rainbowgum.LogProvider;
import io.jstach.rainbowgum.LogProviderRef;
import io.jstach.rainbowgum.ServiceRegistry;
import io.jstach.rainbowgum.annotation.LogConfigurable;
import io.jstach.rainbowgum.annotation.LogConfigurable.ConvertParameter;
import io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter;
Expand All @@ -34,46 +34,32 @@ public PatternConfigurator() {

@Override
public boolean configure(LogConfig config) {
var compiler = compiler(config);
config.encoderRegistry().register(PatternEncoder.PATTERN_SCHEME, new PatternEncoderProvider(compiler));
var services = config.serviceRegistry();
String n = ServiceRegistry.DEFAULT_SERVICE_NAME;
services.putIfAbsent(PatternRegistry.class, n, PatternRegistry::of);
services.putIfAbsent(PatternCompiler.class, n, () -> PatternCompiler.of(b -> {
}).provide(n, config));
config.encoderRegistry().register(PatternEncoder.PATTERN_SCHEME, new PatternEncoderProvider());
return true;
}

static PatternCompiler compiler(LogConfig config) {
var registry = config.serviceRegistry().putIfAbsent(PatternRegistry.class, () -> PatternRegistry.of());
boolean ansiDisable = LogProperty.Property.builder() //
.toBoolean() //
.orElse(false) //
.build(LogProperties.GLOBAL_ANSI_DISABLE_PROPERTY) //
.get(config.properties()) //
.value();
var patternConfig = config.serviceRegistry().putIfAbsent(PatternConfig.class, () -> {
var b = PatternConfig.builder().fromProperties(config.properties());
if (ansiDisable) {
b.ansiDisabled(true);
}
return b.build();
});
var compiler = config.serviceRegistry()
.putIfAbsent(PatternCompiler.class, () -> new Compiler(registry, patternConfig));
return compiler;
}

@LogConfigurable(name = "PatternEncoderBuilder", prefix = LogProperties.ENCODER_PREFIX)
static LogProvider<LogEncoder> provideEncoder(@KeyParameter String name, String pattern,
@PassThroughParameter @Nullable PatternCompiler patternCompiler) {
return (n, config) -> {
var compiler = patternCompiler;
if (compiler == null) {
compiler = PatternConfigurator.compiler(config);
compiler = PatternCompiler.of(b -> {
}).provide(name, config);
}
return LogEncoder.of(compiler.compile(pattern));
};
}

@LogConfigurable(name = "PatternConfigBuilder", prefix = PatternConfig.PATTERN_CONFIG_PREFIX)
static PatternConfig provideFormatterConfig(@ConvertParameter("convertZoneId") @Nullable ZoneId zoneId,
@Nullable String lineSeparator, @Nullable Boolean ansiDisabled) {
static PatternConfig provideFormatterConfig(@KeyParameter String name,
@ConvertParameter("convertZoneId") @Nullable ZoneId zoneId, @Nullable String lineSeparator,
@Nullable Boolean ansiDisabled) {
PatternConfig dc = PatternConfig.of();
ansiDisabled = ansiDisabled == null ? dc.ansiDisabled() : ansiDisabled;
lineSeparator = lineSeparator == null ? dc.lineSeparator() : lineSeparator;
Expand All @@ -89,7 +75,7 @@ static ZoneId convertZoneId(@Nullable String zoneId) {

}

record PatternEncoderProvider(PatternCompiler compiler) implements LogEncoder.EncoderProvider {
record PatternEncoderProvider() implements LogEncoder.EncoderProvider {

@Override
public LogProvider<LogEncoder> provide(LogProviderRef ref) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.jstach.rainbowgum.pattern.format.spi;

import io.jstach.rainbowgum.LogConfig;
import io.jstach.rainbowgum.ServiceRegistry;
import io.jstach.rainbowgum.pattern.format.PatternRegistry;
import io.jstach.rainbowgum.spi.RainbowGumServiceProvider;
import io.jstach.rainbowgum.spi.RainbowGumServiceProvider.Configurator;
Expand All @@ -20,7 +21,8 @@ public PatternKeywordProvider() {

@Override
public boolean configure(LogConfig config) {
PatternRegistry patternRegistry = config.serviceRegistry().findOrNull(PatternRegistry.class);
PatternRegistry patternRegistry = config.serviceRegistry()
.findOrNull(PatternRegistry.class, ServiceRegistry.DEFAULT_SERVICE_NAME);
if (patternRegistry == null) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public LoggerDecoratorService() {

@Override
public final boolean configure(LogConfig config) {
config.serviceRegistry().put(LoggerDecoratorService.class, this, name());
config.serviceRegistry().put(LoggerDecoratorService.class, name(), this);
return true;
}

Expand Down

0 comments on commit c12739d

Please sign in to comment.