From 322cc1d30c790ae9a2a7327de8189e17c4dbf305 Mon Sep 17 00:00:00 2001
From: Jeff Thomas
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code value} is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the value is {@code null} the component attribute with the given {@code key} will
+ * instead be removed from the map.
+ *
+ * The result map is guaranteed to have both non-{@code null} keys and values. + *
+ * @return an immutable map of the key/value attributes + */ + protected @NonNull Map+ * This method is primarily intended to be used in testing. + *
+ */ + protected void clear() { + synchronized (this) { + attributes.clear(); + components.clear(); + } + } + + /** + * Returns an instance of this builder cast to its generic type. + * @return this builder + */ + @SuppressWarnings("unchecked") + protected @NonNull T self() { return (T) this; } } From 406b097ecd2d961d8650979fd63b0ada4aed8138 Mon Sep 17 00:00:00 2001 From: Jeff Thomas+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers + * should avoid sharing instances between threads. + *
+ * * @since 2.4 */ +@ProviderType public interface AppenderComponentBuilder extends FilterableComponentBuilder+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured + * before calling this method. Changes to the builder after calling this method will not have + * any effect. + *
+ * + * @param builder The {@code LayoutComponentBuilder} with all of its attributes set. + * @return this component builder (for chaining) + * @throws NullPointerException if the given {@code builder} argument is {@code null} */ AppenderComponentBuilder add(LayoutComponentBuilder builder); - - /** - * Returns the name of the Appender. - * @return the name of the Appender. - */ - @Override - String getName(); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/AppenderRefComponentBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/AppenderRefComponentBuilder.java index 26953666c27..64334927211 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/AppenderRefComponentBuilder.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/AppenderRefComponentBuilder.java @@ -16,8 +16,58 @@ */ package org.apache.logging.log4j.core.config.builder.api; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.config.AppenderRef; +import org.jspecify.annotations.Nullable; + /** - * Assembler for constructing AppenderRef Components. + * A builder interface for constructing and configuring {@link AppenderRef} components in a Log4j configuration. + * + *+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers + * should avoid sharing instances between threads. + *
+ * * @since 2.4 */ -public interface AppenderRefComponentBuilder extends FilterableComponentBuilder+ * If the given {@code level} is {@code null}, the attribute will be removed from the component. + *
+ * + * @param level the level + * @return this builder (for chaining) + */ + default AppenderRefComponentBuilder setLevelAttribute(@Nullable String level) { + return setAttribute("level", level); + } + + /** + * Sets the "{@code level}" attribute on the appender reference component. + *+ * If the given {@code level} is {@code null}, the attribute will be removed from the component. + *
+ * + * @param level the level + * @return this builder (for chaining) + */ + default AppenderRefComponentBuilder setLevelAttribute(@Nullable Level level) { + return setAttribute("level", level); + } + + /** + * Sets the "{@code ref}" attribute on the appender reference component. + *+ * If the given {@code refAppenderName} is {@code null}, the attribute will be removed from the component. + *
+ * + * @param refAppenderName the name of the appender being referenced + * @return this builder (for chaining) + */ + default AppenderRefComponentBuilder setRefAttribute(@Nullable String refAppenderName) { + return setAttribute("ref", refAppenderName); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/Component.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/Component.java index d6c5934b2b6..438e38ba070 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/Component.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/Component.java @@ -20,45 +20,65 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import org.jspecify.annotations.Nullable; +import org.osgi.annotation.versioning.ProviderType; /** * Container for building Configurations. This class is not normally directly manipulated by users * of the Assembler API. * @since 2.4 */ +@ProviderType public class Component { private final Map+ * If the new value is {@code null}, than any existing entry with the given {@code key} is ejected from the map. + *
+ * @param key the key + * @param newValue the new value + * @return the previous value or {@code null} if none was set + */ + public @Nullable String addAttribute(final String key, final @Nullable String newValue) { + return putAttribute(key, newValue); } public void addComponent(final Component component) { + Objects.requireNonNull(component, "The 'component' argument cannot be null."); components.add(component); } @@ -74,7 +94,27 @@ public String getPluginType() { return pluginType; } - public String getValue() { + public @Nullable String getValue() { return value; } + + /** + * Puts the given key/value pair to the attribute map. + *+ * If the new value is {@code null}, than any existing entry with the given {@code key} is ejected from the map. + *
+ * @param key the key + * @param newValue the new value + * @return the previous value or {@code null} if none was set + */ + protected @Nullable String putAttribute(final String key, final @Nullable String newValue) { + + Objects.requireNonNull(key, "The 'key' argument cannot be null."); + + if (newValue == null) { + return attributes.remove(key); + } else { + return attributes.put(key, newValue); + } + } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ComponentBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ComponentBuilder.java index 0c0f1218ea5..f946d5030e8 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ComponentBuilder.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/api/ComponentBuilder.java @@ -19,18 +19,40 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.util.Builder; -import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; +import org.osgi.annotation.versioning.ProviderType; /** * Builds arbitrary components and is the base type for the provided components. * @param
* If the given {@code level} value is {@code null}, the component attribute with the given key
* will be removed (if present).
@@ -40,11 +62,10 @@ public interface ComponentBuilder
* If the given {@code level} value is {@code null}, the component attribute with the given key
* will be removed (if present).
@@ -54,11 +75,10 @@ public interface ComponentBuilder
* If the given {@code level} value is {@code null}, the component attribute with the given key
* will be removed (if present).
@@ -68,31 +88,28 @@ public interface ComponentBuilder
* If the given {@code value} is {@code null}, the component attribute with the given key
* will be removed (if present).
@@ -102,29 +119,99 @@ public interface ComponentBuilder
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code level} value is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * If the given {@code value} is {@code null}, the component attribute with the given key
+ * will be removed (if present).
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the given {@code onMatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMismatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMismatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * The monitor interval specifies the number of seconds between checks for changes to the configuration source.
+ *
+ * The monitor interval specifies the number of seconds between checks for changes to the configuration source.
+ *
+ * The shutdown-timeout specifies how long appenders and background tasks will get to shut down when the
+ * JVM is shutting down.
+ *
+ * The default is zero which means that each appender uses its default timeout, and doesn't wait for background
+ * tasks. Not all appenders will honor this, it is a hint and not an absolute guarantee that the shutdown
+ * procedure will not take longer.
+ *
+ * Setting the shutdown-timeout too low increase the risk of losing outstanding log events that have not yet
+ * been written to the final destination.
+ *
+ * This setting is ignored if {@link #setShutdownHook(String)} has been set to "disable".
+ *
+ * The shutdown-timeout specifies how long appenders and background tasks will get to shut down when the
+ * JVM is shutting down.
+ *
+ * The default is zero which means that each appender uses its default timeout, and doesn't wait for background
+ * tasks. Not all appenders will honor this, it is a hint and not an absolute guarantee that the shutdown
+ * procedure will not take longer.
+ *
+ * Setting the shutdown-timeout too low increase the risk of losing outstanding log events that have not yet
+ * been written to the final destination.
+ *
+ * This setting is ignored if {@link #setShutdownHook(String)} has been set to "disable".
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the given {@code onMismatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the given {@code onMatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMismatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMismatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the given {@code key} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code value} argument is {@code} the attribute will be removed (if present).
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * Note: the provided {@code builder} will be built by this method; therefore, it must be fully configured
+ * before calling this method. Changes to the builder after calling this method will not have
+ * any effect.
+ *
+ * If the given {@code additivity} is {@code null}, the attribute will be removed from the component.
+ *
+ * If the given {@code includeLocation} is {@code null}, the attribute will be removed from the component.
+ *
+ * If the given {@code level} is {@code null}, the attribute will be removed from the component.
+ *
+ * If the given {@code level} is {@code null}, the attribute will be removed from the component.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the given {@code language} argument is {@code} the attribute will be removed (if present).
+ *
+ * If the given {@code onMatch} argument is {@code} the attribute will be removed (if present).
+ *
+ * Instances of this builder are designed for single-threaded use and are not thread-safe. Developers
+ * should avoid sharing instances between threads.
+ *
+ * If the {@code language} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code isWatched} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code charset} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code path} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code language} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code isWatched} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code isWatched} argument is {@code null} the attribute will be removed.
+ *
+ * If the {@code charset} argument is {@code null} the attribute will be removed.
+ *
+ * This class may be extended to enhance its functionality.
+ *
+ * Important: this constructor is invoked via reflection in {@link DefaultConfigurationBuilder}.
+ * Do not change its signature!
+ *
+ * If the given {@code contentType} is {@code null}, the default content-type "{@code text}" will be assigned.
+ *
+ * The shutdown-timeout specifies how long appenders and background tasks will get to shut down when the
+ * JVM is shutting down.
+ *
+ * The default is zero which means that each appender uses its default timeout, and doesn't wait for background
+ * tasks. Not all appenders will honor this, it is a hint and not an absolute guarantee that the shutdown
+ * procedure will not take longer.
+ *
+ * Setting the shutdown-timeout too low increase the risk of losing outstanding log events that have not yet
+ * been written to the final destination.
+ *
+ * This setting is ignored if {@link #setShutdownHook(String)} has been set to "disable".
+ *
+ * The monitor interval specifies the number of seconds between checks for changes to the configuration source.
+ *
+ * This method will recurse through the children of the given component building a node tree.
+ *
+ * Note: This method assigns the specified parent within the new child node; however, it does not
+ * add the new node to the parent. That is performed by the caller (which in most cases this
+ * method due to recursion).
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * This method is primarily intended to be used in testing.
+ *
- * This method is primarily intended to be used in testing.
- *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note the implementation will be instantiated per reflection and must have a constructor with the following
+ * parameters:
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ *
+ * Note: This builder is not thread-safe. Instances should not be shared between threads.
+ * {@code
+ * public BuiltConfigurationClazz(LogggerContext, ConfigurationSource, Component) {
+ * ...
+ * }
+ * }
+ *
+ * @param clazz the {@code BuiltConfiguration} implementation class
+ */
public DefaultConfigurationBuilder(final Class