/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.gui.legacy.taglib.display; import java.lang.reflect.InvocationTargetException; import java.util.Comparator; import org.apache.commons.beanutils.PropertyUtils; /** * This utility class is used to sort the list that the table is viewing based on arbitrary properties of objects * contained in that list. The only assumption made is that the object returned by the property is either a native type, * or implements the Comparable interface. If the property does not implement Comparable, then this little sorter object * will just assume that all objects are the same, and quietly do nothing (so you should check for Comparable * objecttypes elsewhere as this object won't complain). */ class BeanSorter extends Object implements Comparator { private String property; private Decorator dec; /** * BeanSorter is a decorator of sorts, you need to initialize it with the property name of the object that is to be * sorted (getXXX method name). This property should return a Comparable object. */ protected BeanSorter(String property, Decorator dec) { this.property = property; this.dec = dec; } /** * Compares two objects by first fetching a property from each object and then comparing that value. If there are * any errors produced while trying to compare these objects then a RunTimeException will be thrown as any error * found here will most likely be a programming error that needs to be quickly addressed (like trying to compare * objects that are not comparable, or trying to read a property from a bean that is invalid, etc...) * * @throws RuntimeException if there are any problems making a comparison of the object properties. */ public int compare(Object o1, Object o2) throws RuntimeException { if (property == null) { throw new NullPointerException("Null property provided which " + "prevents BeanSorter sort"); } try { Object p1 = null; Object p2 = null; // If they have supplied a decorator, then make sure and use it for // the sorting as well... TODO - Major hack.... if (this.dec != null) { try { dec.initRow(o1, -1, -1); p1 = PropertyUtils.getProperty(dec, property); dec.initRow(o2, -1, -1); p2 = PropertyUtils.getProperty(dec, property); } catch (Exception e) { // If there were any problems, then assume that the decorator // does not implement that method, and instead fall down to // the original object... p1 = PropertyUtils.getProperty(o1, property); p2 = PropertyUtils.getProperty(o2, property); } } else { p1 = PropertyUtils.getProperty(o1, property); p2 = PropertyUtils.getProperty(o2, property); } if ((p1 instanceof Comparable) && (p2 instanceof Comparable)) { Comparable c1 = (Comparable) p1; Comparable c2 = (Comparable) p2; return c1.compareTo(c2); } else { throw new RuntimeException("Object returned by property \"" + property + "\" is not a Comparable object"); } } catch (IllegalAccessException e) { throw new RuntimeException("IllegalAccessException thrown while " + "trying to fetch property \"" + property + "\" during sort"); } catch (InvocationTargetException e) { throw new RuntimeException("InvocationTargetException thrown while " + "trying to fetch property \"" + property + "\" during sort"); } catch (NoSuchMethodException e) { throw new RuntimeException("NoSuchMethodException thrown while " + "trying to fetch property \"" + property + "\" during sort"); } } /** * Is this Comparator the same as another one... */ public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof BeanSorter) { if (this.property != null) { return this.property.equals(((BeanSorter) obj).property); } else { return false; } } else { return false; } } }