/* * Copyright (2006-2012) Schibsted ASA * This file is part of Possom. * * Possom 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 3 of the License, or * (at your option) any later version. * * Possom 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. * * You should have received a copy of the GNU Lesser General Public License * along with Possom. If not, see <http://www.gnu.org/licenses/>. */ package no.sesat.search.mode.command.querybuilder; import java.util.Collection; import java.util.HashSet; import no.sesat.search.mode.config.querybuilder.PrefixQueryBuilderConfig; import no.sesat.search.mode.config.querybuilder.QueryBuilderConfig; import no.sesat.search.query.AndClause; import no.sesat.search.query.DefaultOperatorClause; import no.sesat.search.query.EmailClause; import no.sesat.search.query.LeafClause; import no.sesat.search.query.NotClause; import no.sesat.search.query.OrClause; import no.sesat.search.query.UrlClause; /** QueryBuilder prefixing terms depending on their inclusion/exclusion. * * @todo grouping doesn't work due to a dependence on the lean of the binary tree. * * @version $Id$ */ public class PrefixQueryBuilder extends AbstractQueryBuilder{ // Constants ----------------------------------------------------- protected enum PrefixState { AND, NOT, OR, DEFAULT }; //private static final Logger LOG = Logger.getLogger(PrefixQueryBuilder.class); // Attributes ---------------------------------------------------- private PrefixState state = PrefixState.DEFAULT; // Static -------------------------------------------------------- // Constructors -------------------------------------------------- public PrefixQueryBuilder(final Context cxt, final QueryBuilderConfig config) { super(cxt, config); } // Public -------------------------------------------------------- // Z implementation ---------------------------------------------- // Y overrides --------------------------------------------------- // Package protected --------------------------------------------- // Protected ----------------------------------------------------- @Override protected PrefixQueryBuilderConfig getConfig() { return (PrefixQueryBuilderConfig) super.getConfig(); } @Override protected Collection<String> getWordsToEscape() { final Collection<String> words = new HashSet<String>(super.getWordsToEscape()); if(!getConfig().getAndPrefix().isEmpty()){ words.add(getConfig().getAndPrefix()); } if(!getConfig().getNotPrefix().isEmpty()){ words.add(getConfig().getNotPrefix()); } if(!getConfig().getOrPrefix().isEmpty()){ words.add(getConfig().getOrPrefix()); } return words; } protected void visitImpl(final LeafClause clause) { if(!isEmptyLeaf(clause)){ insertClauseStatePrefix(); appendToQueryRepresentation(getEscapedTransformedTerm(clause)); } } /** * Adds quotes around the Email address and hard escape everything. * Since there is the @ symbols in email addresses. * * @param clause The email clause. */ protected void visitImpl(final EmailClause clause) { if(!isEmptyLeaf(clause)){ insertClauseStatePrefix(); appendToQueryRepresentation(getContext().escape(getContext().getTransformedTerm(clause).toLowerCase())); } } /** * Adds quotes around the URL and hard escape everything. * Since there are so many symbols in URLs. * * @param clause The url clause. */ protected void visitImpl(final UrlClause clause) { if(!isEmptyLeaf(clause)){ insertClauseStatePrefix(); appendToQueryRepresentation(getContext().escape(getContext().getTransformedTerm(clause).toLowerCase())); } } protected void visitImpl(final AndClause clause) { if (!isEmptyLeaf(clause)) { state = PrefixState.AND; if(getConfig().getAndGrouped()){ appendToQueryRepresentation(getConfig().getAndGroupOpen()); } clause.getFirstClause().accept(this); appendToQueryRepresentation(' '); state = PrefixState.AND; clause.getSecondClause().accept(this); if(getConfig().getAndGrouped()){ appendToQueryRepresentation(getConfig().getAndGroupClose()); } } } protected void visitImpl(final OrClause clause) { if (!isEmptyLeaf(clause)) { state = PrefixState.OR; if(getConfig().getOrGrouped()){ appendToQueryRepresentation(getConfig().getOrGroupOpen()); } clause.getFirstClause().accept(this); appendToQueryRepresentation(' '); state = PrefixState.OR; clause.getSecondClause().accept(this); if(getConfig().getOrGrouped()){ appendToQueryRepresentation(getConfig().getOrGroupClose()); } } } protected void visitImpl(final DefaultOperatorClause clause) { if (!isEmptyLeaf(clause)) { state = PrefixState.DEFAULT; if(getConfig().getDefaultGrouped()){ appendToQueryRepresentation(getConfig().getDefaultGroupOpen()); } clause.getFirstClause().accept(this); appendToQueryRepresentation(' '); state = PrefixState.DEFAULT; clause.getSecondClause().accept(this); if(getConfig().getDefaultGrouped()){ appendToQueryRepresentation(getConfig().getDefaultGroupClose()); } } } protected void visitImpl(final NotClause clause) { if(getConfig().getSupportsNot() && !isEmptyLeaf(clause)) { state = PrefixState.NOT; if(getConfig().getNotGrouped()){ appendToQueryRepresentation(getConfig().getNotGroupOpen()); } clause.getFirstClause().accept(this); if(getConfig().getNotGrouped()){ appendToQueryRepresentation(getConfig().getNotGroupClose()); } } } protected PrefixState getPrefixState(){ return state; } // Private ------------------------------------------------------- private void insertClauseStatePrefix(){ switch(state){ case AND: appendToQueryRepresentation(getConfig().getAndPrefix()); break; case NOT: appendToQueryRepresentation(getConfig().getNotPrefix()); break; case OR: appendToQueryRepresentation(getConfig().getOrPrefix()); break; case DEFAULT: default: appendToQueryRepresentation(getConfig().getDefaultPrefix()); break; } } // Inner classes ------------------------------------------------- }