Java tutorial
/* * 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; } }