/** * DataCleaner (community edition) * Copyright (C) 2014 Neopost - Customer Information Management * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * This program 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 Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.datacleaner.extension.output; import java.util.Comparator; import org.apache.metamodel.data.Row; import org.apache.metamodel.util.NumberComparator; import org.datacleaner.api.InputColumn; import org.datacleaner.components.convert.ConvertToDateTransformer; import org.datacleaner.components.convert.ConvertToNumberTransformer; import org.datacleaner.util.CompareUtils; import org.datacleaner.util.ReflectionUtils; public class SortHelper { /** * Creates a comparator for the {@link InputColumn} based on its type * (sorting numerically or lexicographically). * * @param column * the column to sort on * @param columnIndex * the index of the column in the input {@link Row} * @return the comparator instance */ public static Comparator<Row> createComparator(final InputColumn<?> column, final int columnIndex) { final Class<?> dataType = column.getDataType(); final boolean isNumber = dataType != null && ReflectionUtils.isNumber(dataType); final boolean isDate = dataType != null && ReflectionUtils.isDate(dataType); return (row1, row2) -> { final Comparable<?> value1 = getComparableValue(row1, columnIndex, isNumber, isDate); final Comparable<?> value2 = getComparableValue(row2, columnIndex, isNumber, isDate); final int comparableResult = CompareUtils.compareUnbound(value1, value2); if (comparableResult != 0) { return comparableResult; } else { // The values of the data at the row, and column to be // sorted on are // exactly the same. Now look at other values of all the // columns to // find if the two rows are same. final int numberOfSelectItems = row1.getSelectItems().length; for (int i = 0; i < numberOfSelectItems; i++) { final String rowValue1 = (String) row1.getValue(i); final String rowValue2 = (String) row2.getValue(i); final int compareResult = rowValue1.compareToIgnoreCase(rowValue2); if (compareResult == 0) { continue; } else { return compareResult; } } } return comparableResult; }; } private static Comparable<?> getComparableValue(final Row row, final int columnIndex, final boolean isNumber, final boolean isDate) { final String value = (String) row.getValue(columnIndex); if (isNumber) { final Number result = ConvertToNumberTransformer.transformValue(value); if (result instanceof Comparable) { return (Comparable<?>) result; } return NumberComparator.getComparable(result); } if (isDate) { return ConvertToDateTransformer.getInternalInstance().transformValue(value); } return value.toLowerCase(); } }