package com.philmcrew.utility;
import java.util.Comparator;
/**
* Instances of this class can compare two objects with and without an Operator
*
* @author Mitchell J. Friedman
*/
public class ComparatorHelper implements Comparator
{
/**
* Returns whether the two given objects are equivalent.
*
* @param o1 one of the objects to compare
* @param o2 the other object to compare
* @return true if and only if compare(o1, o2) returns 0
* @see #compare(Object, Object)
*/
public boolean equals( Object o1, Object o2 )
{
return 0 == compare( o1, o2 );
}
/**
* Attempts to compare the two given Objects based on the given kind of
* comparison. Returns a negative integer, zero, or a positive integer
* as the first Object is considered to be less than, equal to, or greater
* than the second Object.
*
* @param o1 the first Object to compare.
* @param o2 the second Object to compare.
* @return the integer result of the comparison.
*/
public int compare( Object o1, Object o2 )
{
int comparison;
if( null == o1 )
{
if( null == o2 )
comparison = 0;
else
comparison = -1;
}
else if( null == o2 )
{
comparison = 1;
}
else
{
if( !(o1 instanceof Comparable) )
{
if( !(o2 instanceof Comparable) )
{
if( o1 instanceof Boolean && o2 instanceof Boolean ) {
comparison = compareBoolean( (Boolean) o1, (Boolean) o2 );
}
else
{
comparison = 0;
}
}
else
comparison = -1;
}
else if( !(o2 instanceof Comparable) )
comparison = 1;
else
comparison = compareTo( (Comparable) o1, (Comparable) o2 );
}
return comparison;
}
/**
* Compares the two given Objects based on the given operator. For
* example, if the operator is less-than it returns true when the
* first Object is less than the second Object. A parameter that is
* null is considered to be less than any parameter that is
* not null.
*
* @param o1 the first Object to compare.
* @param operator the kind of comparison to make
* @param o2 the second Object to compare.
* @return the result of comparing the given Objects using the given operator.
* @see #compare(Object, Object)
*/
public boolean compare( Object o1, Operator operator, Object o2 )
{
int comparison = compare( o1, o2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given Strings. Returns a negative integer, zero, or a
* positive integer as the first String is less than, equal to, or greater
* than the second String.
*
* @param s1
* @param s2
* @return the integer result of the comparison.
* @see java.lang.String#compareTo(java.lang.String)
*/
public int compareStrings( String s1, String s2 )
{
int comparison;
if( s1 == null || s2 == null ) {
comparison = compareTo( (Comparable) s1, (Comparable) s2 );
}
else
comparison = s1.compareTo( s2 );
return comparison;
}
/**
* Compares the two given Strings based on the given operator. For
* example, if the operator is less-than it returns true when the
* first String is less than the second String.
*
* @param s1 the first String to compare.
* @param operator the kind of comparison to make
* @param s2 the second String to compare.
* @return the result of comparing the given Strings using the given operator.
*/
public boolean compareStrings( String s1, Operator operator, String s2 )
{
int comparison = compareStrings( s1, s2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given longs based on the given kind of comparison.
* Returns true if the first long compares with the second long in the
* manner indicated by the given kind of comparison. For example, if
* the operator is less-than and the two numbers are 5 and 8 the result
* is true, but if the numbers are 8 and 5 the result is false.
*
* @param x1 the first long
* @param operator the type of comparison to make
* @param x2 the second long
* @return the boolean result of the comparison.
*/
public boolean compareTo( long x1, Operator operator, long x2 )
{
int comparison = compareTo( x1, x2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given longs. Returns a negative integer, zero, or a
* positive integer as the first long is less than, equal to, or greater
* than the second long.
*
* @param x1 the first long to compare
* @param x2 the second long to compare
* @return a negative integer, zero, or a positive integer as the first
* long is less than, equal to, or greater than the second long.
*/
public int compareTo( long x1, long x2 )
{
int comparison;
if( x1 < x2 )
comparison = -1;
else if( x1 > x2 )
comparison = 1;
else
comparison = 0;
return comparison;
}
/**
* Compares the two given doubles based on the given kind of comparison.
* Returns true if the first double compares with the second double in the
* manner indicated by the given kind of comparison. For example, if
* the operator is less-than and the two numbers are 5.0 and 8.0 the result
* is true, but if the numbers are 8.0 and 5.0 the result is false.
*
* @param x1 the first double
* @param operator the type of comparison to make
* @param x2 the second double
* @return the boolean result of the comparison.
*/
public boolean compareTo( double x1, Operator operator, double x2 )
{
int comparison = compareTo( x1, x2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given doubles. Returns a negative integer, zero, or a
* positive integer as the first double is less than, equal to, or greater
* than the second double.
*
* @param x1 the first double to compare
* @param x2 the second double to compare
* @return a negative integer, zero, or a positive integer as the first
* double is less than, equal to, or greater than the second double.
*/
public int compareTo( double x1, double x2 )
{
int comparison;
if( x1 < x2 )
comparison = -1;
else if( x1 > x2 )
comparison = 1;
else
comparison = 0;
return comparison;
}
/**
* Compares the two given objects for ordering. Returns a negative
* integer, zero, or a positive integer as the first object is less
* than, equal to, or greater than the second object.
*
* @param c1 the first of the objects to compare
* @param c2 the second of the objects to compare
* @return a negative integer, zero, or a positive integer as the first
* object is less than, equal to, or greater than the second object.
*/
public int compareTo( Comparable c1, Comparable c2 )
{
int comparison;
if( null == c1 )
{
if( null == c2 )
comparison = 0;
else
comparison = -1;
}
else if( null == c2 )
{
comparison = 1;
}
else
{
if( c1.getClass() == c2.getClass() )
{
// same class - just do the comparison
comparison = c1.compareTo( c2 );
}
else if( c1 instanceof Number && c2 instanceof Number )
{
// different classes but they are both numbers
comparison = compareNumbers( (Number) c1, (Number) c2 );
}
else if( c1 instanceof String && c2 instanceof String )
{
// one is a string and the other is a null
comparison = compareStrings( (String) c1, (String) c2 );
}
else if( c1 instanceof String && c2 instanceof Number )
{
comparison = compareNumbers( convertToDouble( (String) c1 ), (Number) c2 );
}
else if( c1 instanceof Number && c2 instanceof String ) {
comparison = compareNumbers( (Number) c1, convertToDouble( (String) c2 ) );
}
else
// two not comparables should karmically be the same in some universe
comparison = 0;
}
return comparison;
}
/**
* Converts the given String to a Double. Returns null if there
* is an error converting to a double.
*
* @param s1 the String to convert.
* @return a Double or null.
*/
public Double convertToDouble( String s1 )
{
Double ret = null;
try
{
ret = new Double( s1 );
}
catch( NumberFormatException e )
{
}
return ret;
}
/**
* Compares the two given Numbers. Returns a negative integer, zero, or a
* positive integer as the first Number is less than, equal to, or greater
* than the second Number.
*
* @param x1 the first Number to compare
* @param x2 the second Number to compare
* @return the integer result of the comparison.
*/
public int compareNumbers( Number x1, Number x2 )
{
int comparison;
if( null == x1 || null == x2 )
comparison = compareTo( (Comparable) x1, (Comparable) x2 );
else if( x1.getClass() == x2.getClass() )
{
Comparable comparable = (Comparable) x1;
comparison = comparable.compareTo( x2 );
}
else
{
long long1a = x1.longValue();
long long2a = x2.longValue();
comparison = compareTo( long1a, long2a );
if( 0 == comparison )
{
double double1a = x1.doubleValue();
double double2a = x2.doubleValue();
comparison = compareTo( double1a, double2a );
}
}
return comparison;
}
/**
* Compares the two given Booleans. Returns a negative integer, zero, or a
* positive integer as the first Boolean is considered less than, equal to,
* or greater than the second Boolean. For this operation null is
* considered to be less than any Boolean and true is considered
* to be less than false.
*
* @param b1 the first Boolean value.
* @param b2 the second Boolean value.
* @return the integer result of the comparison.
*/
public int compareBoolean( Boolean b1, Boolean b2 )
{
int comparison;
if( null == b1 )
{
if( null == b2 )
{
comparison = 0;
}
else
{
comparison = -1;
}
}
else if( null == b2 )
{
comparison = 1;
}
else if( b1.equals( b2 ) )
{
comparison = 0;
}
else if( b1.booleanValue() == false )
{
comparison = 1;
}
else
{
comparison = -1;
}
return comparison;
}
/**
* Compares the two given Booleans based on the given operator. For
* example, if the operator is less-than it returns true when the
* first Boolean is less than the second Boolean.
*
* @param b1 the first Boolean to compare.
* @param operator the kind of comparison to make
* @param b2 the second Boolean to compare.
* @return the result of comparing the given Booleans using the given operator.
* @see #compareBoolean(Boolean, Boolean)
*/
public boolean compareBoolean( Boolean b1, Operator operator, Boolean b2 )
{
int comparison = compareBoolean( b1, b2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given Comparables based on the given operator. For
* example, if the operator is less-than it returns true when the first
* Comparable is less than the second Comparable.
*
* @param c1 the first Comparable to compare.
* @param operator the kind of comparison to make
* @param c2 the second Comparable to compare.
* @return the result of comparing the given Comparables using the given operator.
*/
public boolean compareTo( Comparable c1, Operator operator, Comparable c2 )
{
int comparison = compareTo( c1, c2 );
return compareResults( operator, comparison );
}
/**
* Compares the two given Numbers based on the given operator. For
* example, if the operator is less-than it returns true when the
* first Number is less than the second Number.
*
* @param x1 the first Number to compare.
* @param operator the kind of comparison to make
* @param x2 the second Number to compare.
* @return the result of comparing the given Numbers using the given operator.
*/
public boolean compareNumbers( Number x1, Operator operator, Number x2 )
{
int comparison = compareNumbers( x1, x2 );
return compareResults( operator, comparison );
}
/**
* Checks whether the given result of a comparison matches the given
* operator. For example, returns true if the operator is less-than
* when the comparison is a negative number, but returns true if the
* operator is equal-to only when the comparison is zero. The compareTo
* functions should be used to obtain the integer to pass as the
* comparison. (@see #compareTo(Comparable, Comparable))
*
* @param operator the type of comparison
* @param comparison the result of comparing two things
* @return whether the comparison fits the given operator
*/
protected boolean compareResults( Operator operator, int comparison )
{
boolean ret = false;
if( null == operator ) {
// if no operator than true enough
return true;
}
int op = operator.getOp();
switch( op )
{
case Operator.LESS_THAN_INT:
if( comparison < 0 )
ret = true;
break;
case Operator.LESS_THAN_OR_EQUAL_TO_INT:
if( comparison <= 0 )
ret = true;
break;
case Operator.EQUAL_TO_INT:
if( comparison == 0 )
ret = true;
break;
case Operator.GREATER_THAN_OR_EQUAL_TO_INT:
if( comparison >= 0 )
ret = true;
break;
case Operator.GREATER_THAN_INT:
if( comparison > 0 )
ret = true;
break;
case Operator.NOT_EQUAL_TO_INT:
if( comparison != 0 )
ret = true;
default:
break;
}
return ret;
}
}