PatternValidator.java
001 /*
002  *  PatternValidator.java
003  *
004  *  Niraj Aswani, 19/March/07
005  *
006  *  $Id: PatternValidator.html,v 1.0 2007/03/19 16:22:01 niraj Exp $
007  */
008 package gate.creole.annic.lucene;
009 
010 import java.util.*;
011 import gate.creole.annic.apache.lucene.index.*;
012 import gate.creole.annic.apache.lucene.analysis.*;
013 
014 /**
015  * Pattern Validator that given a position of first term, retrieves the
016  * entire pattern from the token stream. If it is not able to retrieve
017  * the entire pattern, the class reports it as an invalid pattern.
018  
019  @author niraj
020  
021  */
022 public class PatternValidator {
023 
024   private int patLen = 0;
025 
026   /**
027    * Gets the length of the pattern.
028    */
029   public int getPatternLength() {
030     return patLen;
031   }
032 
033   /**
034    * This method takes two parameters the actual query issued and
035    * annotations in which it checks if the annotations exist that are
036    * validating for the given query
037    
038    @return int positive number indicates the offset of the last
039    *         annotation of the pattern. -1 indicates invalid pattern.
040    */
041   public int validate(List<String> queryTokens, List<Token> annotations, int from,
042           QueryParser queryParserthrows gate.creole.ir.SearchException {
043     patLen = 0;
044 
045     // and now for each token we need to create Term(s)
046     int enOffset = -1;
047     int stOffset = -1;
048     int position = -1;
049 
050     for(int i = 0; i < queryTokens.size(); i++) {
051       queryParser.position = 0;
052       List<?>[] termpositions = queryParser.createTerms(queryTokens.get(i));
053       
054       @SuppressWarnings("unchecked")
055       List<Term> terms = (List<Term>)termpositions[0];
056       
057       @SuppressWarnings("unchecked")
058       List<Boolean> consider = (List<Boolean>)termpositions[2];
059       
060       // process each term individually
061       for(int k = 0; k < terms.size(); k++) {
062         // when consider is true, that means we should change the start
063         // offset conditions
064         Term term = terms.get(k);
065         if(consider.get(k).booleanValue()) {
066           patLen++;
067           // find relavant annotations where type and text should
068           // match with terms type and text
069           boolean found = false;
070           // among this if we are able to find the token that has
071           // start offset > previous enOffset
072           innerLoop: for(int j = from; j < annotations.size(); j++) {
073             Token tk = annotations.get(j);
074             // if the term is equal to one of the tokens
075             if(!isEqual(tk, term)) continue;
076             // the next token with consider must be starting with
077             // the end of last token
078             // or after 1 space
079             if(enOffset == -|| tk.startOffset() == enOffset
080                     || tk.startOffset() == enOffset + 1) {
081               // the position of the new token must be +1
082               if(tk.getPosition() > position) {
083                 found = true;
084                 // set the current position to the position of
085                 // the found token
086                 position = tk.getPosition();
087                 enOffset = tk.endOffset();
088                 stOffset = tk.startOffset();
089                 // as the annotation is found
090                 // break the innerLoop
091                 // and search for the next term
092                 break innerLoop;
093               }
094             }
095           }
096 
097           if(!found) {
098             // we could not find any annotation that means this
099             // pattern is not valid
100             return -1;
101           }
102 
103         }
104         else {
105           // if consider is false
106           boolean found = false;
107           for(int j = 0; j < annotations.size(); j++) {
108             Token tk = annotations.get(j);
109             if(tk.getPosition() != positioncontinue;
110             if(tk.endOffset() != enOffset || tk.startOffset() != stOffset)
111               continue;
112             if(!isEqual(tk, term))
113               continue;
114             else {
115               found = true;
116               break;
117             }
118           }
119           if(!found) {
120             return -1;
121           }
122         }
123       }
124     }
125     return enOffset;
126   }
127 
128   /**
129    * Checks whether two terms are equal.
130    */
131   private boolean isEqual(Token tk, Term term) {
132     return (term.text().equals(tk.termText()) && term.type().equals(tk.type()));
133   }
134 }