Refactor for ConsoleAppender (and others next) to use inherited Builders. Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2207cae2 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2207cae2 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2207cae2
Branch: refs/heads/LOG4J2-1010&LOG4J2-1447-injectable-contextdata&better-datastructure Commit: 2207cae2a1213fda34cf94e5f08c49c2c9433e50 Parents: e3e37cc Author: Gary Gregory <ggreg...@apache.org> Authored: Wed Aug 10 20:09:29 2016 -0700 Committer: Gary Gregory <ggreg...@apache.org> Committed: Wed Aug 10 20:09:29 2016 -0700 ---------------------------------------------------------------------- .../log4j/core/appender/AbstractAppender.java | 58 +++++++++++++++ .../appender/AbstractOutputStreamAppender.java | 21 ++++++ .../log4j/core/appender/ConsoleAppender.java | 78 +++++++------------- .../log4j/core/filter/AbstractFilterable.java | 27 +++++++ .../core/appender/ConsoleAppenderTest.java | 6 +- 5 files changed, 134 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java index 9f253a0..8df298f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java @@ -23,7 +23,11 @@ import org.apache.logging.log4j.core.ErrorHandler; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; import org.apache.logging.log4j.core.filter.AbstractFilterable; +import org.apache.logging.log4j.core.layout.PatternLayout; import org.apache.logging.log4j.core.util.Integers; /** @@ -32,6 +36,60 @@ import org.apache.logging.log4j.core.util.Integers; */ public abstract class AbstractAppender extends AbstractFilterable implements Appender { + /** + * Subclasses can extend this abstract Builder. + * + * @param <B> This builder class. + */ + public abstract static class Builder<B extends Builder<B>> extends AbstractFilterable.Builder<B> { + + @PluginBuilderAttribute + private boolean ignoreExceptions = true; + + @PluginElement("Layout") + @Required + private Layout<? extends Serializable> layout; + + @PluginBuilderAttribute + @Required + private String name; + + public String getName() { + return name; + } + + public boolean isIgnoreExceptions() { + return ignoreExceptions; + } + + public Layout<? extends Serializable> getLayout() { + return layout; + } + + public B withName(String name) { + this.name = name; + return asBuilder(); + } + + public B withIgnoreExceptions(boolean ignoreExceptions) { + this.ignoreExceptions = ignoreExceptions; + return asBuilder(); + } + + public B withLayout(Layout<? extends Serializable> layout) { + this.layout = layout; + return asBuilder(); + } + + public Layout<? extends Serializable> getOrCreateLayout() { + if (layout == null) { + return PatternLayout.createDefaultLayout(); + } + return layout; + } + + } + private final String name; private final boolean ignoreExceptions; private final Layout<? extends Serializable> layout; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java index 4a95098..67e835a 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java @@ -21,6 +21,7 @@ import java.io.Serializable; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; import org.apache.logging.log4j.core.util.Constants; /** @@ -31,6 +32,26 @@ import org.apache.logging.log4j.core.util.Constants; public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager> extends AbstractAppender { /** + * Subclasses can extend this abstract Builder. + * + * @param <B> This builder class. + */ + public abstract static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B> { + + @PluginBuilderAttribute + private boolean immediateFlush; + + public boolean isImmediateFlush() { + return immediateFlush; + } + + public B withImmediateFlush(boolean immediateFlush) { + this.immediateFlush = immediateFlush; + return asBuilder(); + } + } + + /** * Immediate flush means that the underlying writer or output stream will be flushed at the end of each append * operation. Immediate flush is slower but ensures that each append request is actually written. If * <code>immediateFlush</code> is set to {@code false}, then there is a good chance that the last few logs events http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java index 9747088..eed9319 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java @@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.appender.FileAppender.Builder; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute; @@ -87,7 +88,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they * are propagated to the caller. * @return The ConsoleAppender. - * @deprecated Use {@link #createAppender(Layout, Filter, Target, String, boolean, boolean, boolean)}. + * @deprecated Use {@link #newBuilder()}. */ @Deprecated public static ConsoleAppender createAppender(Layout<? extends Serializable> layout, @@ -122,17 +123,18 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt * @param ignoreExceptions If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they * are propagated to the caller. * @return The ConsoleAppender. + * @deprecated Use {@link #newBuilder()}. */ - @PluginFactory + @Deprecated public static ConsoleAppender createAppender( // @formatter:off - @PluginElement("Layout") Layout<? extends Serializable> layout, - @PluginElement("Filter") final Filter filter, - @PluginAttribute(value = "target") Target target, - @PluginAttribute("name") final String name, - @PluginAttribute(value = "follow", defaultBoolean = false) final boolean follow, - @PluginAttribute(value = "direct", defaultBoolean = false) final boolean direct, - @PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final boolean ignoreExceptions) { + Layout<? extends Serializable> layout, + final Filter filter, + Target target, + final String name, + final boolean follow, + final boolean direct, + final boolean ignoreExceptions) { // @formatter:on if (name == null) { LOGGER.error("No name provided for ConsoleAppender"); @@ -156,72 +158,40 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt } @PluginBuilderFactory - public static Builder newBuilder() { - return new Builder(); + public static <B extends Builder<B>> B newBuilder() { + return new Builder<B>().asBuilder(); } /** * Builds ConsoleAppender instances. + * @param <B> This builder class */ - public static class Builder implements org.apache.logging.log4j.core.util.Builder<ConsoleAppender> { - - @PluginElement("Layout") - @Required - private Layout<? extends Serializable> layout = PatternLayout.createDefaultLayout(); - - @PluginElement("Filter") - private Filter filter; + public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B> + implements org.apache.logging.log4j.core.util.Builder<ConsoleAppender> { @PluginBuilderAttribute @Required private Target target = DEFAULT_TARGET; @PluginBuilderAttribute - @Required - private String name; - - @PluginBuilderAttribute private boolean follow; @PluginBuilderAttribute private boolean direct; - @PluginBuilderAttribute - private boolean ignoreExceptions = true; - - public Builder setLayout(final Layout<? extends Serializable> aLayout) { - this.layout = aLayout; - return this; - } - - public Builder setFilter(final Filter aFilter) { - this.filter = aFilter; - return this; - } - - public Builder setTarget(final Target aTarget) { + public B setTarget(final Target aTarget) { this.target = aTarget; - return this; + return asBuilder(); } - public Builder setName(final String aName) { - this.name = aName; - return this; - } - - public Builder setFollow(final boolean shouldFollow) { + public B setFollow(final boolean shouldFollow) { this.follow = shouldFollow; - return this; + return asBuilder(); } - public Builder setDirect(final boolean shouldDirect) { + public B setDirect(final boolean shouldDirect) { this.direct = shouldDirect; - return this; - } - - public Builder setIgnoreExceptions(final boolean shouldIgnoreExceptions) { - this.ignoreExceptions = shouldIgnoreExceptions; - return this; + return asBuilder(); } @Override @@ -229,7 +199,9 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt if (follow && direct) { throw new IllegalArgumentException("Cannot use both follow and direct on ConsoleAppender"); } - return new ConsoleAppender(name, layout, filter, getManager(target, follow, direct, layout), ignoreExceptions, target); + Layout<? extends Serializable> layout = getOrCreateLayout(); + return new ConsoleAppender(getName(), layout, getFilter(), getManager(target, follow, direct, layout), + isIgnoreExceptions(), target); } } http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java index 140a735..e57b58d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilterable.java @@ -21,6 +21,7 @@ import java.util.Iterator; import org.apache.logging.log4j.core.AbstractLifeCycle; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.config.plugins.PluginElement; /** * Enhances a Class by allowing it to contain Filters. @@ -28,6 +29,32 @@ import org.apache.logging.log4j.core.LogEvent; public abstract class AbstractFilterable extends AbstractLifeCycle implements Filterable { /** + * Subclasses can extend this abstract Builder. + * + * @param <B> This builder class. + */ + public abstract static class Builder<B extends Builder<B>> { + + @PluginElement("Filter") + private Filter filter; + + public Filter getFilter() { + return filter; + } + + @SuppressWarnings("unchecked") + public B asBuilder() { + return (B) this; + } + + public B withFilter(Filter filter) { + this.filter = filter; + return asBuilder(); + } + + } + + /** * May be null. */ private volatile Filter filter; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2207cae2/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java index 9190359..80d024d 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java @@ -98,8 +98,8 @@ public class ConsoleAppenderTest { mocks.replayAll(); systemSetter.systemSet(psMock); final Layout<String> layout = PatternLayout.newBuilder().withAlwaysWriteExceptions(true).build(); - final ConsoleAppender app = ConsoleAppender.createAppender(layout, null, targetName, "Console", false, false, - false); + final ConsoleAppender app = ConsoleAppender.newBuilder().withLayout(layout).setTarget(targetName) + .withName("Console").withIgnoreExceptions(false).build(); app.start(); assertTrue("Appender did not start", app.isStarted()); @@ -131,7 +131,7 @@ public class ConsoleAppenderTest { private void testFollowSystemPrintStream(final PrintStream ps, final Target target, final SystemSetter systemSetter) { final ConsoleAppender app = ConsoleAppender.newBuilder().setTarget(target).setFollow(true) - .setIgnoreExceptions(false).build(); + .withIgnoreExceptions(false).build(); Assert.assertEquals(target, app.getTarget()); app.start(); try {