1 17 package org.alfresco.repo.search.impl.lucene; 18 19 import java.io.IOException ; 20 import java.io.StringReader ; 21 import java.util.HashSet ; 22 23 import org.alfresco.repo.search.SearcherException; 24 import org.alfresco.repo.search.impl.lucene.query.PathQuery; 25 import org.alfresco.service.cmr.dictionary.AspectDefinition; 26 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 27 import org.alfresco.service.cmr.dictionary.DictionaryService; 28 import org.alfresco.service.cmr.dictionary.PropertyDefinition; 29 import org.alfresco.service.cmr.dictionary.TypeDefinition; 30 import org.alfresco.service.namespace.NamespacePrefixResolver; 31 import org.alfresco.service.namespace.QName; 32 import org.apache.log4j.Logger; 33 import org.apache.lucene.analysis.Analyzer; 34 import org.apache.lucene.analysis.TokenStream; 35 import org.apache.lucene.index.Term; 36 import org.apache.lucene.search.BooleanQuery; 37 import org.apache.lucene.search.Query; 38 import org.apache.lucene.search.RangeQuery; 39 import org.apache.lucene.search.TermQuery; 40 import org.saxpath.SAXPathException; 41 42 import com.werken.saxpath.XPathReader; 43 44 public class LuceneQueryParser extends QueryParser 45 { 46 private static Logger s_logger = Logger.getLogger(LuceneQueryParser.class); 47 48 private NamespacePrefixResolver namespacePrefixResolver; 49 50 private DictionaryService dictionaryService; 51 52 64 static public Query parse(String query, String field, Analyzer analyzer, 65 NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService, int defaultOperator) 66 throws ParseException 67 { 68 if (s_logger.isDebugEnabled()) 69 { 70 s_logger.debug("Using Alfresco Lucene Query Parser for query: " + query); 71 } 72 LuceneQueryParser parser = new LuceneQueryParser(field, analyzer); 73 parser.setOperator(defaultOperator); 74 parser.setNamespacePrefixResolver(namespacePrefixResolver); 75 parser.setDictionaryService(dictionaryService); 76 return parser.parse(query); 77 } 78 79 public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver) 80 { 81 this.namespacePrefixResolver = namespacePrefixResolver; 82 } 83 84 public LuceneQueryParser(String arg0, Analyzer arg1) 85 { 86 super(arg0, arg1); 87 } 88 89 public LuceneQueryParser(CharStream arg0) 90 { 91 super(arg0); 92 } 93 94 public LuceneQueryParser(QueryParserTokenManager arg0) 95 { 96 super(arg0); 97 } 98 99 protected Query getFieldQuery(String field, String queryText) throws ParseException 100 { 101 try 102 { 103 if (field.equals("PATH")) 104 { 105 XPathReader reader = new XPathReader(); 106 LuceneXPathHandler handler = new LuceneXPathHandler(); 107 handler.setNamespacePrefixResolver(namespacePrefixResolver); 108 handler.setDictionaryService(dictionaryService); 109 reader.setXPathHandler(handler); 110 reader.parse(queryText); 111 PathQuery pathQuery = handler.getQuery(); 112 pathQuery.setRepeats(false); 113 return pathQuery; 114 } 115 else if (field.equals("PATH_WITH_REPEATS")) 116 { 117 XPathReader reader = new XPathReader(); 118 LuceneXPathHandler handler = new LuceneXPathHandler(); 119 handler.setNamespacePrefixResolver(namespacePrefixResolver); 120 handler.setDictionaryService(dictionaryService); 121 reader.setXPathHandler(handler); 122 reader.parse(queryText); 123 PathQuery pathQuery = handler.getQuery(); 124 pathQuery.setRepeats(true); 125 return pathQuery; 126 } 127 else if (field.equals("ID")) 128 { 129 TermQuery termQuery = new TermQuery(new Term(field, queryText)); 130 return termQuery; 131 } 132 else if (field.equals("TX")) 133 { 134 TermQuery termQuery = new TermQuery(new Term(field, queryText)); 135 return termQuery; 136 } 137 else if (field.equals("PARENT")) 138 { 139 TermQuery termQuery = new TermQuery(new Term(field, queryText)); 140 return termQuery; 141 } 142 else if (field.equals("PRIMARYPARENT")) 143 { 144 TermQuery termQuery = new TermQuery(new Term(field, queryText)); 145 return termQuery; 146 } 147 else if (field.equals("QNAME")) 148 { 149 XPathReader reader = new XPathReader(); 150 LuceneXPathHandler handler = new LuceneXPathHandler(); 151 handler.setNamespacePrefixResolver(namespacePrefixResolver); 152 handler.setDictionaryService(dictionaryService); 153 reader.setXPathHandler(handler); 154 reader.parse("//" + queryText); 155 return handler.getQuery(); 156 } 157 else if (field.equals("TYPE")) 158 { 159 TypeDefinition target = dictionaryService.getType(QName.createQName(queryText)); 160 if (target == null) 161 { 162 throw new SearcherException("Invalid type: " + queryText); 163 } 164 QName targetQName = target.getName(); 165 HashSet <QName> subclasses = new HashSet <QName>(); 166 for (QName classRef : dictionaryService.getAllTypes()) 167 { 168 TypeDefinition current = dictionaryService.getType(classRef); 169 while ((current != null) && !current.getName().equals(targetQName)) 170 { 171 current = (current.getParentName() == null) ? null : dictionaryService.getType(current 172 .getParentName()); 173 } 174 if (current != null) 175 { 176 subclasses.add(classRef); 177 } 178 } 179 BooleanQuery booleanQuery = new BooleanQuery(); 180 for (QName qname : subclasses) 181 { 182 TermQuery termQuery = new TermQuery(new Term(field, qname.toString())); 183 booleanQuery.add(termQuery, false, false); 184 } 185 return booleanQuery; 186 } 187 else if (field.equals("ASPECT")) 188 { 189 AspectDefinition target = dictionaryService.getAspect(QName.createQName(queryText)); 190 QName targetQName = target.getName(); 191 HashSet <QName> subclasses = new HashSet <QName>(); 192 for (QName classRef : dictionaryService.getAllAspects()) 193 { 194 AspectDefinition current = dictionaryService.getAspect(classRef); 195 while ((current != null) && !current.getName().equals(targetQName)) 196 { 197 current = (current.getParentName() == null) ? null : dictionaryService.getAspect(current 198 .getParentName()); 199 } 200 if (current != null) 201 { 202 subclasses.add(classRef); 203 } 204 } 205 206 BooleanQuery booleanQuery = new BooleanQuery(); 207 for (QName qname : subclasses) 208 { 209 TermQuery termQuery = new TermQuery(new Term(field, qname.toString())); 210 booleanQuery.add(termQuery, false, false); 211 } 212 return booleanQuery; 213 } 214 else if (field.startsWith("@")) 215 { 216 217 String expandedFieldName = field; 218 if (field.charAt(1) != '{') 220 { 221 int colonPosition = field.indexOf(':'); 222 if (colonPosition == -1) 223 { 224 expandedFieldName = "@{" 226 + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1); 227 } 228 else 229 { 230 expandedFieldName = "@{" 232 + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}" 233 + field.substring(colonPosition + 1); 234 } 235 } 236 237 if(expandedFieldName.endsWith(".mimetype")) 238 { 239 QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length()-9)); 240 PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); 241 if((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))) 242 { 243 TermQuery termQuery = new TermQuery(new Term(expandedFieldName, queryText)); 244 return termQuery; 245 } 246 247 } 248 249 return super.getFieldQuery(expandedFieldName, queryText); 251 252 253 } 254 else 255 { 256 return super.getFieldQuery(field, queryText); 257 } 258 } 259 catch (SAXPathException e) 260 { 261 throw new ParseException("Failed to parse XPath...\n" + e.getMessage()); 262 } 263 264 } 265 266 270 protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException 271 { 272 if (field.startsWith("@")) 273 { 274 String fieldName = field; 275 if (field.charAt(1) != '{') 277 { 278 int colonPosition = field.indexOf(':'); 279 if (colonPosition == -1) 280 { 281 fieldName = "@{" + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1); 283 } 284 else 285 { 286 fieldName = "@{" 288 + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}" 289 + field.substring(colonPosition + 1); 290 } 291 } 292 return new RangeQuery(new Term(fieldName, getToken(fieldName, part1)), new Term(fieldName, getToken( 293 fieldName, part2)), inclusive); 294 295 } 296 else 297 { 298 return super.getRangeQuery(field, part1, part2, inclusive); 299 } 300 301 } 302 303 private String getToken(String field, String value) 304 { 305 TokenStream source = analyzer.tokenStream(field, new StringReader (value)); 306 org.apache.lucene.analysis.Token t; 307 String tokenised = null; 308 309 while (true) 310 { 311 try 312 { 313 t = source.next(); 314 } 315 catch (IOException e) 316 { 317 t = null; 318 } 319 if (t == null) 320 break; 321 tokenised = t.termText(); 322 } 323 try 324 { 325 source.close(); 326 } 327 catch (IOException e) 328 { 329 330 } 331 return tokenised; 332 333 } 334 335 public void setDictionaryService(DictionaryService dictionaryService) 336 { 337 this.dictionaryService = dictionaryService; 338 } 339 340 } 341 | Popular Tags |