ForwardingLogProperties.java
package io.jstach.rainbowgum.properties;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import org.jspecify.annotations.Nullable;
import io.jstach.rainbowgum.LogProperties;
import io.jstach.rainbowgum.LogReporter;
/**
* Properties that forward every lookup to a delegate, for writing decorators that observe
* or change lookups.
* <p>
* {@link #valueOrNull(String)}, {@link #listOrNull(String)}, {@link #mapOrNull(String)},
* {@link #visit(String, BiFunction)}, {@link #description(String)}, {@link #order()}, and
* {@link #report(Appendable)} forward to {@link #delegate()}. When the delegate's
* {@code visit} passes the delegate itself to the visitor, this properties is passed
* instead, so lookups that go through {@code visit}, such as
* {@link LogProperties#forKey(String)}, reach the methods of this properties. The other
* methods are the {@link LogProperties} defaults, which are built on these.
*/
public abstract class ForwardingLogProperties implements LogProperties, LogReporter.Reportable {
/**
* For subclasses.
*/
protected ForwardingLogProperties() {
}
/**
* The properties lookups are forwarded to.
* @return delegate.
*/
protected abstract LogProperties delegate();
@Override
public @Nullable String valueOrNull(String key) {
return delegate().valueOrNull(key);
}
@Override
public @Nullable List<String> listOrNull(String key) {
return delegate().listOrNull(key);
}
@Override
public @Nullable Map<String, String> mapOrNull(String key) {
return delegate().mapOrNull(key);
}
// Identity on purpose: only the delegate passing itself is replaced.
@SuppressWarnings("ReferenceEquality")
@Override
public <R extends @Nullable Object> @Nullable R visit(String key,
BiFunction<LogProperties, String, @Nullable R> visitor) {
var delegate = delegate();
return delegate.visit(key, (source, sourceKey) -> visitor.apply(source == delegate ? this : source, sourceKey));
}
@Override
public String description(String key) {
return delegate().description(key);
}
@Override
public int order() {
return delegate().order();
}
@Override
public void report(Appendable out) throws IOException {
if (delegate() instanceof LogReporter.Reportable r) {
r.report(out);
}
else {
out.append(delegate().toString());
}
}
@Override
public String toString() {
return getClass().getSimpleName() + "[" + delegate() + "]";
}
}