001    /**
002     * Copyright (c) 2000-2013 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.security.pacl.DoPrivileged;
019    import com.liferay.portal.kernel.util.DateUtil;
020    import com.liferay.portal.kernel.util.OrderByComparator;
021    import com.liferay.portal.kernel.util.OrderByComparatorFactory;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    
025    import java.util.Date;
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     */
032    @DoPrivileged
033    public class OrderByComparatorFactoryImpl implements OrderByComparatorFactory {
034    
035            public OrderByComparator create(String tableName, Object... columns) {
036                    if ((columns.length == 0) || ((columns.length % 2) != 0)) {
037                            throw new IllegalArgumentException(
038                                    "Columns length is not an even number");
039                    }
040    
041                    return new DefaultOrderByComparator(tableName, columns);
042            }
043    
044            protected static class DefaultOrderByComparator extends OrderByComparator {
045    
046                    @Override
047                    public int compare(Object object1, Object object2) {
048                            for (int i = 0; i < _columns.length; i += 2) {
049                                    String columnName = String.valueOf(_columns[i]);
050                                    boolean columnAscending = Boolean.valueOf(
051                                            String.valueOf(_columns[i + 1]));
052    
053                                    Object columnInstance = null;
054    
055                                    Class<?> columnClass = BeanPropertiesUtil.getObjectTypeSilent(
056                                            object1, columnName);
057    
058                                    if (columnClass.isPrimitive()) {
059                                            columnInstance = _primitiveObjects.get(columnClass);
060                                    }
061                                    else {
062                                            try {
063                                                    columnInstance = columnClass.newInstance();
064                                            }
065                                            catch (Exception e) {
066                                            }
067                                    }
068    
069                                    Object columnValue1 = BeanPropertiesUtil.getObjectSilent(
070                                            object1, columnName);
071                                    Object columnValue2 = BeanPropertiesUtil.getObjectSilent(
072                                            object2, columnName);
073    
074                                    if (columnInstance instanceof Date) {
075                                            Date columnValueDate1 = (Date)columnValue1;
076                                            Date columnValueDate2 = (Date)columnValue2;
077    
078                                            int value = DateUtil.compareTo(
079                                                    columnValueDate1, columnValueDate2);
080    
081                                            if (value == 0) {
082                                                    continue;
083                                            }
084    
085                                            if (columnAscending) {
086                                                    return value;
087                                            }
088                                            else {
089                                                    return -value;
090                                            }
091                                    }
092                                    else if (columnInstance instanceof Comparable<?>) {
093                                            Comparable<Object> columnValueComparable1 =
094                                                    (Comparable<Object>)columnValue1;
095                                            Comparable<Object> columnValueComparable2 =
096                                                    (Comparable<Object>)columnValue2;
097    
098                                            int value = columnValueComparable1.compareTo(
099                                                    columnValueComparable2);
100    
101                                            if (value == 0) {
102                                                    continue;
103                                            }
104    
105                                            if (columnAscending) {
106                                                    return value;
107                                            }
108                                            else {
109                                                    return -value;
110                                            }
111                                    }
112                            }
113    
114                            return 0;
115                    }
116    
117                    @Override
118                    public String getOrderBy() {
119                            StringBundler sb = new StringBundler();
120    
121                            for (int i = 0; i < _columns.length; i += 2) {
122                                    if (i != 0) {
123                                            sb.append(StringPool.COMMA);
124                                    }
125    
126                                    sb.append(_tableName);
127                                    sb.append(StringPool.PERIOD);
128    
129                                    String columnName = String.valueOf(_columns[i]);
130                                    boolean columnAscending = Boolean.valueOf(
131                                            String.valueOf(_columns[i + 1]));
132    
133                                    sb.append(columnName);
134    
135                                    if (columnAscending) {
136                                            sb.append(_ORDER_BY_ASC);
137                                    }
138                                    else {
139                                            sb.append(_ORDER_BY_DESC);
140                                    }
141                            }
142    
143                            return sb.toString();
144                    }
145    
146                    @Override
147                    public boolean isAscending(String field) {
148                            String orderBy = getOrderBy();
149    
150                            if (orderBy == null) {
151                                    return false;
152                            }
153    
154                            int x = orderBy.indexOf(
155                                    StringPool.PERIOD + field + StringPool.SPACE);
156    
157                            if (x == -1) {
158                                    return false;
159                            }
160    
161                            int y = orderBy.indexOf(_ORDER_BY_ASC, x);
162    
163                            if (y == -1) {
164                                    return false;
165                            }
166    
167                            int z = orderBy.indexOf(_ORDER_BY_DESC, x);
168    
169                            if ((z >= 0) && (z < y)) {
170                                    return false;
171                            }
172                            else {
173                                    return true;
174                            }
175                    }
176    
177                    private DefaultOrderByComparator(String tableName, Object... columns) {
178                            _tableName = tableName;
179                            _columns = columns;
180                    }
181    
182                    private static final String _ORDER_BY_ASC = " ASC";
183    
184                    private static final String _ORDER_BY_DESC = " DESC";
185    
186                    private static Map<Class<?>, Object> _primitiveObjects =
187                            new HashMap<Class<?>, Object>();
188    
189                    static {
190                            _primitiveObjects.put(boolean.class, new Boolean(true));
191                            _primitiveObjects.put(byte.class, new Byte("0"));
192                            _primitiveObjects.put(char.class, new Character('0'));
193                            _primitiveObjects.put(double.class, new Double(0));
194                            _primitiveObjects.put(float.class, new Float(0));
195                            _primitiveObjects.put(int.class, new Integer(0));
196                            _primitiveObjects.put(long.class, new Long(0));
197                            _primitiveObjects.put(short.class, new Short("0"));
198                    }
199    
200                    private Object[] _columns;
201                    private String _tableName;
202    
203            }
204    
205    }