EmbeddedConstraintPredicate.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, 09/03/08
013  *
014  *  $Id$
015  */
016 package gate.jape.constraint;
017 
018 import java.util.Collection;
019 import java.util.Collections;
020 
021 import gate.Annotation;
022 import gate.AnnotationSet;
023 import gate.jape.Constraint;
024 import gate.jape.JapeException;
025 
026 /**
027  * Predicate whose {@link #getValue()} property may be set to a
028  * Constraint itself, allowing for recursive evaluations.
029  *
030  @version $Revision$
031  @author esword
032  */
033 public abstract class EmbeddedConstraintPredicate extends AbstractConstraintPredicate {
034 
035   protected Constraint valueConstraint;
036   protected String annotType;
037 
038   public EmbeddedConstraintPredicate() {
039     super();
040   }
041 
042   public EmbeddedConstraintPredicate(AnnotationAccessor accessor, Object value) {
043     super(accessor, value);
044   }
045 
046   /**
047    * Sets up environment for concreate class to do the specific matching check
048    */
049   public boolean doMatch(Object annotValue, AnnotationSet context)
050           throws JapeException {
051 
052     Annotation annot = (Annotation)annotValue;
053     AnnotationSet containedSet = doMatch(annot, context);
054 
055     Collection<Annotation> filteredSet = filterMatches(containedSet);
056 
057     return !filteredSet.isEmpty();
058   }
059 
060   protected abstract AnnotationSet doMatch(Annotation annot, AnnotationSet as);
061 
062   /**
063    * If there are attribute constraints, filter the set.
064    @param containedSet
065    @return
066    */
067   protected Collection<Annotation> filterMatches(AnnotationSet containedSet) {
068     if (containedSet == null)
069       return Collections.emptySet();
070 
071     if (valueConstraint == null || containedSet.isEmpty()) {
072       return containedSet;
073     }
074     else {
075       return valueConstraint.matches(containedSet, null, containedSet);
076     }
077   }
078 
079   /**
080    * If the given value is a {@link Constraint}, then check if there
081    * are any additional attribute/feature-checks on the constraint. If
082    * so, then store the constraint for use during matching calls. If
083    * not, then only the annotation type for the constraint is stored
084    * since the full constraint is not needed.
085    */
086   @Override
087   public void setValue(Object v) {
088     if(instanceof Constraint) {
089       Constraint c = (Constraint)v;
090       annotType = c.getAnnotType();
091       if(!c.getAttributeSeq().isEmpty()) {
092         // store full constraint for later use. It's stored in the
093         // main value object for toString purposes.
094         valueConstraint = c;
095         value = c;
096       }
097     }
098 
099     // if the given value is not a constraint, then just store it
100     // directly as the annotationType
101     if(annotType == null && valueConstraint == null) {
102       value = v;
103       annotType = String.valueOf(v);
104     }
105   }
106 }