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(v 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 }
|