All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.graylog.plugins.views.search.validation.TokenCollectingQueryParser Maven / Gradle / Ivy

There is a newer version: 6.1.4
Show newest version
/*
 * Copyright (C) 2020 Graylog, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Server Side Public License, version 1,
 * as published by MongoDB, Inc.
 *
 * This program 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
 * Server Side Public License for more details.
 *
 * You should have received a copy of the Server Side Public License
 * along with this program. If not, see
 * .
 */
package org.graylog.plugins.views.search.validation;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermRangeQuery;

import java.util.Collection;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class TokenCollectingQueryParser extends QueryParser {

    private final CollectingQueryParserTokenManager tokenManager;
    private final Set processedTokens = new HashSet<>();
    private final Map> tokenLookup = new IdentityHashMap<>();

    public TokenCollectingQueryParser(String defaultFieldName, Analyzer analyzer) {
        this(new CollectingQueryParserTokenManager(), defaultFieldName, analyzer);
    }

    TokenCollectingQueryParser(CollectingQueryParserTokenManager collectingQueryParserTokenManager, String defaultFieldName, Analyzer analyzer) {
        super(collectingQueryParserTokenManager);
        this.tokenManager = collectingQueryParserTokenManager;
        this.init(defaultFieldName, analyzer);
    }


    public List getTokens() {
        return tokenManager.getTokens();
    }

    public Map> getTokenLookup() {
        return tokenLookup;
    }

    @Override
    protected Query newFieldQuery(Analyzer analyzer, String field, String queryText, boolean quoted) throws ParseException {
        return saveQueryLookupTokens(super.newFieldQuery(analyzer, field, queryText, quoted));
    }

    @Override
    protected Query newPrefixQuery(Term prefix) {
        return saveQueryLookupTokens(super.newPrefixQuery(prefix));
    }

    @Override
    protected Query newRegexpQuery(Term regexp) {
        return saveQueryLookupTokens(super.newRegexpQuery(regexp));
    }

    @Override
    protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) {
        return saveQueryLookupTokens(super.newFuzzyQuery(term, minimumSimilarity, prefixLength));
    }

    @Override
    protected Query newMatchAllDocsQuery() {
        return saveQueryLookupTokens(super.newMatchAllDocsQuery());
    }

    @Override
    protected Query newWildcardQuery(Term t) {
        return saveQueryLookupTokens(super.newWildcardQuery(t));
    }

    @Override
    protected Query newSynonymQuery(String field, TermAndBoost[] terms) {
        return saveQueryLookupTokens(super.newSynonymQuery(field, terms));
    }

    @Override
    protected Query newGraphSynonymQuery(Iterator queries) {
        return saveQueryLookupTokens(super.newGraphSynonymQuery(queries));
    }

    @Override
    protected Query newTermQuery(Term term, float boost) {
        return saveQueryLookupTokens(super.newTermQuery(term, boost));
    }

    @Override
    protected Query newRangeQuery(String field, String part1, String part2, boolean startInclusive, boolean endInclusive) {
        // first we let lucene parser to build the term range query
        final TermRangeQuery query = (TermRangeQuery)super.newRangeQuery(field, part1, part2, startInclusive, endInclusive);
        // then we wrap it by our own instance, that overrides the visit method and
        // disables the Automation in the visitor calls.
        final Query adaptedQuery = new BypassAutomationRangeQuery(query.getField(), query.getLowerTerm(), query.getUpperTerm(), query.includesLower(), query.includesUpper(), query.getRewriteMethod());
        return saveQueryLookupTokens(adaptedQuery);
    }

    @Override
    protected Query getBooleanQuery(List clauses) throws ParseException {
        final Query delegate = super.getBooleanQuery(clauses);
        // if the superclass returns null, we also return null to mimic the same behaviour
        return delegate != null ? new FixedBooleanQuery((BooleanQuery) delegate) : null;
    }

    /**
     * This method persists all newly discovered tokens that may be referenced in the query to a lookup for
     * later processing. This is the only place that binds query and its tokens together.
     *
     * This would be also good place to collect all subqueries if needed for any feature.
     */
    private Query saveQueryLookupTokens(Query query) {
        final Collection tokens = CollectionUtils.subtract(tokenManager.getTokens(), processedTokens);
        if (!tokenLookup.containsKey(query) && !tokens.isEmpty()) {
            processedTokens.addAll(tokens);
            tokenLookup.put(query, tokens);
        }
        return query;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy