/*Copyright (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 no.sesat.search.mode.config.SearchConfiguration; import no.sesat.search.mode.config.querybuilder.InfixQueryBuilderConfig; import no.sesat.search.mode.config.querybuilder.QueryBuilderConfig; import no.sesat.search.query.LeafClause; import no.sesat.search.query.OrClause; import no.sesat.search.query.XorClause; /** Query builder for creating a query syntax similar to sesam's own. * * Is not thread safe. * It does not use the QueryBuilderConfig. * * Currently is basically a PrefixQueryBuilder with OrClauses wrapped in () parenthesis. * * @version $Id$ */ public class SesamSyntaxQueryBuilder extends InfixQueryBuilder{ // Constants ----------------------------------------------------- private static final QueryBuilderConfig SESAM_SYNTAX_CONFIG = new InfixQueryBuilderConfig( "", "AND", "", "-", true, false, false); //private static final Logger LOG = Logger.getLogger(SesamSyntaxQueryBuilder.class); // Attributes ---------------------------------------------------- private final SearchConfiguration searchConf; // Static -------------------------------------------------------- // Constructors -------------------------------------------------- public SesamSyntaxQueryBuilder(final Context cxt, final SearchConfiguration searchConf) { super(cxt, SESAM_SYNTAX_CONFIG); this.searchConf = searchConf; } // AbstractReflectionVisitor implementation ---------------------------------------------- private boolean insideOr = false; /** Avoids writting out fields to terms that * do not come from the original query, are not possible for the user to use. * * {@inheritDoc} * @param clause {@inheritDoc} */ @Override protected void visitImpl(LeafClause clause) { if(!isEmptyLeaf(clause)){ String transformedClause = getEscapedTransformedTerm(clause); if(null == clause.getField() && transformedClause.contains(":") && !transformedClause.contains("\\:")){ final String field = transformedClause.substring(0,transformedClause.indexOf(':')); if(!searchConf.getFieldFilterMap().containsValue(field)){ // query transformation has prepended the term with fields that are meaningless to the user. transformedClause = transformedClause.replace(field + ':', ""); } } appendToQueryRepresentation(transformedClause); } } /** Overridden to detect and prevent writing out multiple orGroupOpen and orGroupClose ie ()'s * {@inheritDoc} * @param clause {@inheritDoc} */ @Override protected void visitImpl(final OrClause clause) { if (!isEmptyLeaf(clause)) { boolean wasInside = insideOr; final boolean unary = isEmptyLeaf(clause.getFirstClause()) || isEmptyLeaf(clause.getSecondClause()); if(!insideOr && getConfig().getOrGrouped() && !unary){ appendToQueryRepresentation(getConfig().getOrGroupOpen()); } insideOr = true; clause.getFirstClause().accept(this); if(!isNextLeafInsideNotClause(clause.getSecondClause()) && !unary){ appendToQueryRepresentation(' ' + getConfig().getDefaultInfix() + ' '); } clause.getSecondClause().accept(this); insideOr = wasInside; if(!insideOr && getConfig().getOrGrouped() && !unary){ appendToQueryRepresentation(getConfig().getOrGroupClose()); } } } /** Overridden so to avoid visiting any FULLNAME_ON_LEFT. * * @param clause @{@inheritDoc} */ @Override protected void visitImpl(final XorClause clause) { switch (clause.getHint()) { case FULLNAME_ON_LEFT: clause.getSecondClause().accept(this); break; default: super.visitImpl( clause); } } // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }