/* * Copyright (c) 2009 Andrejs Jermakovics. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Andrejs Jermakovics - initial implementation */ package it.unibz.instasearch.indexing.querying; import it.unibz.instasearch.indexing.Field; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.FilteredQuery; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.PrefixQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.WildcardQuery; /** * A query that can accepts visitors for its clauses * The visitors can modify the query */ public class VisitableQuery { private Query query; public VisitableQuery(Query q) { this.query = q; } /** * Accept a query visitor * @param queryVisitor */ public void accept(QueryVisitor queryVisitor) { queryVisitor.init(query); query = accept(query, queryVisitor); query = queryVisitor.endVisit(query); } /** * Recursively go through all the clauses of the query and call the visitor * * @param query * @param queryVisitor * @return */ private Query accept(Query query, QueryVisitor queryVisitor) { Query returnQuery = query; if( query instanceof TermQuery ) { TermQuery termQuery = (TermQuery) query; Field field = Field.getByName(termQuery.getTerm().field()); Query newQuery = queryVisitor.visit( termQuery, field ); newQuery.setBoost( query.getBoost() ); returnQuery = newQuery; } else if( query instanceof BooleanQuery ) { BooleanQuery boolQuery = (BooleanQuery) query; BooleanQuery newBoolQuery = queryVisitor.visit(boolQuery); for(BooleanClause boolClause: boolQuery.getClauses()) { if( ! queryVisitor.visit(boolClause) ) continue; Query newQuery = accept( boolClause.getQuery(), queryVisitor ); boolClause.setQuery( newQuery ); } newBoolQuery.setBoost( boolQuery.getBoost() ); newBoolQuery.setMinimumNumberShouldMatch(boolQuery.getMinimumNumberShouldMatch()); returnQuery = newBoolQuery; } else if( query instanceof FilteredQuery ) { FilteredQuery fq = (FilteredQuery) query; Query newQuery = accept(fq.getQuery(), queryVisitor); if( newQuery != fq.getQuery() ) { FilteredQuery newFq = new FilteredQuery(fq.getQuery(), fq.getFilter()); newFq.setBoost( fq.getBoost() ); returnQuery = newFq; } } else if( query instanceof PhraseQuery ) { PhraseQuery phraseQuery = (PhraseQuery) query; returnQuery = queryVisitor.visit(phraseQuery); } else if( query instanceof WildcardQuery ) { WildcardQuery wildcardQuery = (WildcardQuery) query; Field field = Field.getByName(wildcardQuery.getTerm().field()); Query newQuery = queryVisitor.visit( wildcardQuery, field ); newQuery.setBoost( query.getBoost() ); returnQuery = newQuery; } else if( query instanceof PrefixQuery ) { PrefixQuery prefixQuery = (PrefixQuery) query; Field field = Field.getByName(prefixQuery.getPrefix().field()); Query newQuery = queryVisitor.visit( prefixQuery, field ); newQuery.setBoost( query.getBoost() ); returnQuery = newQuery; } else { returnQuery = queryVisitor.visitQuery(query); } return returnQuery; } /** * @return the resulting query after all visitors have changed it */ public Query getQuery() { return query; } }