AbstractRegExpPredicate.java
01 /*
02  *  Constraint Predicate implementation
03  *
04  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
05  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
06  *
07  *  This file is part of GATE (see http://gate.ac.uk/), and is free
08  *  software, licenced under the GNU Library General Public License,
09  *  Version 2, June 1991 (in the distribution as file licence.html,
10  *  and also available at http://gate.ac.uk/gate/licence.html).
11  *
12  *  Eric Sword, 03/09/08
13  *
14  *  $Id$
15  */
16 package gate.jape.constraint;
17 
18 import gate.AnnotationSet;
19 import gate.jape.JapeException;
20 
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import java.util.regex.PatternSyntaxException;
24 
25 /**
26  * Abstract regular expression based predicate implementation. This
27  * class handles parsing of the regexp into a {@link Pattern} object,
28  * and at match time it creates a {@link Matcher} for the annotation
29  * value. Concrete subclasses define the different criteria for what
30  * counts as a "match" in terms of {@link Matcher#find()} and
31  {@link Matcher#matches()}.
32  */
33 public abstract class AbstractRegExpPredicate
34                                              extends
35                                                AbstractConstraintPredicate {
36 
37   @Override
38   public String toString() {
39     String val = ((Pattern)getValue()).pattern();
40     return getAccessor() + getOperator() "\"" + val + "\"";
41   }
42 
43   @Override
44   public void setValue(Object value) {
45     if(value == nullvalue = "";
46     try {
47       super.setValue(Pattern.compile(value.toString()));
48     }
49     catch(PatternSyntaxException pse) {
50       throw new IllegalArgumentException("Cannot compile pattern '" + value
51               "'");
52     }
53   }
54 
55   /**
56    * Returns true if the given value matches the set pattern. If the
57    * value is null it is treated as an empty string. The actual matching
58    * logic is defined by {@link #matcherResult}.
59    */
60   public boolean doMatch(Object annotValue, AnnotationSet context)
61           throws JapeException {
62 
63     if(annotValue == nullannotValue = "";
64 
65     if(annotValue instanceof String) {
66       String annotValueString = (String)annotValue;
67       Pattern constraintPattern = (Pattern)getValue();
68       return matcherResult(constraintPattern.matcher(annotValueString));
69     }
70     else {
71       throw new JapeException("Cannot do pattern matching on attribute '"
72               + getAccessor() "'.  Are you sure the value is a string?");
73     }
74   }
75 
76   /**
77    * Must be implemented by subclasses to define the matching logic,
78    * typically one of {@link Matcher#find()} and
79    {@link Matcher#matches()}, possibly negated.
80    
81    @param m a {@link Matcher} for the annotation value string,
82    *          obtained from the constraint pattern.
83    @return true if this constraint should be considered to match,
84    *         false otherwise.
85    */
86   protected abstract boolean matcherResult(Matcher m);
87 }