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