blob: b38e16444cb00b74a2b69dd4277b9b9086f0aa49 [file] [log] [blame]
/*********************************************************************************************************************
* Copyright (c) 2008, 2012 Attensity Europe GmbH and brox IT Solutions GmbH. All rights reserved. This program and the
* accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Andreas Weber (Attensity Europe GmbH), Thomas Menzel (brox IT Solution GmbH) - initial implementation
**********************************************************************************************************************/
package org.eclipse.smila.solr.util;
import static org.apache.commons.lang.StringUtils.isEmpty;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.SolrResponseBase;
import org.eclipse.smila.datamodel.Value;
/** Provide extensions/simplifications for handling SolrQuery. */
public final class SolrQueryUtils {
/** Lucene/Solr operator for OR query parts. */
public static final String OR_SEPARATOR = " ";
/** The query wrapper filter string. */
public static final String QUERY_WRAPPER_FILTER = "QueryWrapperFilter";
/** chars, that if part of a term need to be escaped when searching. */
public static final String ESCAPE_CHARS = "+-&|!(){}[]^~*?:\\\"";
/** chars, that if part of a term need to be escaped when searching. including space */
public static final String ESCAPE_CHARS_WS = ESCAPE_CHARS + " ";
/** avoid instatiiation. */
private SolrQueryUtils() {
}
/**
* @param q
* the query to add the field query part to.
* @param field
* the field name to add the query part for
* @param values
* the field value alternatives to match in the search
*/
public static void appendFieldQueryPart(final StringBuilder q, final String field, final List<Value> values) {
if (field != null && values != null && !(values.isEmpty())) {
if (q.length() > 0) {
q.append(OR_SEPARATOR);
}
q.append(field).append(':');
if (values.size() > 1) {
final StringBuilder multiValue = new StringBuilder();
multiValue.append("(");
for (final Value v : values) {
if (multiValue.length() > 1) {
multiValue.append(OR_SEPARATOR);
}
multiValue.append(v);
}
multiValue.append(")");
q.append(multiValue);
} else {
q.append(values.get(0));
}
}
}
/**
* Encode a query into application/x-www-form-urlencoded format.
*
* @param query
* the query.
* @return the urlencoded query.
* @throws UnsupportedEncodingException
* UnsupportedEncodingException.
*/
public static String encodeQuery(String query) throws UnsupportedEncodingException {
return URLEncoder.encode(query, "UTF-8");
}
public static String decodeQuery(String query) throws UnsupportedEncodingException {
return URLDecoder.decode(query, "UTF-8");
}
/**
* Escapes all chars with a special meaning to the lucene query parser. Spaces are not escaped.
*
* @param query
* the query.
* @return the query after escaping.
* @see SolrQueryUtils#ESCAPE_CHARS
* @see SolrQueryUtils# toConstQueryOnField(String, String)
*/
public static String escapeQuery(String query) {
return escapeQuery(query, ESCAPE_CHARS);
}
/**
* Escapes the given chars in the given query by prepending '\'.
*
* @param query
* the query, if empty nothing happens and it is returned as is.
* @param escapeChars
* the chars to escape
* @return the string
*/
public static String escapeQuery(String query, final String escapeChars) {
/* NOTE: this method has been impl'ed in regard to performance | tmenzel @ May 23, 2011 */
if (isEmpty(query)) {
return query;
}
final int strLength = query.length();
final StringBuilder buf = new StringBuilder(strLength * 2); // can only get twice as big thru injecting '\'
for (int i = 0; i < strLength; i++) {
final char ch = query.charAt(i);
if (escapeChars.indexOf(ch) >= 0) {
buf.append('\\');
}
buf.append(ch);
}
if (buf.length() != query.length()) {
return buf.toString();
}
return query;
}
/**
* returns true if response indicates an error.
*
* @see http://lucene.472066.n3.nabble.com/Response-status-td490876.html
*/
public static boolean responseStatusIsError(final SolrResponseBase response) throws SolrServerException {
return response.getStatus() != 0;
}
/**
* Convert a lucene QueryWrapperFilter to a query filter for solr.
*
* @param filter
* the filter.
* @return the solr query filter.
*/
public static String toSolrQueryFilter(String filter) {
filter = StringUtils.remove(filter, QUERY_WRAPPER_FILTER);
filter = StringUtils.replace(filter, "\\", "\\\\");
return filter;
}
/**
* creates a query string on the given field for a constant which must be searched "as is", i.e. escaping fo chars and
* wrapping in quotes
*
* @param fieldName
* must not contain whitespace, but this is not checked!
* @param constant
* the constant
* @return the lucen query string
*/
public static String toConstQueryOnField(String fieldName, String constant) {
return fieldName + ":\"" + escapeQuery(constant) + '"';
}
/**
* returns an escaped query string of the form {@code (<field>:<token>)}. The given token is fully escaped, i.e.
* including spaces.
*
*
*/
public static String toTokenQueryOnField(String fieldName, String token) {
return "(" + fieldName + ":" + escapeQuery(token, ESCAPE_CHARS_WS) + ')';
}
}