Package grails.plugin.searchable.internal.compass.search

Source Code of grails.plugin.searchable.internal.compass.search.DefaultStringQuerySearchableCompassQueryBuilder

/*
* Copyright 2007 the original author or authors.
*
* Licensed 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 grails.plugin.searchable.internal.compass.search;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.lucene.queryParser.CompassQueryParser;
import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.compass.core.Compass;
import org.compass.core.CompassQuery;
import org.compass.core.CompassQueryBuilder;
import org.compass.core.CompassSession;
import org.springframework.util.Assert;

/**
* @author Maurice Nicholson
*/
public class DefaultStringQuerySearchableCompassQueryBuilder extends AbstractSearchableCompassQueryBuilder {
    private static final String[] ANALYZER_NAMES = new String[] {"analyzer"};
    private static final String[] PARSER_NAMES = new String[] {"parser", "queryParser"};
    private static final String[] DEFAULT_PROPERTY_NAMES = new String[] {"defaultProperty", "defaultSearchProperty"};
    private static final String[] PROPERTIES_NAMES = new String[] {"properties"};
    private static final String[] USE_AND_DEFAULT_OPERATOR_NAMES = new String[] {"andDefaultOperator", "useAndDefaultOperator"};
    private static final String[] DEFAULT_OPERATOR_NAMES = new String[] {"defaultOperator"};

    public DefaultStringQuerySearchableCompassQueryBuilder(Compass compass) {
        super(compass);
    }

    public CompassQuery buildQuery(GrailsApplication grailsApplication, CompassSession compassSession, Map options, Object query) {
        Assert.notNull(query, "query cannot be null");
        Assert.isInstanceOf(String.class, query, "query must be a String but is [" + query.getClass().getName() + "]");

        String analyzer = (String) getOption(ANALYZER_NAMES, options);
        String parser = (String) getOption(PARSER_NAMES, options);
        String defaultSearchProperty = (String) getOption(DEFAULT_PROPERTY_NAMES, options);
        Collection properties = (Collection) getOption(PROPERTIES_NAMES, options);
        Boolean useAndDefaultOperator = (Boolean) getOption(USE_AND_DEFAULT_OPERATOR_NAMES, options);
        String defaultOperator = (String) getOption(DEFAULT_OPERATOR_NAMES, options);
        Boolean escape = MapUtils.getBoolean(options, "escape", false);

        Assert.isTrue(!(properties != null && defaultSearchProperty != null), "The " + DefaultGroovyMethods.join(DEFAULT_PROPERTY_NAMES, "/") + " and " + DefaultGroovyMethods.join(PROPERTIES_NAMES, "/") + " options cannot be combined");
        Assert.isTrue(!(defaultOperator != null && useAndDefaultOperator != null), "The [" + DefaultGroovyMethods.join(USE_AND_DEFAULT_OPERATOR_NAMES, ", ") + "] and [" + DEFAULT_PROPERTY_NAMES[0] + "] options indicate the same thing so cannot be used together: [" + DEFAULT_PROPERTY_NAMES + "] is better");

        String queryString = (String) query;
        if (escape) {
            queryString = CompassQueryParser.escape(queryString);
        }

        CompassQueryBuilder compassQueryBuilder = compassSession.queryBuilder();
        CompassQueryBuilder.ToCompassQuery stringBuilder;
        if (properties != null && !properties.isEmpty()) {
            stringBuilder = compassQueryBuilder.multiPropertyQueryString(queryString);
            for (Iterator iter = properties.iterator(); iter.hasNext(); ) {
                ((CompassQueryBuilder.CompassMultiPropertyQueryStringBuilder) stringBuilder).add((String) iter.next());
            }
        } else {
            stringBuilder = compassQueryBuilder.queryString(queryString);
        }

        if (analyzer != null) {
            InvokerHelper.invokeMethod(stringBuilder, "setAnalyzer", analyzer);
        }
        if (parser != null) {
            InvokerHelper.invokeMethod(stringBuilder, "setQueryParser", parser);
        }
        if (defaultSearchProperty != null) {
            InvokerHelper.invokeMethod(stringBuilder, "setDefaultSearchProperty", defaultSearchProperty);
        }
        // todo deprecate "useAndDefaultOperator" - "defaultOperator" is better
        if (useAndDefaultOperator != null) {
            if (useAndDefaultOperator) {
                InvokerHelper.invokeMethod(stringBuilder, "useAndDefaultOperator", null);
            } else {
                InvokerHelper.invokeMethod(stringBuilder, "useOrDefaultOperator", null);
            }
        }
        if (defaultOperator != null) {
            if (defaultOperator.equalsIgnoreCase("and")) {
                InvokerHelper.invokeMethod(stringBuilder, "useAndDefaultOperator", null);
            } else if (defaultOperator.equalsIgnoreCase("or")) {
                InvokerHelper.invokeMethod(stringBuilder, "useOrDefaultOperator", null);
            } else {
                throw new IllegalArgumentException("The [" + DEFAULT_OPERATOR_NAMES[0] + "] option only accepts 'and' or 'or' values but [" + defaultOperator + "] was supplied");
            }
        }
        return stringBuilder.toQuery();
    }

    private Object getOption(String[] names, Map options) {
        Object value = null;
        for (int i = 0; i < names.length; i++) {
            String name = names[i];
            if (options.containsKey(name)) {
                if (value != null) {
                    throw new IllegalArgumentException("More than one equivalent option specified for names: [" + DefaultGroovyMethods.join(names, ", ") + "]");
                }
                value = options.get(name);
            }
        }
        return value;
    }
}
TOP

Related Classes of grails.plugin.searchable.internal.compass.search.DefaultStringQuerySearchableCompassQueryBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.