/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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. */ package com.liferay.portal.kernel.util; import com.liferay.portal.kernel.bean.BeanPropertiesUtil; import com.liferay.portal.kernel.model.BaseModel; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @author Brian Wing Shun Chan */ public class OrderByComparatorFactoryUtil { public static <T extends BaseModel<T>> OrderByComparator<T> create( String tableName, Object... columns) { if ((columns.length == 0) || ((columns.length % 2) != 0)) { throw new IllegalArgumentException( "Columns length is not an even number"); } return new DefaultOrderByComparator<>(tableName, columns); } protected static class DefaultOrderByComparator<T extends BaseModel<T>> extends OrderByComparator<T> { @Override public int compare(T object1, T object2) { for (int i = 0; i < _columns.length; i += 2) { String columnName = String.valueOf(_columns[i]); boolean columnAscending = Boolean.valueOf( String.valueOf(_columns[i + 1])); Object columnInstance = null; Class<?> columnClass = BeanPropertiesUtil.getObjectTypeSilent( object1, columnName); if (columnClass.isPrimitive()) { columnInstance = _primitiveObjects.get(columnClass); } else { try { columnInstance = columnClass.newInstance(); } catch (Exception e) { } } Object columnValue1 = BeanPropertiesUtil.getObjectSilent( object1, columnName); Object columnValue2 = BeanPropertiesUtil.getObjectSilent( object2, columnName); if (columnInstance instanceof Date) { Date columnValueDate1 = (Date)columnValue1; Date columnValueDate2 = (Date)columnValue2; int value = DateUtil.compareTo( columnValueDate1, columnValueDate2); if (value == 0) { continue; } if (columnAscending) { return value; } else { return -value; } } else if (columnInstance instanceof Comparable<?>) { Comparable<Object> columnValueComparable1 = (Comparable<Object>)columnValue1; Comparable<Object> columnValueComparable2 = (Comparable<Object>)columnValue2; int value = columnValueComparable1.compareTo( columnValueComparable2); if (value == 0) { continue; } if (columnAscending) { return value; } else { return -value; } } } return 0; } @Override public String getOrderBy() { StringBundler sb = new StringBundler(5 * _columns.length - 1); for (int i = 0; i < _columns.length; i += 2) { if (i != 0) { sb.append(StringPool.COMMA); } sb.append(_tableName); sb.append(StringPool.PERIOD); String columnName = String.valueOf(_columns[i]); boolean columnAscending = Boolean.valueOf( String.valueOf(_columns[i + 1])); sb.append(columnName); if (columnAscending) { sb.append(_ORDER_BY_ASC); } else { sb.append(_ORDER_BY_DESC); } } return sb.toString(); } @Override public boolean isAscending(String field) { String orderBy = getOrderBy(); if (orderBy == null) { return false; } int x = orderBy.indexOf( StringPool.PERIOD + field + StringPool.SPACE); if (x == -1) { return false; } int y = orderBy.indexOf(_ORDER_BY_ASC, x); if (y == -1) { return false; } int z = orderBy.indexOf(_ORDER_BY_DESC, x); if ((z >= 0) && (z < y)) { return false; } else { return true; } } private DefaultOrderByComparator(String tableName, Object... columns) { _tableName = tableName; _columns = columns; } private static final String _ORDER_BY_ASC = " ASC"; private static final String _ORDER_BY_DESC = " DESC"; private static final Map<Class<?>, Object> _primitiveObjects = new HashMap<>(); static { _primitiveObjects.put(boolean.class, Boolean.TRUE); _primitiveObjects.put(byte.class, Byte.valueOf("0")); _primitiveObjects.put(char.class, Character.valueOf('0')); _primitiveObjects.put(double.class, Double.valueOf(0)); _primitiveObjects.put(float.class, Float.valueOf(0)); _primitiveObjects.put(int.class, Integer.valueOf(0)); _primitiveObjects.put(long.class, Long.valueOf(0)); _primitiveObjects.put(short.class, Short.valueOf("0")); } private final Object[] _columns; private final String _tableName; } }