001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util;
016    
017    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
018    import com.liferay.portal.kernel.util.DateUtil;
019    import com.liferay.portal.kernel.util.OrderByComparator;
020    import com.liferay.portal.kernel.util.OrderByComparatorFactory;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    
024    import java.util.Date;
025    
026    /**
027     * @author Brian Wing Shun Chan
028     */
029    public class OrderByComparatorFactoryImpl implements OrderByComparatorFactory {
030    
031            public OrderByComparator create(String tableName, Object... columns) {
032                    if ((columns.length == 0) || ((columns.length % 2) != 0)) {
033                            throw new IllegalArgumentException(
034                                    "Columns length is not an even number");
035                    }
036    
037                    return new DefaultOrderByComparator(tableName, columns);
038            }
039    
040            protected class DefaultOrderByComparator extends OrderByComparator {
041    
042                    @Override
043                    public int compare(Object object1, Object object2) {
044                            for (int i = 0; i < _columns.length; i += 2) {
045                                    String columnName = String.valueOf(_columns[i]);
046                                    boolean columnAscending = Boolean.valueOf(
047                                            String.valueOf(_columns[i + 1]));
048    
049                                    Class<?> columnClass = BeanPropertiesUtil.getObjectTypeSilent(
050                                            object1, columnName);
051    
052                                    Object columnInstance = null;
053    
054                                    try {
055                                            columnInstance = columnClass.newInstance();
056                                    }
057                                    catch (Exception e) {
058                                    }
059    
060                                    Object columnValue1 = BeanPropertiesUtil.getObjectSilent(
061                                            object1, columnName);
062                                    Object columnValue2 = BeanPropertiesUtil.getObjectSilent(
063                                            object2, columnName);
064    
065                                    if (columnInstance instanceof Date) {
066                                            Date columnValueDate1 = (Date)columnValue1;
067                                            Date columnValueDate2 = (Date)columnValue2;
068    
069                                            int value = DateUtil.compareTo(
070                                                    columnValueDate1, columnValueDate2);
071    
072                                            if (value == 0) {
073                                                    continue;
074                                            }
075    
076                                            if (columnAscending) {
077                                                    return value;
078                                            }
079                                            else {
080                                                    return -value;
081                                            }
082                                    }
083                                    else if (columnInstance instanceof Comparable<?>) {
084                                            Comparable<Object> columnValueComparable1 =
085                                                    (Comparable<Object>)columnValue1;
086                                            Comparable<Object> columnValueComparable2 =
087                                                    (Comparable<Object>)columnValue2;
088    
089                                            int value = columnValueComparable1.compareTo(
090                                                    columnValueComparable2);
091    
092                                            if (value == 0) {
093                                                    continue;
094                                            }
095    
096                                            if (columnAscending) {
097                                                    return value;
098                                            }
099                                            else {
100                                                    return -value;
101                                            }
102                                    }
103                            }
104    
105                            return 0;
106                    }
107    
108                    @Override
109                    public String getOrderBy() {
110                            StringBundler sb = new StringBundler();
111    
112                            for (int i = 0; i < _columns.length; i += 2) {
113                                    if (i != 0) {
114                                            sb.append(StringPool.COMMA);
115                                    }
116    
117                                    sb.append(_tableName);
118                                    sb.append(StringPool.PERIOD);
119    
120                                    String columnName = String.valueOf(_columns[i]);
121                                    boolean columnAscending = Boolean.valueOf(
122                                            String.valueOf(_columns[i + 1]));
123    
124                                    sb.append(columnName);
125    
126                                    if (columnAscending) {
127                                            sb.append(_ORDER_BY_ASC);
128                                    }
129                                    else {
130                                            sb.append(_ORDER_BY_DESC);
131                                    }
132                            }
133    
134                            return sb.toString();
135                    }
136    
137                    @Override
138                    public boolean isAscending(String field) {
139                            String orderBy = getOrderBy();
140    
141                            if (orderBy == null) {
142                                    return false;
143                            }
144    
145                            int x = orderBy.indexOf(
146                                    StringPool.PERIOD + field + StringPool.SPACE);
147    
148                            if (x == -1) {
149                                    return false;
150                            }
151    
152                            int y = orderBy.indexOf(_ORDER_BY_ASC, x);
153    
154                            if (y == -1) {
155                                    return false;
156                            }
157    
158                            int z = orderBy.indexOf(_ORDER_BY_DESC, x);
159    
160                            if ((z >= 0) && (z < y)) {
161                                    return false;
162                            }
163                            else {
164                                    return true;
165                            }
166                    }
167    
168                    private DefaultOrderByComparator(String tableName, Object... columns) {
169                            _tableName = tableName;
170                            _columns = columns;
171                    }
172    
173                    private static final String _ORDER_BY_ASC = " ASC";
174    
175                    private static final String _ORDER_BY_DESC = " DESC";
176    
177                    private Object[] _columns;
178                    private String _tableName;
179    
180            }
181    
182    }