ComparablePredicate.java
001 /*
002  *  Constraint Predicate implementation
003  *
004  *  Copyright (c) 1995-2012, 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  @author esword
026  */
027 @SuppressWarnings({"unchecked","rawtypes"})
028 public abstract class ComparablePredicate extends AbstractConstraintPredicate {
029 
030   private static final long serialVersionUID = -5667456294601338967L;
031   
032   protected Comparable comparableValue;
033 
034   /**
035    * Value must be a Comparable
036    */
037   @Override
038   public void setValue(Object value) {
039     if(!(value instanceof Comparable)) {
040       String classString = (value == null"null" : value.getClass()
041               .toString();
042       throw new IllegalArgumentException("Value for attribute '"
043               + getAccessor() "' must be a Comparable type, not a "
044               + classString);
045     }
046     comparableValue = (Comparable)value;
047 
048     super.setValue(value);
049   }
050 
051   @Override
052   public boolean doMatch(Object value, AnnotationSet contextthrows JapeException {
053     if(value == nullreturn false;
054 
055     return doMatch(value);
056   }
057 
058   protected abstract boolean doMatch(Object featureValuethrows JapeException;
059 
060   /**
061    * Use <code>compareTo</code> to compare set value with the given
062    * object, doing basic type conversion to get the two objects to the
063    * same class.
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 }