/*************************************************************************** * Copyright (C) 2003-2009 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see<http://www.gnu.org/licenses/>. * **************************************************************************/ package org.exoplatform.ecm.utils.comparator; import java.util.Calendar; import java.util.Comparator; import javax.jcr.Node; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; /** * Created by The eXo Platform SARL * Author : Hoang Van Hung * hunghvit@gmail.com * May 14, 2009 */ public class PropertyValueComparator implements Comparator<Node> { public static final String ASCENDING_ORDER = "Ascending"; public static final String DESCENDING_ORDER = "Descending"; private String propertyName; private String orderType; private static final Log LOG = ExoLogger.getLogger(PropertyValueComparator.class.getName()); public PropertyValueComparator(String propertyName, String orderType) { this.propertyName = propertyName; this.orderType = orderType; } public int compare(Node node0, Node node1) { int flipFlop = ASCENDING_ORDER.equals(orderType) ? 1 : -1; int requireType = getRequireType(node0); int requireType2 = getRequireType(node1); if (requireType == -1 && requireType2 == -1) return 0; if (requireType == -1 && requireType2 != -1) return -1 * flipFlop; if (requireType != -1 && requireType2 == -1) return 1 * flipFlop; try { switch (requireType) { case PropertyType.BINARY: return compareString(node0, node1); case PropertyType.BOOLEAN: return compareString(node0, node1); case PropertyType.NAME: return compareString(node0, node1); case PropertyType.PATH: return compareString(node0, node1); case PropertyType.STRING: return compareString(node0, node1); case PropertyType.LONG: return compareLong(node0, node1); case PropertyType.DOUBLE: return compareLong(node0, node1); case PropertyType.DATE: return compareDate(node0, node1); case PropertyType.REFERENCE: return compareString(node0, node1); default: throw new RepositoryException("Unknown type " + requireType); } } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("Unexpected error", e); } return 0; } } private int compareLong(Node node0, Node node1) { try { long propertyValue0 = node0.getProperty(propertyName) == null ? -1 : node0.getProperty(propertyName) .getLong(); long propertyValue1 = node1.getProperty(propertyName) == null ? -1 : node1.getProperty(propertyName) .getLong(); if (ASCENDING_ORDER.equals(orderType)) { if (propertyValue0 < propertyValue1) { return -1; } else if (propertyValue0 == propertyValue1) { return 0; } else { return 1; } } else { if (propertyValue0 < propertyValue1) { return 1; } else if (propertyValue0 == propertyValue1) { return 0; } else { return -1; } } } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error("Unexpected error", e); } return 0; } } private int getRequireType(Node node) { try { if (node.hasProperty(propertyName)) { return node.getProperty(propertyName).getDefinition().getRequiredType(); } return -1; } catch (RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error("Unexpected error", e); } return -1; } } private int compareString(Node node0, Node node1) { try { String propertyValue0 = node0.getProperty(propertyName) == null ? "" : String.valueOf(node0.getProperty(propertyName) .getString()); String propertyValue1 = node1.getProperty(propertyName) == null ? "" : String.valueOf(node1.getProperty(propertyName) .getString()); if(ASCENDING_ORDER.equals(orderType)) { return propertyValue0.compareToIgnoreCase(propertyValue1); } return propertyValue1.compareToIgnoreCase(propertyValue0); } catch(RepositoryException e) { if (LOG.isErrorEnabled()) { LOG.error("Unexpected error", e); } return 0; } } public int compareDate(Node node0, Node node1) { try{ Calendar date0 = node0.getProperty(propertyName).getDate(); Calendar date1 = node1.getProperty(propertyName).getDate(); if(ASCENDING_ORDER.equals(orderType)) { return date0.compareTo(date1) ; } return date1.compareTo(date0) ; } catch (Exception e) { if (LOG.isErrorEnabled()) { LOG.error("Unexpected error", e); } } return 0; } }