/** * Copyright Plugtree LLC * * 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 com.plugtree.solrmeter.model.service.impl; import java.util.LinkedList; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrQuery.ORDER; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.QueryResponse; import com.google.inject.Singleton; import com.plugtree.solrmeter.model.SolrMeterConfiguration; import com.plugtree.solrmeter.model.SolrServerRegistry; import com.plugtree.solrmeter.model.exception.QueryException; import com.plugtree.solrmeter.model.service.QueryService; /** * SolrJ Implementation of the QueryService * @author tflobbe * */ @Singleton public class QueryServiceSolrJImpl implements QueryService { @Override public QueryResponse executeQuery(String q, String fq, String qt, boolean highlight, String facetFields, String sort, String sortOrder, Integer rows, Integer start, String otherParams) throws QueryException { SolrServer server = SolrServerRegistry.getSolrServer(SolrMeterConfiguration.getProperty(SolrMeterConfiguration.SOLR_SEARCH_URL)); SolrQuery query = this.createQuery(q, fq, qt, highlight, facetFields, sort, sortOrder, rows, start, otherParams); QueryResponse response = null; try { response = server.query(query); } catch (SolrServerException e) { throw new QueryException(e); } return response; } protected SolrQuery createQuery(String q, String fq, String qt, boolean highlight, String facetFields, String sort, String sortOrder, Integer rows, Integer start, String otherParams) throws QueryException { SolrQuery query = new SolrQuery(); if(q != null) { query.setQuery(q); } if(fq != null) { List<String> filterQueries = this.getFilterQueries(fq); for(String filterQuery:filterQueries) { query.addFilterQuery(filterQuery); } } if(qt != null) { query.setQueryType(qt); } query.setHighlight(highlight); if(facetFields == null || "".equals(facetFields)) { query.setFacet(false); }else { query.setFacet(true); List<String> facets = this.getFacets(facetFields); for(String facet:facets) { query.addFacetField(facet); } } if(sort != null && !"".equals(sort)) { query.setSortField(sort, ORDER.valueOf(sortOrder)); } if(rows != null && rows < 0) { throw new QueryException("Rows can't be less than 0"); }else if(rows != null) { query.setRows(rows); } if(start != null && start < 0) { throw new QueryException("Rows can't be less than 0"); }else if(start != null) { query.setStart(start); } if(otherParams != null) { List<String> params = this.getOtherParams(otherParams); for(String param:params) { query.add(getParamName(param), getParamValue(param)); } } return query; } protected String getParamName(String param) { return param.substring(0, param.indexOf("=")); } protected String getParamValue(String param) { return param.substring(param.indexOf("=") + 1 ); } /** * Return the list of name=value pairs for other params. * @param otherParams * @return * @throws QueryException */ protected List<String> getOtherParams(String otherParams) throws QueryException { List<String> list = getCommaSeparatedValues(otherParams); for(String param:list) { this.validateOtherParam(param); } return list; } /** * validate that the param is of type type=value. Value can be empty, but not type * @param param * @throws QueryException */ private void validateOtherParam(String param) throws QueryException { if(!param.contains("=") || param.indexOf("=") == 0) { throw new QueryException("The parameter " + param + " must contain the field name"); } } /** * returns the list of filter queries to add to the query * @param fq * @return */ protected List<String> getFilterQueries(String fq) throws QueryException { List<String> list = getCommaSeparatedValues(fq); for(String filter:list) { this.validateFilterQuery(filter); } return list; } /** * Validate that the filter query contains a field and a value * @param filter * @throws QueryException */ private void validateFilterQuery(String filter) throws QueryException { if(!filter.contains(":") || filter.indexOf(":") == 0) { throw new QueryException("Filter query " + filter + " must contain the field name"); } if(filter.indexOf(":") == filter.length() - 1) { throw new QueryException("Filter query " + filter + " must contain a field value"); } } /** * Returns a list of trings parsing the comma separated values of the parameter string. * @param facetFields * @return * @throws QueryException */ protected List<String> getFacets(String facetFields) throws QueryException { List<String> list = getCommaSeparatedValues(facetFields); for(String facet:list) { if(hasWitespaces(facet)) { throw new QueryException("Facet fields can't have whitespaces"); } } return list; } private boolean hasWitespaces(String facet) { return facet.contains(" "); } private List<String> getCommaSeparatedValues(String value) { List<String> list = new LinkedList<String>(); String[] splitted = value.split(","); for(String chunk:splitted) { String facet = chunk.trim(); if(!facet.isEmpty()) { list.add(chunk.trim()); } } return list; } }