ComparablePredicate.java
001 /*
002  *  Constraint Predicate implementation
003  *
004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Eric Sword, 03/09/08
013  *
014  *  $Id$
015  */
016 package gate.jape.constraint;
017 
018 import gate.AnnotationSet;
019 import gate.jape.JapeException;
020 
021 /**
022  * Base class for those predicates which use <code>compareTo</code> to
023  * compare values.
024  *
025  @version $Revision$
026  @author esword
027  */
028 @SuppressWarnings("unchecked")
029 public abstract class ComparablePredicate extends AbstractConstraintPredicate {
030   protected Comparable comparableValue;
031 
032   /**
033    * Value must be a Comparable
034    */
035   @Override
036   public void setValue(Object value) {
037     if(!(value instanceof Comparable)) {
038       String classString = (value == null"null" : value.getClass()
039               .toString();
040       throw new IllegalArgumentException("Value for attribute '"
041               + getAccessor() "' must be a Comparable type, not a "
042               + classString);
043     }
044     comparableValue = (Comparable)value;
045 
046     super.setValue(value);
047   }
048 
049   public boolean doMatch(Object value, AnnotationSet contextthrows JapeException {
050     if(value == nullreturn false;
051 
052     return doMatch(value);
053   }
054 
055   protected abstract boolean doMatch(Object featureValuethrows JapeException;
056 
057   /**
058    * Use <code>compareTo</code> to compare set value with the given
059    * object, doing basic type conversion to get the two objects to the
060    * same class.
061    *
062    @param obj
063    @return
064    @throws JapeException if the provided object is not a Comparable or
065    *           the classes cannot be compared.
066    */
067   protected int compareValue(Object objthrows JapeException {
068 
069     if(!(obj instanceof Comparable)) {
070       String classString = (obj == null"null" : obj.getClass().toString();
071       throw new JapeException("Value passed to compare to attribute '"
072               + getAccessor() "' must be a Comparable type, not a "
073               + classString);
074     }
075     Comparable passedValue = (Comparable)obj;
076 
077     try {
078       return comparableValue.compareTo(passedValue);
079     }
080     catch(ClassCastException notSameType) {
081       try {
082         // try to compare as Longs
083         if(comparableValue instanceof Long) {
084           return comparableValue.compareTo(Long.valueOf(passedValue.toString()));
085         }
086 
087         // try to compare as Double
088         if(comparableValue instanceof Double) {
089           return comparableValue.compareTo(Double.valueOf(passedValue.toString()));
090         }
091 
092         // can't compare
093         throw new JapeException("Cannot compare values for attribute '"
094                 + getAccessor() "' because cannot compare '"
095                 + comparableValue + "' to '" + passedValue + "'.");
096       // try
097       catch(NumberFormatException nfe) {
098         // stored value is a Long/Double, but annot is not: cannot
099         // compare
100         throw new JapeException("Cannot compare values for attribute '"
101                 + getAccessor() "' because cannot compare '"
102                 + comparableValue + "' to '" + passedValue + "'.");
103       }
104 
105     // catch notSameType
106 
107   }
108 
109 }