LOG4J2-435 added classes and interfaces to support sorting paths before
executing the Delete action

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/b7900411
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b7900411
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b7900411

Branch: refs/heads/master
Commit: b7900411178242e14ebb2445894699890c5c0eb0
Parents: 6a1a2af
Author: rpopma <[email protected]>
Authored: Thu Nov 26 23:43:43 2015 +0900
Committer: rpopma <[email protected]>
Committed: Thu Nov 26 23:43:43 2015 +0900

----------------------------------------------------------------------
 .../action/PathSortByModificationTime.java      | 74 ++++++++++++++++
 .../appender/rolling/action/PathSorter.java     | 27 ++++++
 .../rolling/action/PathWithAttributes.java      | 52 +++++++++++
 .../appender/rolling/action/SortingVisitor.java | 58 ++++++++++++
 .../action/PathSortByModificationTimeTest.java  | 93 ++++++++++++++++++++
 .../rolling/action/SortingVisitorTest.java      | 89 +++++++++++++++++++
 6 files changed, 393 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTime.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTime.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTime.java
new file mode 100644
index 0000000..522d1c3
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTime.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+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.PluginFactory;
+
+/**
+ * {@link PathSorter} that sorts path by their LastModified attribute.
+ */
+@Plugin(name = "SortByModificationTime", category = "Core", printObject = true)
+public class PathSortByModificationTime implements PathSorter {
+
+    private final boolean recentFirst;
+    private final int multiplier;
+
+    /**
+     * Constructs a new SortByModificationTime sorter.
+     * 
+     * @param recentFirst if true, most recently modified paths should come 
first
+     */
+    public PathSortByModificationTime(final boolean recentFirst) {
+        this.recentFirst = recentFirst;
+        this.multiplier = recentFirst ? 1 : -1;
+    }
+
+    /**
+     * Create a PathSorter that sorts by lastModified time.
+     * 
+     * @param recentFirst if true, most recently modified paths should come 
first.
+     * @return A PathSorter.
+     */
+    @PluginFactory
+    public static PathSorter createSorter( //
+            @PluginAttribute(value = "recentFirst", defaultBoolean = true) 
final boolean recentFirst) {
+        return new PathSortByModificationTime(recentFirst);
+    }
+
+    /**
+     * Returns whether this sorter sorts recent files first.
+     * @return whether this sorter sorts recent files first
+     */
+    public boolean isRecentFirst() {
+        return recentFirst;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+     */
+    @Override
+    public int compare(final PathWithAttributes path1, final 
PathWithAttributes path2) {
+        final long lastModified1 = 
path1.getAttributes().lastModifiedTime().toMillis();
+        final long lastModified2 = 
path2.getAttributes().lastModifiedTime().toMillis();
+        return multiplier * Long.signum(lastModified2 - lastModified1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java
new file mode 100644
index 0000000..2e765ab
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.util.Comparator;
+
+/**
+ * Defines the interface of classes that can sort Paths.
+ */
+public interface PathSorter extends Comparator<PathWithAttributes>{
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java
new file mode 100644
index 0000000..88c460a
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Objects;
+
+/**
+ * Tuple of a {@code Path} and {@code BasicFileAttributes}, used for sorting.
+ */
+public class PathWithAttributes {
+
+    private final Path path;
+    private final BasicFileAttributes attributes;
+
+    public PathWithAttributes(final Path path, final BasicFileAttributes 
attributes) {
+        this.path = Objects.requireNonNull(path, "path");
+        this.attributes = Objects.requireNonNull(attributes, "attributes");
+    }
+
+    /**
+     * Returns the path.
+     * @return the path
+     */
+    public Path getPath() {
+        return path;
+    }
+
+    /**
+     * Returns the attributes.
+     * @return the attributes
+     */
+    public BasicFileAttributes getAttributes() {
+        return attributes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java
new file mode 100644
index 0000000..7bf76b6
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * FileVisitor that sorts files.
+ */
+public class SortingVisitor extends SimpleFileVisitor<Path> {
+
+    private final PathSorter sorter;
+    private final List<PathWithAttributes> collected = new ArrayList<>();
+
+    /**
+     * Constructs a new DeletingVisitor.
+     * 
+     * @param basePath used to relativize paths
+     * @param pathFilters objects that need to confirm whether a file can be 
deleted
+     */
+    public SortingVisitor(final PathSorter sorter) {
+        this.sorter = Objects.requireNonNull(sorter, "sorter");
+    }
+
+    @Override
+    public FileVisitResult visitFile(final Path path, final 
BasicFileAttributes attrs) throws IOException {
+        collected.add(new PathWithAttributes(path, attrs));
+        return FileVisitResult.CONTINUE;
+    }
+    
+    public List<PathWithAttributes> getSortedPaths() {
+        Collections.sort(collected, sorter);
+        return collected;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
new file mode 100644
index 0000000..8127cac
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/PathSortByModificationTimeTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the {@code PathSortByModificationTime} class.
+ */
+public class PathSortByModificationTimeTest {
+
+    /**
+     * Test method for
+     * {@link 
org.apache.logging.log4j.core.appender.rolling.action.PathSortByModificationTime#isRecentFirst()}.
+     */
+    @Test
+    public void testIsRecentFirstReturnsConstructorValue() {
+        assertTrue(((PathSortByModificationTime) 
PathSortByModificationTime.createSorter(true)).isRecentFirst());
+        assertFalse(((PathSortByModificationTime) 
PathSortByModificationTime.createSorter(false)).isRecentFirst());
+    }
+
+    @Test
+    public void testCompareRecentFirst() {
+        PathSorter sorter = PathSortByModificationTime.createSorter(true);
+        Path p1 = Paths.get("aaa");
+        Path p2 = Paths.get("bbb");
+        DummyFileAttributes a1 = new DummyFileAttributes();
+        DummyFileAttributes a2 = new DummyFileAttributes();
+        a1.lastModified = FileTime.fromMillis(100);
+        a2.lastModified = FileTime.fromMillis(222);
+        
+        assertEquals("same path, 2nd more recent", 1, sorter.compare(path(p1, 
a1), path(p1, a2)));
+        assertEquals("path ignored, 2nd more recent", 1, 
sorter.compare(path(p1, a1), path(p2, a2)));
+        assertEquals("path ignored, 2nd more recent", 1, 
sorter.compare(path(p2, a1), path(p1, a2)));
+        
+        assertEquals("same path, 1st more recent", -1, sorter.compare(path(p1, 
a2), path(p1, a1)));
+        assertEquals("path ignored, 1st more recent", -1, 
sorter.compare(path(p1, a2), path(p2, a1)));
+        assertEquals("path ignored, 1st more recent", -1, 
sorter.compare(path(p2, a2), path(p1, a1)));
+        
+        assertEquals("same path, same time", 0, sorter.compare(path(p1, a1), 
path(p1, a1)));
+        assertEquals("path ignored, same time", 0, sorter.compare(path(p1, 
a1), path(p2, a1)));
+        assertEquals("path ignored, same time", 0, sorter.compare(path(p2, 
a1), path(p1, a1)));
+    }
+
+    @Test
+    public void testCompareRecentLast() {
+        PathSorter sorter = PathSortByModificationTime.createSorter(false);
+        Path p1 = Paths.get("aaa");
+        Path p2 = Paths.get("bbb");
+        DummyFileAttributes a1 = new DummyFileAttributes();
+        DummyFileAttributes a2 = new DummyFileAttributes();
+        a1.lastModified = FileTime.fromMillis(100);
+        a2.lastModified = FileTime.fromMillis(222);
+        
+        assertEquals("same path, 2nd more recent", -1, sorter.compare(path(p1, 
a1), path(p1, a2)));
+        assertEquals("path ignored, 2nd more recent", -1, 
sorter.compare(path(p1, a1), path(p2, a2)));
+        assertEquals("path ignored, 2nd more recent", -1, 
sorter.compare(path(p2, a1), path(p1, a2)));
+        
+        assertEquals("same path, 1st more recent", 1, sorter.compare(path(p1, 
a2), path(p1, a1)));
+        assertEquals("path ignored, 1st more recent", 1, 
sorter.compare(path(p1, a2), path(p2, a1)));
+        assertEquals("path ignored, 1st more recent", 1, 
sorter.compare(path(p2, a2), path(p1, a1)));
+        
+        assertEquals("same path, same time", 0, sorter.compare(path(p1, a1), 
path(p1, a1)));
+        assertEquals("path ignored, same time", 0, sorter.compare(path(p1, 
a1), path(p2, a1)));
+        assertEquals("path ignored, same time", 0, sorter.compare(path(p2, 
a1), path(p1, a1)));
+    }
+
+    private PathWithAttributes path(Path path, DummyFileAttributes attributes) 
{
+        return new PathWithAttributes(path, attributes);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b7900411/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitorTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitorTest.java
 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitorTest.java
new file mode 100644
index 0000000..8cb2530
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitorTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.nio.file.FileVisitOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests the SortingVisitor class.
+ */
+public class SortingVisitorTest {
+    
+    private Path base;
+    private Path aaa;
+    private Path bbb;
+    private Path ccc;
+
+    @Before
+    public void setUp() throws Exception {
+        base = Files.createTempDirectory("tempDir", new FileAttribute<?>[0]);
+        aaa = Files.createTempFile(base, "aaa", null, new FileAttribute<?>[0]);
+        Thread.sleep(1);
+        bbb = Files.createTempFile(base, "bbb", null, new FileAttribute<?>[0]);
+        Thread.sleep(1);
+        ccc = Files.createTempFile(base, "ccc", null, new FileAttribute<?>[0]);
+    }
+    
+    @After
+    public void tearDown() throws Exception {
+        Files.deleteIfExists(ccc);
+        Files.deleteIfExists(bbb);
+        Files.deleteIfExists(aaa);
+        Files.deleteIfExists(base);
+    }
+
+    @Test
+    public void testRecentFirst() throws Exception {
+        SortingVisitor visitor = new SortingVisitor(new 
PathSortByModificationTime(true));
+        Set<FileVisitOption> options = Collections.emptySet();
+        Files.walkFileTree(base, options, 1, visitor);
+
+        List<PathWithAttributes> found = visitor.getSortedPaths();
+        assertNotNull(found);
+        assertEquals("file count", 3, found.size());
+        assertEquals("1st: most recent", ccc, found.get(0).getPath());
+        assertEquals("2nd", bbb, found.get(1).getPath());
+        assertEquals("3rd: oldest", aaa, found.get(2).getPath());
+    }
+
+    @Test
+    public void testRecentLast() throws Exception {
+        SortingVisitor visitor = new SortingVisitor(new 
PathSortByModificationTime(false));
+        Set<FileVisitOption> options = Collections.emptySet();
+        Files.walkFileTree(base, options, 1, visitor);
+
+        List<PathWithAttributes> found = visitor.getSortedPaths();
+        assertNotNull(found);
+        assertEquals("file count", 3, found.size());
+        assertEquals("1st: oldest first", aaa, found.get(0).getPath());
+        assertEquals("2nd", bbb, found.get(1).getPath());
+        assertEquals("3rd: most recent last", ccc, found.get(2).getPath());
+    }
+}

Reply via email to