All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fcrepo.utilities.FileComparator Maven / Gradle / Ivy

There is a newer version: 6.5.0
Show newest version
/* The contents of this file are subject to the license and copyright terms
 * detailed in the license directory at the root of the source tree (also 
 * available online at http://fedora-commons.org/license/).
 */
package org.fcrepo.utilities;

import java.io.File;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * Comparator for sorting files and directories in a deterministic manner. The
 * sort order can be case-sensitive (default) or case-insensitive, ascending
 * (default) or descending, with directories occurring before (if ascending) or
 * after files within the same directory. The default behavior has the
 * convenient property that it sorts in the same order as would be done when
 * performing a pre-order traversal of the filesystem.
 * 
 * 
 * Example input:
 *   afile
 *   file1
 *   file2
 *   dir1/
 *   FILE3
 *   dir1/file4
 *   dir2/file5
 *   dir2/file10
 *   dir2/
 *   file6
 *
 * Example output (with default behavior: case-sensitive, ascending):
 *   dir1
 *   dir1\file4
 *   dir2
 *   dir2\file10
 *   dir2\file5
 *   FILE3
 *   afile
 *   file1
 *   file2
 *   file6
 * 
* * @author Chris Wilper */ public class FileComparator implements Comparator { private int m_multiplier = 1; private boolean m_ignoreCase = false; /** * Construct a case-sensitive comparator that sorts in ascending order. */ public FileComparator() { } /** * Construct a case-sensitive comparator that sorts in the specified order. */ public FileComparator(boolean useDescendingOrder) { if (useDescendingOrder) { m_multiplier = -1; } } /** * Construct a comparator that sorts in the specified order using the * specified case sensitivity. */ public FileComparator(boolean useDescendingOrder, boolean ignoreCase) { this(useDescendingOrder); m_ignoreCase = ignoreCase; } public int compare(Object o1, Object o2) { String s1 = getComparable(o1); String s2 = getComparable(o2); if (m_ignoreCase) { return m_multiplier * s1.compareToIgnoreCase(s2); } else { return m_multiplier * s1.compareTo(s2); } } /** * Does this comparator work for descending sorts? */ public boolean descends() { return m_multiplier == -1; } /** * Does this comparator ignore case? */ public boolean ignoresCase() { return m_ignoreCase; } private static String getComparable(Object o) { File f = (File) o; StringBuffer out = new StringBuffer(); // prepend a space to the name of all directories in the path StringTokenizer names = new StringTokenizer(f.getPath(), File.separator); int last = names.countTokens(); int count = 0; while (names.hasMoreTokens()) { String name = names.nextToken(); count++; if (count != 1) { out.append(File.separator); } if (count == last && !f.isDirectory()) { out.append(name); } else { out.append(" " + name); } } return out.toString(); } @Override public boolean equals(Object o) { if (o instanceof FileComparator) { FileComparator c = (FileComparator) o; return descends() == c.descends() && ignoresCase() == c.ignoresCase(); } else { return false; } } /** * Command-line entry point for simple testing of this class. Given a * directory, get all files and dirs (recursively) in no particular order. * Print all filenames (using spaces to denote directory names) in unsorted, * default sorted, and FileComparator sorted order. */ public static void main(String[] args) { List list = new ArrayList(); getFilesAndDirs(new File(args[0]), list); File[] files = new File[list.size()]; for (int i = 0; i < files.length; i++) { files[i] = (File) list.get(i); } print("Before sorting", files); Arrays.sort(files); print("Default File sorting", files); Arrays.sort(files, new FileComparator()); print("Sorted with FileComparator", files); Arrays.sort(files, new FileComparator(true)); print("Sorted with FileComparator in reverse", files); } // for testing via main private static void print(String kind, File[] f) { System.out.println(kind); for (File element : f) { System.out.println(getComparable(element)); } System.out.println(); } // for testing via main private static void getFilesAndDirs(File dir, List list) { File[] files = dir.listFiles(); for (File element : files) { list.add(element); if (element.isDirectory()) { getFilesAndDirs(element, list); } } } }