/*
* Copyright (c) 2002 Cunningham & Cunningham, Inc.
* Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence
*
* This file is part of FitGoodies.
*
* FitGoodies is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FitGoodies is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FitGoodies. If not, see <http://www.gnu.org/licenses/>.
*/
package de.cologneintelligence.fitgoodies.runners;
import java.io.File;
import java.io.Serializable;
import java.util.Comparator;
import java.util.regex.Pattern;
/**
* Compares two FileInformation objects. They are sorted in alphabetical order,
* with two exceptions: files with the name "setup.html" are the first
* file in the directory, files named "teardown.html" are processed as
* the last item in a directory
*/
public abstract class FitFilenameComparator<T> implements Comparator<T>, Serializable {
private static final long serialVersionUID = 2;
private static final int RIGHT_IS_SMALLER = 1;
private static final int LEFT_IS_SMALLER = -1;
private static final int EQUAL = 0;
private static final Pattern setupPattern =
Pattern.compile("([\\\\/]|^)setup\\.html?$", Pattern.CASE_INSENSITIVE);
private static final Pattern tearDownPattern =
Pattern.compile("([\\\\//]|^)teardown\\.html?$", Pattern.CASE_INSENSITIVE);
/**
* Compare two <code>FileInformation</code> objects. See {@link FitFilenameComparator}
* for more information.
*
* @param lhs left hand side
* @param rhs right hand side
* @return < 0 if <code>lhs</code> is greater, > 0 if <code>rhr</code>
* is greater, 0 if they are equal.
*/
@Override
public final int compare(final T lhs, final T rhs) {
int c = compareDirectoryNames(lhs, rhs);
if (c == EQUAL) {
if (isSetupFile(lhs) || isTearDownFile(rhs)) {
return LEFT_IS_SMALLER;
} else if (isSetupFile(rhs) || isTearDownFile(lhs)) {
return RIGHT_IS_SMALLER;
} else {
return compareFullnames(lhs, rhs);
}
} else if (c <= LEFT_IS_SMALLER) {
return subCompare(lhs, rhs);
} else {
return -subCompare(rhs, lhs);
}
}
private int subCompare(final T lhs, final T rhs) {
if (isSubDirectory(lhs, rhs) && isSetupFile(lhs)) {
return LEFT_IS_SMALLER;
} else if (isSubDirectory(lhs, rhs) && isTearDownFile(lhs)) {
return RIGHT_IS_SMALLER;
} else {
return compareFullnames(lhs, rhs);
}
}
private boolean isSubDirectory(final T lhs, final T rhs) {
String leftDir = getParent(lhs);
String rightDir = getParent(rhs);
return leftDir.length() <= rightDir.length() && rightDir.startsWith(leftDir);
}
private int compareFullnames(final T lhs, final T rhs) {
return getFile(lhs).getPath().compareTo(getFile(rhs).getPath());
}
private int compareDirectoryNames(final T lhs, final T rhs) {
return getParent(lhs).compareTo(getParent(rhs));
}
private String getParent(T file) {
String parent = getFile(file).getParent();
return parent == null ? "" : parent;
}
private boolean isTearDownFile(final T fo) {
return tearDownPattern.matcher(getFileName(fo)).find();
}
private boolean isSetupFile(final T fo) {
return setupPattern.matcher(getFileName(fo)).find();
}
protected abstract File getFile(T file);
protected abstract String getFileName(T file);
}