diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java index 333af1ebd46..22bf04e43f1 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModifiedTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.file.attribute.FileTime; +import java.time.Duration; import java.util.List; import org.apache.logging.log4j.core.config.Node; import org.apache.logging.log4j.core.config.NullConfiguration; @@ -43,15 +44,10 @@ @SetSystemProperty(key = "log4j2.status.entries", value = "10") class IfLastModifiedTest { - @Test - public void testGetDurationReturnsConstructorValue() { - final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("P7D")); - assertEquals(0, filter.getAge().compareTo(Duration.parse("P7D"))); - } - @Test public void testAcceptsIfFileAgeEqualToDuration() { - final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S")); + final IfLastModified filter = + IfLastModified.newBuilder().setAge(Duration.parse("PT33S")).build(); final DummyFileAttributes attrs = new DummyFileAttributes(); final long age = 33 * 1000; attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - age); @@ -60,7 +56,8 @@ public void testAcceptsIfFileAgeEqualToDuration() { @Test public void testAcceptsIfFileAgeExceedsDuration() { - final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S")); + final IfLastModified filter = + IfLastModified.newBuilder().setAge(Duration.parse("PT33S")).build(); final DummyFileAttributes attrs = new DummyFileAttributes(); final long age = 33 * 1000 + 5; attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - age); @@ -69,7 +66,8 @@ public void testAcceptsIfFileAgeExceedsDuration() { @Test public void testDoesNotAcceptIfFileAgeLessThanDuration() { - final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S")); + final IfLastModified filter = + IfLastModified.newBuilder().setAge(Duration.parse("PT33S")).build(); final DummyFileAttributes attrs = new DummyFileAttributes(); final long age = 33 * 1000 - 5; attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - age); @@ -79,7 +77,10 @@ public void testDoesNotAcceptIfFileAgeLessThanDuration() { @Test public void testAcceptCallsNestedConditionsOnlyIfPathAccepted() { final CountingCondition counter = new CountingCondition(true); - final IfLastModified filter = IfLastModified.createAgeCondition(Duration.parse("PT33S"), counter); + final IfLastModified filter = IfLastModified.newBuilder() + .setAge(Duration.parse("PT33S")) + .setNestedConditions(counter) + .build(); final DummyFileAttributes attrs = new DummyFileAttributes(); final long oldEnough = 33 * 1000 + 5; attrs.lastModified = FileTime.fromMillis(System.currentTimeMillis() - oldEnough); @@ -104,8 +105,10 @@ public void testAcceptCallsNestedConditionsOnlyIfPathAccepted() { @Test public void testBeforeTreeWalk() { final CountingCondition counter = new CountingCondition(true); - final IfLastModified filter = - IfLastModified.createAgeCondition(Duration.parse("PT33S"), counter, counter, counter); + final IfLastModified filter = IfLastModified.newBuilder() + .setAge(Duration.parse("PT33S")) + .setNestedConditions(counter, counter, counter) + .build(); filter.beforeFileTreeWalk(); assertEquals(3, counter.getBeforeFileTreeWalkCount()); } @@ -113,7 +116,8 @@ public void testBeforeTreeWalk() { @Test public void testCreateAgeConditionCalledProgrammaticallyThrowsNPEWhenAgeIsNotSpecified() { Duration age = null; - assertThrows(NullPointerException.class, () -> IfLastModified.createAgeCondition(age)); + assertThrows( + NullPointerException.class, () -> IfLastModified.newBuilder().setAge(age)); } @ParameterizedTest diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/Duration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/Duration.java index 597eceea24a..a9c4f9437b0 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/Duration.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/Duration.java @@ -30,7 +30,9 @@ * This implementation does not support fractions or negative values. * * @see #parse(CharSequence) + * @deprecated since 2.24.0 use {@link java.time.Duration} instead. */ +@Deprecated public class Duration implements Serializable, Comparable { private static final long serialVersionUID = -3756810052716342061L; @@ -66,6 +68,13 @@ public class Duration implements Serializable, Comparable { private static final Pattern PATTERN = Pattern.compile( "P?(?:([0-9]+)D)?" + "(T?(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)?S)?)?", Pattern.CASE_INSENSITIVE); + /** + * @since 2.24.0 + */ + public static Duration ofMillis(final long millis) { + return new Duration(millis / 1000L); + } + /** * The number of seconds in the duration. */ diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java index 6b15f5409f2..e8a105edf5f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/IfLastModified.java @@ -19,6 +19,7 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; +import java.time.Duration; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -26,9 +27,9 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.Core; 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; +import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; import org.apache.logging.log4j.core.config.plugins.PluginElement; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required; import org.apache.logging.log4j.core.util.Clock; import org.apache.logging.log4j.core.util.ClockFactory; @@ -36,6 +37,7 @@ /** * PathCondition that accepts paths that are older than the specified duration. + * @since 2.5 */ @Plugin(name = "IfLastModified", category = Core.CATEGORY_NAME, printObject = true) public final class IfLastModified implements PathCondition { @@ -50,20 +52,18 @@ private IfLastModified(final Duration age, final PathCondition[] nestedCondition this.nestedConditions = PathCondition.copy(nestedConditions); } - public Duration getAge() { - return age; + /** + * @deprecated since 2.24.0. In 3.0.0 the signature will change. + */ + @Deprecated + public org.apache.logging.log4j.core.appender.rolling.action.Duration getAge() { + return org.apache.logging.log4j.core.appender.rolling.action.Duration.ofMillis(age.toMillis()); } public List getNestedConditions() { return Collections.unmodifiableList(Arrays.asList(nestedConditions)); } - /* - * (non-Javadoc) - * - * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#accept(java.nio.file.Path, - * java.nio.file.Path, java.nio.file.attribute.BasicFileAttributes) - */ @Override public boolean accept(final Path basePath, final Path relativePath, final BasicFileAttributes attrs) { final FileTime fileTime = attrs.lastModifiedTime(); @@ -79,30 +79,22 @@ public boolean accept(final Path basePath, final Path relativePath, final BasicF return result; } - /* - * (non-Javadoc) - * - * @see org.apache.logging.log4j.core.appender.rolling.action.PathCondition#beforeFileTreeWalk() - */ @Override public void beforeFileTreeWalk() { IfAll.beforeFileTreeWalk(nestedConditions); } /** - * Create an IfLastModified condition. - * - * @param age The path age that is accepted by this condition. Must be a valid Duration. - * @param nestedConditions nested conditions to evaluate if this condition accepts a path - * @return An IfLastModified condition. + * @deprecated since 2.24.0 use {@link #newBuilder()} instead. */ - @PluginFactory + @Deprecated public static IfLastModified createAgeCondition( - // @formatter:off - @PluginAttribute("age") @Required(message = "No age provided for IfLastModified") final Duration age, - @PluginElement("PathConditions") final PathCondition... nestedConditions) { - // @formatter:on - return new IfLastModified(age, nestedConditions); + final org.apache.logging.log4j.core.appender.rolling.action.Duration age, + final PathCondition... pathConditions) { + return newBuilder() + .setAge(Duration.ofMillis(age.toMillis())) + .setNestedConditions(pathConditions) + .build(); } @Override @@ -110,4 +102,39 @@ public String toString() { final String nested = nestedConditions.length == 0 ? "" : " AND " + Arrays.toString(nestedConditions); return "IfLastModified(age=" + age + nested + ")"; } + + /** + * @since 2.24.0 + */ + @PluginBuilderFactory + public static Builder newBuilder() { + return new Builder(); + } + + /** + * @since 2.24.0 + */ + public static final class Builder implements org.apache.logging.log4j.core.util.Builder { + @PluginBuilderAttribute + @Required(message = "No age provided for IfLastModified") + private org.apache.logging.log4j.core.appender.rolling.action.Duration age; + + @PluginElement("nestedConditions") + private PathCondition[] nestedConditions; + + public Builder setAge(final Duration age) { + this.age = org.apache.logging.log4j.core.appender.rolling.action.Duration.ofMillis(age.toMillis()); + return this; + } + + public Builder setNestedConditions(final PathCondition... nestedConditions) { + this.nestedConditions = nestedConditions; + return this; + } + + @Override + public IfLastModified build() { + return isValid() ? new IfLastModified(Duration.ofMillis(age.toMillis()), nestedConditions) : null; + } + } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/package-info.java index 76054597368..4e9d1a1bb9d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/package-info.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/package-info.java @@ -18,7 +18,7 @@ * Support classes for the Rolling File Appender. */ @Export -@Version("2.20.2") +@Version("2.24.0") package org.apache.logging.log4j.core.appender.rolling.action; import org.osgi.annotation.bundle.Export; diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java index 987e68e9cc4..3e005f07c5d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.java @@ -36,7 +36,6 @@ import java.util.regex.Pattern; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.appender.rolling.action.Duration; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.util.CronExpression; import org.apache.logging.log4j.status.StatusLogger; @@ -224,14 +223,17 @@ public Double convert(final String s) { } /** - * Converts a {@link String} into a {@link Duration}. + * Converts a {@link String} into a {@link org.apache.logging.log4j.core.appender.rolling.action.Duration}. * @since 2.5 + * @deprecated since 2.24.0. A {@link java.time.Duration} converter will be available in 3.0.0. */ @Plugin(name = "Duration", category = CATEGORY) - public static class DurationConverter implements TypeConverter { + @Deprecated + public static class DurationConverter + implements TypeConverter { @Override - public Duration convert(final String s) { - return Duration.parse(s); + public org.apache.logging.log4j.core.appender.rolling.action.Duration convert(final String s) { + return org.apache.logging.log4j.core.appender.rolling.action.Duration.parse(s); } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/package-info.java index 59da1e88bc7..a4300945314 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/package-info.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/convert/package-info.java @@ -20,7 +20,7 @@ * attributes in plugin factory methods. */ @Export -@Version("2.20.2") +@Version("2.24.0") package org.apache.logging.log4j.core.config.plugins.convert; import org.osgi.annotation.bundle.Export; diff --git a/src/changelog/.2.x.x/deprecate_duration.xml b/src/changelog/.2.x.x/deprecate_duration.xml new file mode 100644 index 00000000000..f11e9c569ad --- /dev/null +++ b/src/changelog/.2.x.x/deprecate_duration.xml @@ -0,0 +1,7 @@ + + + Deprecate `org.apache.logging.log4j.core.appender.rolling.action.Duration` class for removal. +