001 package railo.runtime.search.lucene2.query; 002 003 import java.io.IOException; 004 import java.io.StringReader; 005 import java.util.Map; 006 import java.util.Vector; 007 import java.util.WeakHashMap; 008 009 import org.apache.lucene.analysis.Analyzer; 010 import org.apache.lucene.analysis.TokenStream; 011 import org.apache.lucene.index.Term; 012 import org.apache.lucene.search.BooleanQuery; 013 import org.apache.lucene.search.FuzzyQuery; 014 import org.apache.lucene.search.PhraseQuery; 015 import org.apache.lucene.search.PrefixQuery; 016 import org.apache.lucene.search.Query; 017 import org.apache.lucene.search.TermQuery; 018 import org.apache.lucene.search.WildcardQuery; 019 020 import railo.commons.lang.ParserString; 021 022 /** 023 * @deprecated no longer in use 024 * The simple query is the default query type and is appropriate for the vast majority of searches. 025 * When entering text on a search form, you perform a simple query by entering a word or comma-delimited strings, 026 * with optional wildcard characters. 027 * Verity treats each comma as a logical OR. If you omit the commas, Verity treats the expression as a phrase. 028 */ 029 public final class Simple { 030 private String OR="or"; 031 private String AND="and"; 032 private String NOT="not"; 033 private char QUOTER='"'; 034 private String FIELD="contents"; 035 036 private static final short TYPE_TERMAL=0; 037 private static final short TYPE_WILDCARD=1; 038 private static final short TYPE_PREFIX=2; 039 private static final short TYPE_FUZZY=3; 040 private static final short TYPE_PHRASE=4; 041 042 private Analyzer analyzer; 043 044 private Map results=new WeakHashMap(); 045 046 /** 047 * constructor of the class 048 * @param analyzer 049 */ 050 public Simple(Analyzer analyzer) { 051 this.analyzer=analyzer; 052 053 } 054 /** 055 * parse given string query 056 * @param criteria 057 * @return matching Query 058 */ 059 public Query parse(String criteria) { 060 Query qry=(Query) results.get(criteria); 061 if(qry!=null) return qry; 062 063 // remove operators at start 064 if(criteria.length()>0) { 065 char first=criteria.charAt(0); 066 // start with operator 067 while(first=='*' || first=='~' || first=='?') { 068 criteria=criteria.substring(1); 069 if(criteria.length()==0) break; 070 first=criteria.charAt(0); 071 } 072 } 073 074 // make never foud query if quey is empty 075 if(criteria.length()==0) { 076 BooleanQuery bool = new BooleanQuery(); 077 bool.add(new TermQuery(new Term(FIELD, "dshnuiaslfspfhsadhfisd")), OccurUtil.toOccur(false, true)); 078 results.put(criteria,bool); 079 return bool; 080 } 081 082 ParserString ps=new ParserString(criteria); 083 qry= orOp(ps); 084 results.put(criteria,qry); 085 return qry; 086 } 087 088 089 090 private Query orOp(ParserString ps) { 091 Query query=andOp(ps); 092 ps.removeSpace(); 093 094 // OR 095 while(ps.isValidIndex() && ps.forwardIfCurrent(OR) || ps.forwardIfCurrent(',')) { 096 ps.removeSpace(); 097 BooleanQuery bool = new BooleanQuery(); 098 099 bool.add(query, OccurUtil.toOccur(false, false)); 100 //bool.add(query, false, false); 101 bool.add(andOp(ps), OccurUtil.toOccur(false, false)); 102 query = bool; 103 } 104 return query; 105 } 106 107 private Query andOp(ParserString ps) { 108 Query query = notOp(ps); 109 ps.removeSpace(); 110 111 // AND 112 while(ps.isValidIndex() && ps.forwardIfCurrent(AND)) { 113 ps.removeSpace(); 114 BooleanQuery bool = new BooleanQuery(); 115 bool.add(query, OccurUtil.toOccur(true, false)); 116 bool.add(notOp(ps), OccurUtil.toOccur(true, false)); 117 query = bool; 118 } 119 return query; 120 } 121 private Query notOp(ParserString ps) { 122 // NOT 123 if(ps.isValidIndex() && ps.forwardIfCurrent(NOT)) { 124 ps.removeSpace(); 125 BooleanQuery bool = new BooleanQuery(); 126 bool.add(clip(ps), OccurUtil.toOccur(false, true)); 127 return bool; 128 } 129 return clip(ps); 130 } 131 132 private Query clip(ParserString ps) { 133 // () 134 if(ps.isValidIndex() && ps.forwardIfCurrent('(')) { 135 Query query=orOp(ps); 136 ps.removeSpace(); 137 ps.forwardIfCurrent(')'); 138 ps.removeSpace(); 139 return query; 140 } 141 return literal(ps); 142 } 143 144 private Query literal(ParserString ps) { 145 _Term term=term(ps); 146 ps.removeSpace(); 147 while(ps.isValidIndex() && !ps.isCurrent(',') && !ps.isCurrent(OR) && !ps.isCurrent(AND) && !ps.isCurrent(')')) { 148 term.append(term(ps)); 149 ps.removeSpace(); 150 } 151 return term.toQuery(); 152 } 153 154 private _Term term(ParserString ps) { 155 short type=TYPE_TERMAL; 156 ps.removeSpace(); 157 StringBuffer sb=new StringBuffer(); 158 boolean inside=false; 159 char c=0; 160 while(ps.isValidIndex() && ((c=ps.getCurrentLower())!=' ' && c!=',' && c!=')' || inside)) { 161 ps.next(); 162 if(c==QUOTER) { 163 inside=!inside; 164 type=TYPE_PHRASE; 165 continue; 166 } 167 sb.append(c); 168 if(!inside) { 169 if(type==TYPE_PREFIX)type=TYPE_WILDCARD; 170 if(type==TYPE_TERMAL && c=='*')type=TYPE_PREFIX; 171 if(c=='?')type=TYPE_WILDCARD; 172 if(type==TYPE_TERMAL && c=='~') { 173 type=TYPE_FUZZY; 174 break; 175 } 176 } 177 } 178 return new _Term(type,sb.toString()); 179 180 } 181 182 class _Term { 183 private short type; 184 private String content; 185 186 private _Term(short type, String content) { 187 this.type = type; 188 this.content=content; 189 } 190 191 private void append(_Term term) { 192 content+=' '+term.content; 193 type=TYPE_PHRASE; 194 } 195 196 private Query toQuery() { 197 if(type==TYPE_FUZZY) return toFuzzyQuery(); 198 else if(type==TYPE_WILDCARD) return new WildcardQuery(toTerm()); 199 else if(type==TYPE_PREFIX)return toPrefixQuery(); 200 else if(type==TYPE_PHRASE) return toPhraseQuery(); 201 return new TermQuery(toTerm()); 202 } 203 204 private FuzzyQuery toFuzzyQuery() { 205 String c=toContent(); 206 return new FuzzyQuery(new Term(FIELD,c.substring(0,c.length()-1))); 207 } 208 209 private PrefixQuery toPrefixQuery() { 210 String c=toContent(); 211 return new PrefixQuery(new Term(FIELD,c.substring(0,c.length()-1))); 212 } 213 214 private PhraseQuery toPhraseQuery() { 215 216 217 TokenStream source = analyzer.tokenStream(FIELD,new StringReader(content)); 218 Vector v = new Vector(); 219 org.apache.lucene.analysis.Token t; 220 221 while (true) { 222 try { 223 t = source.next(); 224 } 225 catch (IOException e) { 226 t = null; 227 } 228 if (t == null) 229 break; 230 v.addElement(t.termText()); 231 } 232 try { 233 source.close(); 234 } 235 catch (IOException e) { 236 // ignore 237 } 238 239 PhraseQuery q = new PhraseQuery(); 240 q.setSlop(0); 241 242 for (int i=0; i<v.size(); i++) { 243 q.add(new Term(FIELD, (String) v.elementAt(i))); 244 } 245 return q; 246 247 } 248 249 private String toContent() { 250 return content; 251 } 252 private Term toTerm() { 253 return new Term(FIELD, toContent()); 254 } 255 @Override 256 public String toString() { 257 return toContent(); 258 } 259 } 260 }