/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.document.library.repository.search.internal; import com.liferay.document.library.repository.search.util.KeywordsUtil; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.repository.search.RepositorySearchQueryTermBuilder; import com.liferay.portal.kernel.search.BooleanClauseOccur; import com.liferay.portal.kernel.search.BooleanQuery; import com.liferay.portal.kernel.search.SearchContext; import com.liferay.portal.kernel.search.TermQuery; import com.liferay.portal.kernel.search.WildcardQuery; import com.liferay.portal.kernel.search.generic.BooleanQueryImpl; import com.liferay.portal.kernel.search.generic.TermQueryImpl; import com.liferay.portal.kernel.search.generic.WildcardQueryImpl; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import java.util.Map; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.core.KeywordAnalyzer; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.QueryParser; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; /** * @author Michael C. Han */ @Component(immediate = true, service = RepositorySearchQueryTermBuilder.class) public class LuceneRepositorySearchQueryTermBuilder implements RepositorySearchQueryTermBuilder { @Override public void addTerm( BooleanQuery booleanQuery, SearchContext searchContext, String field, String value) { if (Validator.isNull(value)) { return; } try { QueryParser queryParser = new QueryParser(field, _analyzer); queryParser.setAllowLeadingWildcard(true); queryParser.setLowercaseExpandedTerms(false); org.apache.lucene.search.Query query = null; try { query = queryParser.parse(value); } catch (Exception e) { query = queryParser.parse(KeywordsUtil.escape(value)); } translateQuery( booleanQuery, searchContext, query, org.apache.lucene.search.BooleanClause.Occur.SHOULD); } catch (Exception e) { _log.error(e, e); } } @Activate protected void activate(Map<String, Object> properties) { _analyzer = new KeywordAnalyzer(); } protected org.apache.lucene.search.BooleanClause.Occur getBooleanClauseOccur(BooleanClauseOccur occur) { if (occur.equals(BooleanClauseOccur.MUST)) { return org.apache.lucene.search.BooleanClause.Occur.MUST; } else if (occur.equals(BooleanClauseOccur.MUST_NOT)) { return org.apache.lucene.search.BooleanClause.Occur.MUST_NOT; } return org.apache.lucene.search.BooleanClause.Occur.SHOULD; } protected BooleanClauseOccur getBooleanClauseOccur( org.apache.lucene.search.BooleanClause.Occur occur) { if (occur.equals(org.apache.lucene.search.BooleanClause.Occur.MUST)) { return BooleanClauseOccur.MUST; } else if (occur.equals( org.apache.lucene.search.BooleanClause.Occur.MUST_NOT)) { return BooleanClauseOccur.MUST_NOT; } return BooleanClauseOccur.SHOULD; } protected void translateQuery( BooleanQuery booleanQuery, SearchContext searchContext, org.apache.lucene.search.Query query, org.apache.lucene.search.BooleanClause.Occur occur) throws Exception { BooleanClauseOccur booleanClauseOccur = getBooleanClauseOccur(occur); if (query instanceof org.apache.lucene.search.TermQuery) { org.apache.lucene.search.TermQuery luceneTermQuery = (org.apache.lucene.search.TermQuery)query; Term term = luceneTermQuery.getTerm(); String termValue = term.text(); TermQuery termQuery = new TermQueryImpl(term.field(), termValue); booleanQuery.add(termQuery, getBooleanClauseOccur(occur)); } else if (query instanceof org.apache.lucene.search.BooleanQuery) { org.apache.lucene.search.BooleanQuery curBooleanQuery = (org.apache.lucene.search.BooleanQuery)query; BooleanQuery conjunctionQuery = new BooleanQueryImpl(); BooleanQuery disjunctionQuery = new BooleanQueryImpl(); for (org.apache.lucene.search.BooleanClause booleanClause : curBooleanQuery.getClauses()) { BooleanClauseOccur curBooleanClauseOccur = getBooleanClauseOccur(booleanClause.getOccur()); BooleanQuery subbooleanQuery = null; if (curBooleanClauseOccur.equals(BooleanClauseOccur.SHOULD)) { subbooleanQuery = disjunctionQuery; } else { subbooleanQuery = conjunctionQuery; } translateQuery( subbooleanQuery, searchContext, booleanClause.getQuery(), booleanClause.getOccur()); } if (conjunctionQuery.hasClauses()) { booleanQuery.add(conjunctionQuery, BooleanClauseOccur.MUST); } if (disjunctionQuery.hasClauses()) { booleanQuery.add(disjunctionQuery, BooleanClauseOccur.SHOULD); } } else if (query instanceof org.apache.lucene.search.FuzzyQuery) { org.apache.lucene.search.FuzzyQuery fuzzyQuery = (org.apache.lucene.search.FuzzyQuery)query; Term term = fuzzyQuery.getTerm(); String termValue = term.text().concat(StringPool.STAR); WildcardQuery wildcardQuery = new WildcardQueryImpl( term.field(), termValue); booleanQuery.add(wildcardQuery, booleanClauseOccur); } else if (query instanceof org.apache.lucene.search.PhraseQuery) { org.apache.lucene.search.PhraseQuery phraseQuery = (org.apache.lucene.search.PhraseQuery)query; Term[] terms = phraseQuery.getTerms(); StringBundler sb = new StringBundler(terms.length * 2); for (Term term : terms) { sb.append(term.text()); sb.append(StringPool.SPACE); } TermQuery termQuery = new TermQueryImpl( terms[0].field(), sb.toString().trim()); booleanQuery.add(termQuery, booleanClauseOccur); } else if (query instanceof org.apache.lucene.search.PrefixQuery) { org.apache.lucene.search.PrefixQuery prefixQuery = (org.apache.lucene.search.PrefixQuery)query; Term prefixTerm = prefixQuery.getPrefix(); String termValue = prefixTerm.text().concat(StringPool.STAR); WildcardQuery wildcardQuery = new WildcardQueryImpl( prefixTerm.field(), termValue); booleanQuery.add(wildcardQuery, booleanClauseOccur); } else if (query instanceof org.apache.lucene.search.TermRangeQuery) { org.apache.lucene.search.TermRangeQuery termRangeQuery = (org.apache.lucene.search.TermRangeQuery)query; booleanQuery.addRangeTerm( termRangeQuery.getField(), termRangeQuery.getLowerTerm().utf8ToString(), termRangeQuery.getUpperTerm().utf8ToString()); } else if (query instanceof org.apache.lucene.search.WildcardQuery) { org.apache.lucene.search.WildcardQuery luceneWildcardQuery = (org.apache.lucene.search.WildcardQuery)query; Term wildcardTerm = luceneWildcardQuery.getTerm(); WildcardQuery wildcardQuery = new WildcardQueryImpl( wildcardTerm.field(), wildcardTerm.text()); booleanQuery.add(wildcardQuery, booleanClauseOccur); } else { if (_log.isWarnEnabled()) { _log.warn( "Ignoring unknown query type " + query.getClass() + " with query " + query); } } } private static final Log _log = LogFactoryUtil.getLog( LuceneRepositorySearchQueryTermBuilder.class); private Analyzer _analyzer; }