Skip to content

Commit faa58c0

Browse files
author
Niall Pemberton
committed
IO-186 new Composite and DIrectory File Comparator implementations
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/io/trunk@721744 13f79535-47bb-0310-9956-ffa450edef68
1 parent 0a3e961 commit faa58c0

4 files changed

Lines changed: 388 additions & 0 deletions

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.comparator;
18+
19+
import java.io.File;
20+
import java.io.Serializable;
21+
import java.util.ArrayList;
22+
import java.util.Comparator;
23+
import java.util.List;
24+
25+
/**
26+
* Compare two files using a set of delegate file {@link Comparator}.
27+
* <p>
28+
* This comparator can be used to sort lists or arrays of files
29+
* by combining a number other comparators.
30+
* <p>
31+
* Example of sorting a list of files by type (i.e. directory or file)
32+
* and then by name:
33+
* <pre>
34+
* CompositeFileComparator comparator =
35+
* new CompositeFileComparator(
36+
* DirectoryFileComparator.DIRECTORY_COMPARATOR,
37+
* NameFileComparator.NAME_COMPARATOR);
38+
* List&lt;File&gt; list = ...
39+
* comparator.sort(list);
40+
* </pre>
41+
*
42+
* @version $Revision$ $Date$
43+
* @since Commons IO 2.0
44+
*/
45+
public class CompositeFileComparator extends AbstractFileComparator implements Serializable {
46+
47+
private final Comparator<File>[] delegates;
48+
49+
/**
50+
* Create a composite comparator for the set of delegate comparators.
51+
*
52+
* @param delegates The delegate file comparators
53+
*/
54+
public CompositeFileComparator(Comparator<File>... delegates) {
55+
int size = (delegates == null ? 0 : delegates.length);
56+
this.delegates = new Comparator[size];
57+
for (int i = 0; i < size; i++) {
58+
this.delegates[i] = delegates[i];
59+
}
60+
}
61+
62+
/**
63+
* Create a composite comparator for the set of delegate comparators.
64+
*
65+
* @param delegates The delegate file comparators
66+
*/
67+
public CompositeFileComparator(Iterable<Comparator<File>> delegates) {
68+
List<Comparator<File>> list = new ArrayList<Comparator<File>>();
69+
if (delegates != null) {
70+
for (Comparator<File> comparator : delegates) {
71+
list.add(comparator);
72+
}
73+
}
74+
this.delegates = list.toArray(new Comparator[list.size()]);
75+
}
76+
77+
/**
78+
* Compare the two files using delegate comparators.
79+
*
80+
* @param file1 The first file to compare
81+
* @param file2 The second file to compare
82+
* @return the first non-zero result returned from
83+
* the delegate comparators or zero.
84+
*/
85+
public int compare(File file1, File file2) {
86+
int result = 0;
87+
for (int i = 0; i < delegates.length; i++) {
88+
result = delegates[i].compare(file1, file2);
89+
if (result != 0) {
90+
break;
91+
}
92+
}
93+
return result;
94+
}
95+
96+
/**
97+
* String representation of this file comparator.
98+
*
99+
* @return String representation of this file comparator
100+
*/
101+
public String toString() {
102+
StringBuilder builder = new StringBuilder();
103+
builder.append(super.toString());
104+
builder.append('{');
105+
for (int i = 0; i < delegates.length; i++) {
106+
if (i > 0) {
107+
builder.append(',');
108+
}
109+
builder.append(delegates[i]);
110+
}
111+
builder.append('}');
112+
return builder.toString();
113+
}
114+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.comparator;
18+
19+
import java.io.File;
20+
import java.io.Serializable;
21+
import java.util.Comparator;
22+
23+
/**
24+
* Compare two files using the <b>default</b> {@link File#isDirectory()} method.
25+
* <p>
26+
* This comparator can be used to sort lists or arrays by directories and files.
27+
* <p>
28+
* Example of sorting a list of files/directories using the
29+
* {@link #DIRECTORY_COMPARATOR} singleton instance:
30+
* <pre>
31+
* List&lt;File&gt; list = ...
32+
* DirectoryFileComparator.DIRECTORY_COMPARATOR.sort(list);
33+
* </pre>
34+
* <p>
35+
* Example of doing a <i>reverse</i> sort of an array of files/directories using the
36+
* {@link #DEFAULT_REVERSE} singleton instance:
37+
* <pre>
38+
* File[] array = ...
39+
* DirectoryFileComparator.DIRECTORY_REVERSE.sort(array);
40+
* </pre>
41+
* <p>
42+
*
43+
* @version $Revision$ $Date$
44+
* @since Commons IO 2.0
45+
*/
46+
public class DirectoryFileComparator extends AbstractFileComparator implements Serializable {
47+
48+
/** Singleton default comparator instance */
49+
public static final Comparator<File> DIRECTORY_COMPARATOR = new DirectoryFileComparator();
50+
51+
/** Singleton reverse default comparator instance */
52+
public static final Comparator<File> DIRECTORY_REVERSE = new ReverseComparator(DIRECTORY_COMPARATOR);
53+
54+
/**
55+
* Compare the two files using the {@link File#isDirectory()} method.
56+
*
57+
* @param file1 The first file to compare
58+
* @param file2 The second file to compare
59+
* @return the result of calling file1's
60+
* {@link File#compareTo(File)} with file2 as the parameter.
61+
*/
62+
public int compare(File file1, File file2) {
63+
return (getType(file1) - getType(file2));
64+
}
65+
66+
/**
67+
* Convert type to numeric value.
68+
*
69+
* @param file The file
70+
* @return 1 for directories and 2 for files
71+
*/
72+
private int getType(File file) {
73+
if (file.isDirectory()) {
74+
return 1;
75+
} else {
76+
return 2;
77+
}
78+
}
79+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.comparator;
18+
19+
import java.io.File;
20+
import java.util.ArrayList;
21+
import java.util.Comparator;
22+
import java.util.List;
23+
24+
import junit.framework.Test;
25+
import junit.framework.TestSuite;
26+
import junit.textui.TestRunner;
27+
28+
/**
29+
* Test case for {@link CompositeFileComparator}.
30+
*/
31+
public class CompositeFileComparatorTest extends ComparatorAbstractTestCase {
32+
33+
/**
34+
* Run the test.
35+
*
36+
* @param args arguments
37+
*/
38+
public static void main(String[] args) {
39+
TestRunner.run(suite());
40+
}
41+
42+
/**
43+
* Create a test suite.
44+
*
45+
* @return The test suite
46+
*/
47+
public static Test suite() {
48+
return new TestSuite(CompositeFileComparatorTest.class);
49+
}
50+
51+
/**
52+
* Construct a new test case with the specified name.
53+
*
54+
* @param name Name of the test
55+
*/
56+
public CompositeFileComparatorTest(String name) {
57+
super(name);
58+
}
59+
60+
/** @see junit.framework.TestCase#setUp() */
61+
protected void setUp() throws Exception {
62+
super.setUp();
63+
comparator = new CompositeFileComparator(SizeFileComparator.SIZE_COMPARATOR,
64+
ExtensionFileComparator.EXTENSION_COMPARATOR);
65+
reverse = new ReverseComparator(comparator);
66+
File dir = getTestDirectory();
67+
lessFile = new File(dir, "xyz.txt");
68+
equalFile1 = new File(dir, "foo.txt");
69+
equalFile2 = new File(dir, "bar.txt");
70+
moreFile = new File(dir, "foo.xyz");
71+
createFile(lessFile, 32);
72+
createFile(equalFile1, 48);
73+
createFile(equalFile2, 48);
74+
createFile(moreFile, 48);
75+
}
76+
77+
/**
78+
* Test Constructor with null Iterable
79+
*/
80+
public void testConstructorIterable() {
81+
List<Comparator<File>> list = new ArrayList<Comparator<File>>();
82+
list.add(SizeFileComparator.SIZE_COMPARATOR);
83+
list.add(ExtensionFileComparator.EXTENSION_COMPARATOR);
84+
Comparator<File> c = new CompositeFileComparator(list);
85+
86+
assertTrue("equal", c.compare(equalFile1, equalFile2) == 0);
87+
assertTrue("less", c.compare(lessFile, moreFile) < 0);
88+
assertTrue("more", c.compare(moreFile, lessFile) > 0);
89+
}
90+
91+
/**
92+
* Test Constructor with null Iterable
93+
*/
94+
public void testConstructorIterableNull() {
95+
Comparator<File> c = new CompositeFileComparator((Iterable)null);
96+
assertEquals("less,more", 0, c.compare(lessFile, moreFile));
97+
assertEquals("more,less", 0, c.compare(moreFile, lessFile));
98+
assertEquals("toString", "CompositeFileComparator{}", c.toString());
99+
}
100+
101+
/**
102+
* Test Constructor with null array
103+
*/
104+
public void testConstructorArrayNull() {
105+
Comparator<File> c = new CompositeFileComparator((Comparator[])null);
106+
assertEquals("less,more", 0, c.compare(lessFile, moreFile));
107+
assertEquals("more,less", 0, c.compare(moreFile, lessFile));
108+
assertEquals("toString", "CompositeFileComparator{}", c.toString());
109+
}
110+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.io.comparator;
18+
19+
import java.io.File;
20+
21+
import junit.framework.Test;
22+
import junit.framework.TestSuite;
23+
import junit.textui.TestRunner;
24+
25+
/**
26+
* Test case for {@link DirectoryFileComparator}.
27+
*/
28+
public class DirectoryFileComparatorTest extends ComparatorAbstractTestCase {
29+
30+
/**
31+
* Run the test.
32+
*
33+
* @param args arguments
34+
*/
35+
public static void main(String[] args) {
36+
TestRunner.run(suite());
37+
}
38+
39+
/**
40+
* Create a test suite.
41+
*
42+
* @return The test suite
43+
*/
44+
public static Test suite() {
45+
return new TestSuite(DirectoryFileComparatorTest.class);
46+
}
47+
48+
/**
49+
* Construct a new test case with the specified name.
50+
*
51+
* @param name Name of the test
52+
*/
53+
public DirectoryFileComparatorTest(String name) {
54+
super(name);
55+
}
56+
57+
/** @see junit.framework.TestCase#setUp() */
58+
protected void setUp() throws Exception {
59+
super.setUp();
60+
comparator = (AbstractFileComparator)DirectoryFileComparator.DIRECTORY_COMPARATOR;
61+
reverse = DirectoryFileComparator.DIRECTORY_REVERSE;
62+
File currentDir = new File(".");
63+
equalFile1 = new File(currentDir, "src");
64+
equalFile2 = new File(currentDir, "xdocs");
65+
lessFile = new File(currentDir, "src");
66+
moreFile = new File(currentDir, "pom.xml");
67+
}
68+
69+
/**
70+
* Test the comparator array sort.
71+
*/
72+
@Override
73+
public void testSortArray() {
74+
// skip sort test
75+
}
76+
77+
/**
78+
* Test the comparator array sort.
79+
*/
80+
@Override
81+
public void testSortList() {
82+
// skip sort test
83+
}
84+
}
85+

0 commit comments

Comments
 (0)