View Javadoc
1   /***************************************************************************
2    * Copyright (C) 2003-2009 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   *
17   **************************************************************************/
18  package org.exoplatform.ecm.utils.comparator;
19  
20  import java.util.Calendar;
21  import java.util.Comparator;
22  
23  import javax.jcr.Node;
24  import javax.jcr.PropertyType;
25  import javax.jcr.RepositoryException;
26  
27  import org.exoplatform.services.log.ExoLogger;
28  import org.exoplatform.services.log.Log;
29  
30  /**
31   * Created by The eXo Platform SARL
32   * Author : Hoang Van Hung
33   *          hunghvit@gmail.com
34   * May 14, 2009
35   */
36  public class PropertyValueComparator implements Comparator<Node> {
37  
38    public static final String ASCENDING_ORDER  = "Ascending";
39  
40    public static final String DESCENDING_ORDER = "Descending";
41  
42    private String             propertyName;
43  
44    private String             orderType;
45    private static final Log LOG  = ExoLogger.getLogger(PropertyValueComparator.class.getName());
46    public PropertyValueComparator(String propertyName, String orderType) {
47      this.propertyName = propertyName;
48      this.orderType = orderType;
49    }
50  
51    public int compare(Node node0, Node node1) {
52      int flipFlop = ASCENDING_ORDER.equals(orderType) ? 1 : -1;    
53      int requireType = getRequireType(node0);    
54      int requireType2 = getRequireType(node1);     
55      if (requireType == -1 && requireType2 == -1) return 0;    
56      if (requireType == -1 && requireType2 != -1) return -1 * flipFlop;    
57      if (requireType != -1 && requireType2 == -1) return 1 * flipFlop; 
58      try {
59        switch (requireType) {
60        case PropertyType.BINARY:
61          return compareString(node0, node1);
62        case PropertyType.BOOLEAN:
63          return compareString(node0, node1);
64        case PropertyType.NAME:
65          return compareString(node0, node1);
66        case PropertyType.PATH:
67          return compareString(node0, node1);
68        case PropertyType.STRING:
69          return compareString(node0, node1);
70        case PropertyType.LONG:
71          return compareLong(node0, node1);
72        case PropertyType.DOUBLE:
73          return compareLong(node0, node1);
74        case PropertyType.DATE:
75          return compareDate(node0, node1);
76        case PropertyType.REFERENCE:
77          return compareString(node0, node1);
78        default:
79          throw new RepositoryException("Unknown type " + requireType);
80        }
81      } catch (Exception e) {
82        if (LOG.isErrorEnabled()) {
83          LOG.error("Unexpected error", e);
84        }
85        return 0;
86      }
87    }
88    
89    private int compareLong(Node node0, Node node1) {
90      try {
91        long propertyValue0 = node0.getProperty(propertyName) == null ? -1 : node0.getProperty(propertyName)
92                .getLong();
93        long propertyValue1 = node1.getProperty(propertyName) == null ? -1 : node1.getProperty(propertyName)
94                .getLong();
95        if (ASCENDING_ORDER.equals(orderType)) {
96          if (propertyValue0 < propertyValue1) {
97            return -1;
98          } else if (propertyValue0 == propertyValue1) {
99            return 0;
100         } else {
101           return 1;
102         }
103       } else {
104         if (propertyValue0 < propertyValue1) {
105           return 1;
106         } else if (propertyValue0 == propertyValue1) {
107           return 0;
108         } else {
109           return -1;
110         }
111       }
112     } catch (RepositoryException e) {
113       if (LOG.isErrorEnabled()) {
114         LOG.error("Unexpected error", e);
115       }
116       return 0;
117     }
118   }
119 
120   private int getRequireType(Node node) {
121     try {
122       if (node.hasProperty(propertyName)) {
123         return node.getProperty(propertyName).getDefinition().getRequiredType();
124       }
125      return -1;
126     } catch (RepositoryException e) {
127       if (LOG.isErrorEnabled()) {
128         LOG.error("Unexpected error", e);
129       }
130       return -1;
131     }
132   }
133 
134   private int compareString(Node node0, Node node1) {
135     try {
136       String propertyValue0 = node0.getProperty(propertyName) == null ? ""
137                                                                      : String.valueOf(node0.getProperty(propertyName)
138                                                                                            .getString());
139       String propertyValue1 = node1.getProperty(propertyName) == null ? ""
140                                                                      : String.valueOf(node1.getProperty(propertyName)
141                                                                                            .getString());
142       if(ASCENDING_ORDER.equals(orderType)) {
143         return propertyValue0.compareToIgnoreCase(propertyValue1);
144       }
145       return propertyValue1.compareToIgnoreCase(propertyValue0);
146     } catch(RepositoryException e) {
147       if (LOG.isErrorEnabled()) {
148         LOG.error("Unexpected error", e);
149       }
150       return 0;
151     }
152   }
153 
154   public int compareDate(Node node0, Node node1) {
155     try{
156         Calendar date0 = node0.getProperty(propertyName).getDate();
157         Calendar date1 = node1.getProperty(propertyName).getDate();
158         if(ASCENDING_ORDER.equals(orderType)) {
159           return date0.compareTo(date1) ;
160         }
161         return date1.compareTo(date0) ;
162     } catch (Exception e) {
163       if (LOG.isErrorEnabled()) {
164         LOG.error("Unexpected error", e);
165       }
166     }
167     return 0;
168   }
169 }