EmbeddedConstraintPredicate.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, 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  @author esword
031  */
032 public abstract class EmbeddedConstraintPredicate extends AbstractConstraintPredicate {
033 
034   private static final long serialVersionUID = 7472456256804424432L;
035 
036   protected Constraint valueConstraint;
037   protected String annotType;
038 
039   public EmbeddedConstraintPredicate() {
040     super();
041   }
042 
043   public EmbeddedConstraintPredicate(AnnotationAccessor accessor, Object value) {
044     super(accessor, value);
045   }
046 
047   /**
048    * Sets up environment for concrete class to do the specific matching check
049    */
050   @Override
051   public boolean doMatch(Object annotValue, AnnotationSet context)
052           throws JapeException {
053 
054     Annotation annot = (Annotation)annotValue;
055     AnnotationSet containedSet = doMatch(annot, context);
056 
057     Collection<Annotation> filteredSet = filterMatches(containedSet);
058 
059     return !filteredSet.isEmpty();
060   }
061 
062   protected abstract AnnotationSet doMatch(Annotation annot, AnnotationSet as);
063 
064   /**
065    * If there are attribute constraints, filter the set.
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 
107   public String getAnnotType() {
108     return annotType;
109   }
110 
111   @Override
112   public String toString() {
113     StringBuilder str = new StringBuilder();
114     str.append(getOperator()).append(" ");
115     if(annotType != null)  str.append(annotType);
116     if(valueConstraint != null){
117       str.append(": ").append(valueConstraint);
118     }
119     return str.toString();
120   }
121   
122   @Override
123   public int hashCode() {
124     final int prime = 31;
125     int result = super.hashCode();
126     result = prime * result + ((annotType == null: annotType.hashCode());
127     result =
128         prime * result
129             ((valueConstraint == null: valueConstraint.hashCode());
130     return result;
131   }
132 
133   @Override
134   public boolean equals(Object obj) {
135     if(this == objreturn true;
136     if(!super.equals(obj)) return false;
137     if(!(obj instanceof EmbeddedConstraintPredicate)) return false;
138     EmbeddedConstraintPredicate other = (EmbeddedConstraintPredicate)obj;
139     if(annotType == null) {
140       if(other.annotType != nullreturn false;
141     else if(!annotType.equals(other.annotType)) return false;
142     if(valueConstraint == null) {
143       if(other.valueConstraint != nullreturn false;
144     else if(!valueConstraint.equals(other.valueConstraint)) return false;
145     return true;
146   }
147 }