Coverage Report - org.apache.commons.beanutils.BeanComparator
 
Classes in this File Line Coverage Branch Coverage Complexity
BeanComparator
38%
15/39
12%
2/16
3.222
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 package org.apache.commons.beanutils;
 19  
 
 20  
 import java.lang.reflect.InvocationTargetException;
 21  
 import java.io.Serializable;
 22  
 import java.util.Comparator;
 23  
 import org.apache.commons.collections.comparators.ComparableComparator;
 24  
 
 25  
 /**
 26  
  * <p>
 27  
  * This comparator compares two beans by the specified bean property. 
 28  
  * It is also possible to compare beans based on nested, indexed, 
 29  
  * combined, mapped bean properties. Please see the {@link PropertyUtilsBean} 
 30  
  * documentation for all property name possibilities. 
 31  
  *
 32  
  * </p><p>
 33  
  * <strong>Note:</strong> The BeanComparator passes the values of the specified 
 34  
  * bean property to a ComparableComparator, if no comparator is 
 35  
  * specified in the constructor. If you are comparing two beans based 
 36  
  * on a property that could contain "null" values, a suitable <code>Comparator</code> 
 37  
  * or <code>ComparatorChain</code> should be supplied in the constructor. 
 38  
  * </p>
 39  
  *
 40  
  * @author     <a href"mailto:epugh@upstate.com">Eric Pugh</a>
 41  
  * @author Tim O'Brien 
 42  
  */
 43  
 public class BeanComparator implements Comparator, Serializable {
 44  
 
 45  
     private String property;
 46  
     private Comparator comparator;
 47  
 
 48  
     /** 
 49  
      * <p>Constructs a Bean Comparator without a property set.
 50  
      * </p><p>
 51  
      * <strong>Note</strong> that this is intended to be used 
 52  
      * only in bean-centric environments.
 53  
      * </p><p>
 54  
      * Until {@link #setProperty} is called with a non-null value.
 55  
      * this comparator will compare the Objects only.
 56  
      * </p>
 57  
      */
 58  
     public BeanComparator() {
 59  0
         this( null );
 60  0
     }
 61  
 
 62  
     /**
 63  
      * <p>Constructs a property-based comparator for beans.
 64  
      * This compares two beans by the property 
 65  
      * specified in the property parameter. This constructor creates 
 66  
      * a <code>BeanComparator</code> that uses a <code>ComparableComparator</code>
 67  
      * to compare the property values. 
 68  
      * </p>
 69  
      * 
 70  
      * <p>Passing "null" to this constructor will cause the BeanComparator 
 71  
      * to compare objects based on natural order, that is 
 72  
      * <code>java.lang.Comparable</code>. 
 73  
      * </p>
 74  
      *
 75  
      * @param property String Name of a bean property, which may contain the 
 76  
      * name of a simple, nested, indexed, mapped, or combined 
 77  
      * property. See {@link PropertyUtilsBean} for property query language syntax. 
 78  
      * If the property passed in is null then the actual objects will be compared
 79  
      */
 80  
     public BeanComparator( String property ) {
 81  8
         this( property, ComparableComparator.getInstance() );
 82  8
     }
 83  
 
 84  
     /**
 85  
      * Constructs a property-based comparator for beans.
 86  
      * This constructor creates 
 87  
      * a BeanComparator that uses the supplied Comparator to compare 
 88  
      * the property values. 
 89  
      * 
 90  
      * @param property Name of a bean property, can contain the name 
 91  
      * of a simple, nested, indexed, mapped, or combined 
 92  
      * property. See {@link PropertyUtilsBean} for property query language  
 93  
      * syntax. 
 94  
      * @param comparator BeanComparator will pass the values of the 
 95  
      * specified bean property to this Comparator. 
 96  
      * If your bean property is not a comparable or 
 97  
      * contains null values, a suitable comparator 
 98  
      * may be supplied in this constructor.
 99  
      */
 100  8
     public BeanComparator( String property, Comparator comparator ) {
 101  8
         setProperty( property );
 102  8
         if (comparator != null) {
 103  8
             this.comparator = comparator;
 104  
         } else {
 105  0
             this.comparator = ComparableComparator.getInstance();
 106  
         }
 107  8
     }
 108  
 
 109  
     /**
 110  
      * Sets the method to be called to compare two JavaBeans
 111  
      *
 112  
      * @param property String method name to call to compare 
 113  
      * If the property passed in is null then the actual objects will be compared
 114  
      */
 115  
     public void setProperty( String property ) {
 116  9
         this.property = property;
 117  9
     }
 118  
 
 119  
 
 120  
     /**
 121  
      * Gets the property attribute of the BeanComparator
 122  
      *
 123  
      * @return String method name to call to compare. 
 124  
      * A null value indicates that the actual objects will be compared
 125  
      */
 126  
     public String getProperty() {
 127  0
         return property;
 128  
     }
 129  
 
 130  
 
 131  
     /**
 132  
      * Gets the Comparator being used to compare beans.
 133  
      *
 134  
      * @return the Comparator being used to compare beans 
 135  
      */
 136  
     public Comparator getComparator() {
 137  0
         return comparator;
 138  
     }
 139  
 
 140  
 
 141  
     /**
 142  
      * Compare two JavaBeans by their shared property.
 143  
      * If {@link #getProperty} is null then the actual objects will be compared.
 144  
      *
 145  
      * @param  o1 Object The first bean to get data from to compare against
 146  
      * @param  o2 Object The second bean to get data from to compare
 147  
      * @return int negative or positive based on order
 148  
      */
 149  
     public int compare( Object o1, Object o2 ) {
 150  
         
 151  9
         if ( property == null ) {
 152  
             // compare the actual objects
 153  0
             return comparator.compare( o1, o2 );
 154  
         }
 155  
         
 156  
         try {
 157  9
             Object value1 = PropertyUtils.getProperty( o1, property );
 158  8
             Object value2 = PropertyUtils.getProperty( o2, property );
 159  7
             return comparator.compare( value1, value2 );
 160  
         }
 161  0
         catch ( IllegalAccessException iae ) {
 162  0
             throw new RuntimeException( "IllegalAccessException: " + iae.toString() );
 163  
         } 
 164  0
         catch ( InvocationTargetException ite ) {
 165  0
             throw new RuntimeException( "InvocationTargetException: " + ite.toString() );
 166  
         }
 167  1
         catch ( NoSuchMethodException nsme ) {
 168  1
             throw new RuntimeException( "NoSuchMethodException: " + nsme.toString() );
 169  
         } 
 170  
     }
 171  
     
 172  
     /**
 173  
      * Two <code>BeanComparator</code>'s are equals if and only if
 174  
      * the wrapped comparators and the property names to be compared
 175  
      * are equal.
 176  
      * @param  o Comparator to compare to
 177  
      * @return whether the the comparators are equal or not
 178  
      */
 179  
     public boolean equals(Object o) {
 180  0
         if (this == o) {
 181  0
             return true;
 182  
         }
 183  0
         if (!(o instanceof BeanComparator)) {
 184  0
             return false;
 185  
         }
 186  
 
 187  0
         final BeanComparator beanComparator = (BeanComparator) o;
 188  
 
 189  0
         if (!comparator.equals(beanComparator.comparator)) {
 190  0
             return false;
 191  
         }
 192  0
         if (property != null)
 193  
         {
 194  0
             if (!property.equals(beanComparator.property)) {
 195  0
                 return false;
 196  
             }
 197  
         }
 198  
         else
 199  
         {
 200  0
             return (beanComparator.property == null);
 201  
         }
 202  
 
 203  0
         return true;
 204  
     }
 205  
 
 206  
     /**
 207  
      * Hashcode compatible with equals.
 208  
      * @return the hash code for this comparator
 209  
      */ 
 210  
     public int hashCode() {
 211  
         int result;
 212  0
         result = comparator.hashCode();
 213  0
         return result;
 214  
     }
 215  
 }