ppkarwasz commented on code in PR #3513:
URL: https://github.com/apache/logging-log4j2/pull/3513#discussion_r2093225330


##########
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilter.java:
##########
@@ -43,16 +45,30 @@ public abstract static class AbstractFilterBuilder<B 
extends AbstractFilterBuild
         public static final String ATTR_ON_MISMATCH = "onMismatch";
         public static final String ATTR_ON_MATCH = "onMatch";
 
+        /**
+         * The action to perform when a match occurs.
+         */
         @PluginBuilderAttribute(ATTR_ON_MATCH)
-        private Result onMatch = Result.NEUTRAL;
+        protected Result onMatch = Result.NEUTRAL;

Review Comment:
   There is already a getter and a setter. Making this `protected` is not 
needed.



##########
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/AbstractFilter.java:
##########
@@ -43,16 +45,30 @@ public abstract static class AbstractFilterBuilder<B 
extends AbstractFilterBuild
         public static final String ATTR_ON_MISMATCH = "onMismatch";
         public static final String ATTR_ON_MATCH = "onMatch";
 
+        /**
+         * The action to perform when a match occurs.
+         */
         @PluginBuilderAttribute(ATTR_ON_MATCH)
-        private Result onMatch = Result.NEUTRAL;
+        protected Result onMatch = Result.NEUTRAL;
 
+        /**
+         * The action to perform when a mismatch occurs.
+         */
         @PluginBuilderAttribute(ATTR_ON_MISMATCH)
-        private Result onMismatch = Result.DENY;
+        protected Result onMismatch = Result.DENY;

Review Comment:
   There is already a getter and a setter. Making this `protected` is not 
needed.



##########
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java:
##########
@@ -28,140 +25,312 @@
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.message.StringFormattedMessage;
+import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginAttribute;
-import org.apache.logging.log4j.plugins.PluginElement;
+import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.plugins.util.Assert;
+import org.apache.logging.log4j.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.util.Strings;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
 
 /**
- * This filter returns the onMatch result if the message matches the regular 
expression.
- *
- * The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to the result of
- * calling Message.getMessageFormat (true) or Message.getFormattedMessage() 
(false). The default is false.
- *
+ * This filter returns the {@code onMatch} result if the message exactly 
matches the configured
+ * "{@code regex}" regular-expression pattern; otherwise, it returns the 
{@code onMismatch} result.
+ * <p>
+ *   The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to
+ *   the result of calling Message.getMessageFormat (true) or 
Message.getFormattedMessage() (false).
+ *   The default is {@code false}.
+ * </p>
  */
 @Configurable(elementType = Filter.ELEMENT_TYPE, printObject = true)
+@NullMarked
 @Plugin
 public final class RegexFilter extends AbstractFilter {
 
-    private static final int DEFAULT_PATTERN_FLAGS = 0;
+    /** The pattern compiled from the regular-expression. */
     private final Pattern pattern;
+
+    /** Flag: if {@code true} use message format-pattern / field for the match 
target. */
     private final boolean useRawMessage;
 
-    private RegexFilter(final boolean raw, final Pattern pattern, final Result 
onMatch, final Result onMismatch) {
-        super(onMatch, onMismatch);
-        this.pattern = pattern;
-        this.useRawMessage = raw;
+    /**
+     * Constructs a new {@code RegexFilter} configured by the given builder.
+     * @param builder the builder
+     * @throws IllegalArgumentException if the regular expression is not 
configured or cannot be compiled to a pattern
+     */
+    private RegexFilter(final Builder builder) {
+
+        super(builder);
+
+        // NOTE: the constructor throws exceptions but is only called from 
Builder#build() where *null*
+        //       should be returned for a misconfigured builder.  *If* an 
exception is thrown here
+        //       it will be caught and logged in the builder and not 
propagated by returning *null*.
+
+        if (Strings.isBlank(builder.regex)) {
+            throw new IllegalArgumentException("The 'regex' attribute must not 
be null or empty.");
+        }
+
+        this.useRawMessage = Boolean.TRUE.equals(builder.useRawMsg);
+
+        try {
+            this.pattern = Pattern.compile(builder.regex);
+        } catch (final Exception ex) {
+            throw new IllegalArgumentException("Unable to compile regular 
expression: '" + builder.regex + "'.", ex);
+        }
+    }
+
+    /**
+     * Returns the compiled regular-expression pattern.
+     * @return the pattern (will never be {@code null}
+     */
+    public Pattern getPattern() {
+        return this.pattern;
     }

Review Comment:
   Since there is already a `getRegex` method below, I think this method can be 
removed.



##########
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java:
##########
@@ -28,140 +25,312 @@
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.message.StringFormattedMessage;
+import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginAttribute;
-import org.apache.logging.log4j.plugins.PluginElement;
+import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.plugins.util.Assert;
+import org.apache.logging.log4j.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.util.Strings;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
 
 /**
- * This filter returns the onMatch result if the message matches the regular 
expression.
- *
- * The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to the result of
- * calling Message.getMessageFormat (true) or Message.getFormattedMessage() 
(false). The default is false.
- *
+ * This filter returns the {@code onMatch} result if the message exactly 
matches the configured
+ * "{@code regex}" regular-expression pattern; otherwise, it returns the 
{@code onMismatch} result.
+ * <p>
+ *   The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to
+ *   the result of calling Message.getMessageFormat (true) or 
Message.getFormattedMessage() (false).
+ *   The default is {@code false}.
+ * </p>
  */
 @Configurable(elementType = Filter.ELEMENT_TYPE, printObject = true)
+@NullMarked
 @Plugin
 public final class RegexFilter extends AbstractFilter {
 
-    private static final int DEFAULT_PATTERN_FLAGS = 0;
+    /** The pattern compiled from the regular-expression. */
     private final Pattern pattern;
+
+    /** Flag: if {@code true} use message format-pattern / field for the match 
target. */
     private final boolean useRawMessage;
 
-    private RegexFilter(final boolean raw, final Pattern pattern, final Result 
onMatch, final Result onMismatch) {
-        super(onMatch, onMismatch);
-        this.pattern = pattern;
-        this.useRawMessage = raw;
+    /**
+     * Constructs a new {@code RegexFilter} configured by the given builder.
+     * @param builder the builder
+     * @throws IllegalArgumentException if the regular expression is not 
configured or cannot be compiled to a pattern
+     */
+    private RegexFilter(final Builder builder) {
+
+        super(builder);
+
+        // NOTE: the constructor throws exceptions but is only called from 
Builder#build() where *null*
+        //       should be returned for a misconfigured builder.  *If* an 
exception is thrown here
+        //       it will be caught and logged in the builder and not 
propagated by returning *null*.
+
+        if (Strings.isBlank(builder.regex)) {
+            throw new IllegalArgumentException("The 'regex' attribute must not 
be null or empty.");
+        }
+
+        this.useRawMessage = Boolean.TRUE.equals(builder.useRawMsg);
+
+        try {
+            this.pattern = Pattern.compile(builder.regex);
+        } catch (final Exception ex) {
+            throw new IllegalArgumentException("Unable to compile regular 
expression: '" + builder.regex + "'.", ex);
+        }
+    }
+
+    /**
+     * Returns the compiled regular-expression pattern.
+     * @return the pattern (will never be {@code null}
+     */
+    public Pattern getPattern() {
+        return this.pattern;
     }
 
+    /**
+     * Returns the regular-expression.
+     * @return the regular-expression (it may be an empty string but never 
{@code null})
+     */
+    public String getRegex() {
+        return this.pattern.pattern();
+    }
+
+    /**
+     * Returns whether the raw-message should be used.
+     * @return {@code true} if the raw message should be used; otherwise, 
{@code false}
+     */
+    public boolean isUseRawMessage() {
+        return this.useRawMessage;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message formatted with
+     *   the given parameters.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
String msg, final Object... params) {
-        if (useRawMessage || params == null || params.length == 0) {
-            return filter(msg);
-        }
-        return filter(ParameterizedMessage.format(msg, params));
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable String msg,
+            final @Nullable Object @Nullable ... params) {
+
+        return (useRawMessage || params == null || params.length == 0)
+                ? filter(msg)
+                : filter(ParameterizedMessage.format(msg, params));
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *     <li>{@code throwable}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
Object msg, final Throwable t) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        return filter(msg.toString());
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable Object message,
+            final @Nullable Throwable throwable) {
+
+        return (message == null) ? this.onMismatch : 
filter(message.toString());
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *     <li>{@code throwable}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
Message msg, final Throwable t) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        final String text = useRawMessage ? msg.getFormat() : 
msg.getFormattedMessage();
-        return filter(text);
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable Message message,
+            final @Nullable Throwable throwable) {
+        return (message == null) ? this.onMismatch : 
filter(getMessageTextByType(message));
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if the {@code event} argument is {@code 
null}
+     */
     @Override
     public Result filter(final LogEvent event) {
-        final String text = useRawMessage
-                ? event.getMessage().getFormat()
-                : event.getMessage().getFormattedMessage();
-        return filter(text);
+        Objects.requireNonNull(event, "The 'event' argument must not be 
null.");
+        return filter(getMessageTextByType(event.getMessage()));
     }
 
-    private Result filter(final String msg) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        final Matcher m = pattern.matcher(msg);
-        return m.matches() ? onMatch : onMismatch;
+    /**
+     * Apply the filter to the given message and return the {@code onMatch} 
result if the <i>entire</i>
+     * message matches the configured regex pattern; otherwise, {@code 
onMismatch}.
+     * <p>
+     *   If the given '{@code msg}' is {@code null} the configured {@code 
onMismatch} result will be returned.
+     * </p>
+     * @param msg the message
+     * @return the {@code onMatch} result if the pattern matches; otherwise, 
the {@code onMismatch} result
+     */
+    public Result filter(final @Nullable String msg) {
+        return (msg != null && pattern.matcher(msg).matches()) ? onMatch : 
onMismatch;
+    }
+
+    /**
+     * Tests the filter pattern against the given Log4j {@code Message}.
+     * <p>
+     *   If the raw-message flag is enabled and message is an instance of the 
following, the raw message format
+     *   will be returned.
+     * </p>
+     * <ul>
+     *   <li>{@link ParameterizedMessage}</li>
+     *   <li>{@link StringFormattedMessage}</li>
+     *   <li>{@link StructuredDataMessage}</li>
+     * </ul>
+     * <p>
+     *   If the '{@code useRawMessage}' flag is disabled <i>OR</i> the message 
is not one of the above
+     *   implementations, the message's formatted message will be returned.
+     * </p>
+     * <h3>Developer Note</h3>
+     * <p>
+     * While `Message#getFormat()` is broken in general, it still makes sense 
for certain types.
+     * Hence, suppress the deprecation warning.
+     * </p>
+     *
+     * @param message the message
+     * @return the target message based on configuration and message-type
+     */
+    @SuppressWarnings("deprecation")
+    private String getMessageTextByType(final Message message) {
+        return useRawMessage
+                        && (message instanceof ParameterizedMessage
+                                || message instanceof StringFormattedMessage
+                                || message instanceof StructuredDataMessage)
+                ? message.getFormat()
+                : message.getFormattedMessage();
     }
 
+    /** {@inheritDoc} */
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("useRaw=").append(useRawMessage);
-        sb.append(", pattern=").append(pattern.toString());
-        return sb.toString();
+        return "useRawMessage=" + useRawMessage + ", pattern=" + pattern;
     }
 
     /**
-     * Creates a Filter that matches a regular expression.
-     *
-     * @param regex
-     *        The regular expression to match.
-     * @param patternFlags
-     *        An array of Strings where each String is a {@link 
Pattern#compile(String, int)} compilation flag.
-     * @param useRawMsg
-     *        If true, the raw message will be used, otherwise the formatted 
message will be used.
-     * @param onMatch
-     *        The action to perform when a match occurs.
-     * @param onMismatch
-     *        The action to perform when a mismatch occurs.
-     * @return The RegexFilter.
-     * @throws IllegalAccessException
-     * @throws IllegalArgumentException
+     * Creates a new builder instance.
+     * @return the new builder instance
      */
-    // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
     @PluginFactory
-    public static RegexFilter createFilter(
-            // @formatter:off
-            @PluginAttribute final String regex,
-            @PluginElement final String[] patternFlags,
-            @PluginAttribute final Boolean useRawMsg,
-            @PluginAttribute final Result onMatch,
-            @PluginAttribute final Result onMismatch)
-            // @formatter:on
-            throws IllegalArgumentException, IllegalAccessException {
-        if (regex == null) {
-            LOGGER.error("A regular expression must be provided for 
RegexFilter");
-            return null;
-        }
-        return new RegexFilter(useRawMsg, Pattern.compile(regex, 
toPatternFlags(patternFlags)), onMatch, onMismatch);
+    public static Builder newBuilder() {
+        return new Builder();
     }

Review Comment:
   A plugin builder factory must be annotated with `@PluginBuilderFactory` 
instead of `@PluginFactory`.



##########
log4j-core/src/main/java/org/apache/logging/log4j/core/filter/RegexFilter.java:
##########
@@ -28,140 +25,312 @@
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.message.StringFormattedMessage;
+import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.plugins.Configurable;
 import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.plugins.PluginAttribute;
-import org.apache.logging.log4j.plugins.PluginElement;
+import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.plugins.util.Assert;
+import org.apache.logging.log4j.plugins.validation.constraints.Required;
+import org.apache.logging.log4j.util.Strings;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
 
 /**
- * This filter returns the onMatch result if the message matches the regular 
expression.
- *
- * The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to the result of
- * calling Message.getMessageFormat (true) or Message.getFormattedMessage() 
(false). The default is false.
- *
+ * This filter returns the {@code onMatch} result if the message exactly 
matches the configured
+ * "{@code regex}" regular-expression pattern; otherwise, it returns the 
{@code onMismatch} result.
+ * <p>
+ *   The "useRawMsg" attribute can be used to indicate whether the regular 
expression should be applied to
+ *   the result of calling Message.getMessageFormat (true) or 
Message.getFormattedMessage() (false).
+ *   The default is {@code false}.
+ * </p>
  */
 @Configurable(elementType = Filter.ELEMENT_TYPE, printObject = true)
+@NullMarked
 @Plugin
 public final class RegexFilter extends AbstractFilter {
 
-    private static final int DEFAULT_PATTERN_FLAGS = 0;
+    /** The pattern compiled from the regular-expression. */
     private final Pattern pattern;
+
+    /** Flag: if {@code true} use message format-pattern / field for the match 
target. */
     private final boolean useRawMessage;
 
-    private RegexFilter(final boolean raw, final Pattern pattern, final Result 
onMatch, final Result onMismatch) {
-        super(onMatch, onMismatch);
-        this.pattern = pattern;
-        this.useRawMessage = raw;
+    /**
+     * Constructs a new {@code RegexFilter} configured by the given builder.
+     * @param builder the builder
+     * @throws IllegalArgumentException if the regular expression is not 
configured or cannot be compiled to a pattern
+     */
+    private RegexFilter(final Builder builder) {
+
+        super(builder);
+
+        // NOTE: the constructor throws exceptions but is only called from 
Builder#build() where *null*
+        //       should be returned for a misconfigured builder.  *If* an 
exception is thrown here
+        //       it will be caught and logged in the builder and not 
propagated by returning *null*.
+
+        if (Strings.isBlank(builder.regex)) {
+            throw new IllegalArgumentException("The 'regex' attribute must not 
be null or empty.");
+        }
+
+        this.useRawMessage = Boolean.TRUE.equals(builder.useRawMsg);
+
+        try {
+            this.pattern = Pattern.compile(builder.regex);
+        } catch (final Exception ex) {
+            throw new IllegalArgumentException("Unable to compile regular 
expression: '" + builder.regex + "'.", ex);
+        }
+    }
+
+    /**
+     * Returns the compiled regular-expression pattern.
+     * @return the pattern (will never be {@code null}
+     */
+    public Pattern getPattern() {
+        return this.pattern;
     }
 
+    /**
+     * Returns the regular-expression.
+     * @return the regular-expression (it may be an empty string but never 
{@code null})
+     */
+    public String getRegex() {
+        return this.pattern.pattern();
+    }
+
+    /**
+     * Returns whether the raw-message should be used.
+     * @return {@code true} if the raw message should be used; otherwise, 
{@code false}
+     */
+    public boolean isUseRawMessage() {
+        return this.useRawMessage;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message formatted with
+     *   the given parameters.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
String msg, final Object... params) {
-        if (useRawMessage || params == null || params.length == 0) {
-            return filter(msg);
-        }
-        return filter(ParameterizedMessage.format(msg, params));
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable String msg,
+            final @Nullable Object @Nullable ... params) {
+
+        return (useRawMessage || params == null || params.length == 0)
+                ? filter(msg)
+                : filter(ParameterizedMessage.format(msg, params));
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *     <li>{@code throwable}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
Object msg, final Throwable t) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        return filter(msg.toString());
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable Object message,
+            final @Nullable Throwable throwable) {
+
+        return (message == null) ? this.onMismatch : 
filter(message.toString());
     }
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     *   This implementation performs the filter evaluation against the given 
message.
+     * </p>
+     * <p>
+     *   The following method arguments are ignored by this filter method 
implementation:
+     *   <ul>
+     *     <li>{@code logger}</li>
+     *     <li>{@code level}</li>
+     *     <li>{@code marker}</li>
+     *     <li>{@code throwable}</li>
+     *   </ul>
+     * </p>
+     */
     @Override
     public Result filter(
-            final Logger logger, final Level level, final Marker marker, final 
Message msg, final Throwable t) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        final String text = useRawMessage ? msg.getFormat() : 
msg.getFormattedMessage();
-        return filter(text);
+            final @Nullable Logger logger,
+            final @Nullable Level level,
+            final @Nullable Marker marker,
+            final @Nullable Message message,
+            final @Nullable Throwable throwable) {
+        return (message == null) ? this.onMismatch : 
filter(getMessageTextByType(message));
     }
 
+    /**
+     * {@inheritDoc}
+     *
+     * @throws NullPointerException if the {@code event} argument is {@code 
null}
+     */
     @Override
     public Result filter(final LogEvent event) {
-        final String text = useRawMessage
-                ? event.getMessage().getFormat()
-                : event.getMessage().getFormattedMessage();
-        return filter(text);
+        Objects.requireNonNull(event, "The 'event' argument must not be 
null.");
+        return filter(getMessageTextByType(event.getMessage()));
     }
 
-    private Result filter(final String msg) {
-        if (msg == null) {
-            return onMismatch;
-        }
-        final Matcher m = pattern.matcher(msg);
-        return m.matches() ? onMatch : onMismatch;
+    /**
+     * Apply the filter to the given message and return the {@code onMatch} 
result if the <i>entire</i>
+     * message matches the configured regex pattern; otherwise, {@code 
onMismatch}.
+     * <p>
+     *   If the given '{@code msg}' is {@code null} the configured {@code 
onMismatch} result will be returned.
+     * </p>
+     * @param msg the message
+     * @return the {@code onMatch} result if the pattern matches; otherwise, 
the {@code onMismatch} result
+     */
+    public Result filter(final @Nullable String msg) {
+        return (msg != null && pattern.matcher(msg).matches()) ? onMatch : 
onMismatch;
+    }
+
+    /**
+     * Tests the filter pattern against the given Log4j {@code Message}.
+     * <p>
+     *   If the raw-message flag is enabled and message is an instance of the 
following, the raw message format
+     *   will be returned.
+     * </p>
+     * <ul>
+     *   <li>{@link ParameterizedMessage}</li>
+     *   <li>{@link StringFormattedMessage}</li>
+     *   <li>{@link StructuredDataMessage}</li>
+     * </ul>
+     * <p>
+     *   If the '{@code useRawMessage}' flag is disabled <i>OR</i> the message 
is not one of the above
+     *   implementations, the message's formatted message will be returned.
+     * </p>
+     * <h3>Developer Note</h3>
+     * <p>
+     * While `Message#getFormat()` is broken in general, it still makes sense 
for certain types.
+     * Hence, suppress the deprecation warning.
+     * </p>
+     *
+     * @param message the message
+     * @return the target message based on configuration and message-type
+     */
+    @SuppressWarnings("deprecation")
+    private String getMessageTextByType(final Message message) {
+        return useRawMessage
+                        && (message instanceof ParameterizedMessage
+                                || message instanceof StringFormattedMessage
+                                || message instanceof StructuredDataMessage)
+                ? message.getFormat()
+                : message.getFormattedMessage();
     }
 
+    /** {@inheritDoc} */
     @Override
     public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("useRaw=").append(useRawMessage);
-        sb.append(", pattern=").append(pattern.toString());
-        return sb.toString();
+        return "useRawMessage=" + useRawMessage + ", pattern=" + pattern;
     }
 
     /**
-     * Creates a Filter that matches a regular expression.
-     *
-     * @param regex
-     *        The regular expression to match.
-     * @param patternFlags
-     *        An array of Strings where each String is a {@link 
Pattern#compile(String, int)} compilation flag.
-     * @param useRawMsg
-     *        If true, the raw message will be used, otherwise the formatted 
message will be used.
-     * @param onMatch
-     *        The action to perform when a match occurs.
-     * @param onMismatch
-     *        The action to perform when a mismatch occurs.
-     * @return The RegexFilter.
-     * @throws IllegalAccessException
-     * @throws IllegalArgumentException
+     * Creates a new builder instance.
+     * @return the new builder instance
      */
-    // TODO Consider refactoring to use AbstractFilter.AbstractFilterBuilder
     @PluginFactory
-    public static RegexFilter createFilter(
-            // @formatter:off
-            @PluginAttribute final String regex,
-            @PluginElement final String[] patternFlags,
-            @PluginAttribute final Boolean useRawMsg,
-            @PluginAttribute final Result onMatch,
-            @PluginAttribute final Result onMismatch)
-            // @formatter:on
-            throws IllegalArgumentException, IllegalAccessException {
-        if (regex == null) {
-            LOGGER.error("A regular expression must be provided for 
RegexFilter");
-            return null;
-        }
-        return new RegexFilter(useRawMsg, Pattern.compile(regex, 
toPatternFlags(patternFlags)), onMatch, onMismatch);

Review Comment:
   For backward compatibility, we can not remove this method, but we can:
   
   - Remove the `@PluginFactory` annotation.
   - Deprecated it.
   - Rewrite it in terms of builder calls.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@logging.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to