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

org.elasticsearch.index.query.IndexQueryParserModule Maven / Gradle / Ivy

There is a newer version: 8.15.1
Show newest version
/*
 * Licensed to ElasticSearch and Shay Banon under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. ElasticSearch licenses this
 * file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.elasticsearch.index.query;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Scopes;
import org.elasticsearch.common.inject.assistedinject.FactoryProvider;
import org.elasticsearch.common.inject.multibindings.MapBinder;
import org.elasticsearch.common.settings.Settings;

import java.util.LinkedList;
import java.util.Map;

/**
 *
 */
public class IndexQueryParserModule extends AbstractModule {

    /**
     * A custom processor that can be extended to process and bind custom implementations of
     * {@link QueryParserFactory}, and {@link FilterParser}.
     */
    public static class QueryParsersProcessor {

        /**
         * Extension point to bind a custom {@link QueryParserFactory}.
         */
        public void processXContentQueryParsers(XContentQueryParsersBindings bindings) {

        }

        public static class XContentQueryParsersBindings {

            private final MapBinder binder;
            private final Map groupSettings;

            public XContentQueryParsersBindings(MapBinder binder, Map groupSettings) {
                this.binder = binder;
                this.groupSettings = groupSettings;
            }

            public MapBinder binder() {
                return binder;
            }

            public Map groupSettings() {
                return groupSettings;
            }

            public void processXContentQueryParser(String name, Class xcontentQueryParser) {
                if (!groupSettings.containsKey(name)) {
                    binder.addBinding(name).toProvider(FactoryProvider.newFactory(QueryParserFactory.class, xcontentQueryParser)).in(Scopes.SINGLETON);
                }
            }
        }

        /**
         * Extension point to bind a custom {@link FilterParserFactory}.
         */
        public void processXContentFilterParsers(XContentFilterParsersBindings bindings) {

        }

        public static class XContentFilterParsersBindings {

            private final MapBinder binder;
            private final Map groupSettings;

            public XContentFilterParsersBindings(MapBinder binder, Map groupSettings) {
                this.binder = binder;
                this.groupSettings = groupSettings;
            }

            public MapBinder binder() {
                return binder;
            }

            public Map groupSettings() {
                return groupSettings;
            }

            public void processXContentQueryFilter(String name, Class xcontentFilterParser) {
                if (!groupSettings.containsKey(name)) {
                    binder.addBinding(name).toProvider(FactoryProvider.newFactory(FilterParserFactory.class, xcontentFilterParser)).in(Scopes.SINGLETON);
                }
            }
        }
    }

    private final Settings settings;

    private final LinkedList processors = Lists.newLinkedList();

    private final Map> queries = Maps.newHashMap();
    private final Map> filters = Maps.newHashMap();

    public IndexQueryParserModule(Settings settings) {
        this.settings = settings;
    }

    /**
     * Adds a custom query parser.
     *
     * @param name        The name of the query parser
     * @param queryParser the class of the query parser
     */
    public void addQueryParser(String name, Class queryParser) {
        queries.put(name, queryParser);
    }

    /**
     * Adds a custom filter parser.
     *
     * @param name         The name of the filter parser
     * @param filterParser the class of the filter parser
     */
    public void addFilterParser(String name, Class filterParser) {
        filters.put(name, filterParser);
    }

    public IndexQueryParserModule addProcessor(QueryParsersProcessor processor) {
        processors.addFirst(processor);
        return this;
    }

    @Override
    protected void configure() {

        bind(IndexQueryParserService.class).asEagerSingleton();

        // handle XContenQueryParsers
        MapBinder queryBinder
                = MapBinder.newMapBinder(binder(), String.class, QueryParserFactory.class);
        Map xContentQueryParserGroups = settings.getGroups(IndexQueryParserService.Defaults.QUERY_PREFIX);
        for (Map.Entry entry : xContentQueryParserGroups.entrySet()) {
            String qName = entry.getKey();
            Settings qSettings = entry.getValue();
            Class type = qSettings.getAsClass("type", null);
            if (type == null) {
                throw new IllegalArgumentException("Query Parser [" + qName + "] must be provided with a type");
            }
            queryBinder.addBinding(qName).toProvider(FactoryProvider.newFactory(QueryParserFactory.class,
                    qSettings.getAsClass("type", null))).in(Scopes.SINGLETON);
        }

        QueryParsersProcessor.XContentQueryParsersBindings xContentQueryParsersBindings = new QueryParsersProcessor.XContentQueryParsersBindings(queryBinder, xContentQueryParserGroups);
        for (QueryParsersProcessor processor : processors) {
            processor.processXContentQueryParsers(xContentQueryParsersBindings);
        }

        for (Map.Entry> entry : queries.entrySet()) {
            queryBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(QueryParserFactory.class, entry.getValue())).in(Scopes.SINGLETON);
        }

        // handle XContentFilterParsers
        MapBinder filterBinder
                = MapBinder.newMapBinder(binder(), String.class, FilterParserFactory.class);
        Map xContentFilterParserGroups = settings.getGroups(IndexQueryParserService.Defaults.FILTER_PREFIX);
        for (Map.Entry entry : xContentFilterParserGroups.entrySet()) {
            String fName = entry.getKey();
            Settings fSettings = entry.getValue();
            Class type = fSettings.getAsClass("type", null);
            if (type == null) {
                throw new IllegalArgumentException("Filter Parser [" + fName + "] must be provided with a type");
            }
            filterBinder.addBinding(fName).toProvider(FactoryProvider.newFactory(FilterParserFactory.class,
                    fSettings.getAsClass("type", null))).in(Scopes.SINGLETON);
        }

        QueryParsersProcessor.XContentFilterParsersBindings xContentFilterParsersBindings = new QueryParsersProcessor.XContentFilterParsersBindings(filterBinder, xContentFilterParserGroups);
        for (QueryParsersProcessor processor : processors) {
            processor.processXContentFilterParsers(xContentFilterParsersBindings);
        }

        for (Map.Entry> entry : filters.entrySet()) {
            filterBinder.addBinding(entry.getKey()).toProvider(FactoryProvider.newFactory(FilterParserFactory.class, entry.getValue())).in(Scopes.SINGLETON);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy