org.reuseware.sokan.index.solr.FacetedBrowsing.java Source code

Java tutorial

Introduction

Here is the source code for org.reuseware.sokan.index.solr.FacetedBrowsing.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2012
 * Software Technology Group, Dresden University of Technology
 * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
 * 
 * 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:
 *   Software Technology Group - TU Dresden, Germany;
 *   DevBoost GmbH - Berlin, Germany
 *      - initial API and implementation
 ******************************************************************************/
package org.reuseware.sokan.index.solr;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.eclipse.emf.common.util.EList;
import org.reuseware.sokan.Constraint;
import org.reuseware.sokan.FacetedRequest;
import org.reuseware.sokan.FacetedResponse;
import org.reuseware.sokan.IndexRow;
import org.reuseware.sokan.index.util.CoreUtil;
import org.reuseware.sokan.index.util.FacetUtil;

/**
 * Utility class to support facet-based queries on the Solr index.
 * <p>
 * Webinar: Mastering Solr 1.4 contained hints about faceted queries 
 * on slide 14.
 * <p>
 * q=index replication&facet=true
 * &fq={!tag=proj}project:(luceneOR solr)
 * &facet.field={!ex=proj}project
 * &facet.field={!ex=src}source
 */
public final class FacetedBrowsing {

    private FacetedBrowsing() {
    }

    private static final SolrControler CONTROLER = SolrControler.INSTANCE;
    private static final String AND = " AND ";

    // private static final String OR = " OR ";

    /**
     * Query the index according to the given request.
     * 
     * @param request the faceted request
     * 
     * @return the query result
     */
    public static FacetedResponse query(FacetedRequest request) {
        SolrQuery query = buildQuery(request);
        QueryResponse response = CONTROLER.query(query);
        return buildResponse(response, request);
    }

    private static SolrQuery buildQuery(FacetedRequest request) {

        // create query object
        SolrQuery query = new SolrQuery();

        // allow to define a keyword search on facets and values!
        // String queryString = request.getKeywordSearchString();
        // if (queryString != null && !queryString.equals(""))
        // query.setQuery(queryString);

        // maintain faceted constraints
        List<Constraint> constList = request.getConstraints();
        if (constList == null || constList.isEmpty()) {
            return null;
        }
        // start building queryString
        String queryString = "";
        String valueString;
        String field;
        EList<String> valueList;
        Set<String> fields = CONTROLER.getFieldNames();
        boolean stop;

        for (Constraint con : constList) {
            valueString = ":(";
            valueList = con.getValues();
            field = SolrUtil.adaptField(con.getName(), fields);
            if (field == null) {
                continue;
            }
            if (valueList.size() == 0 || valueList.contains("")) {
                queryString += "-" + field + ":" + "[\"\" TO *]" + AND;
            } else {
                stop = false;
                for (String value : valueList) {
                    //TODO #1261: de-activated to allow complex query construction 
                    /*if (value.contains("*")
                          && (value.contains(" ") || value.startsWith("*"))) {
                       stop = true;
                       break;
                    }*/

                    if (value != null && value.contains("*")) {
                        queryString += field + ":" + value + AND;
                        stop = true;
                        break;
                    }

                    valueString += "\"" + value + "\" ";
                }
                if (stop) {
                    continue;
                }
                queryString += field + CoreUtil.trimLastChar(valueString) + ")" + AND;
            }

        }
        if ("".equals(queryString)) {
            return null;
        }
        queryString = CoreUtil.trimLastSeperator(queryString, AND);
        query.setQuery(queryString);

        // maintain facet fields to get facetCounts
        List<String> facetFields = request.getFacetFields();
        if (facetFields != null && facetFields.size() > 0) {
            query.setFacet(true);
            for (String facet : facetFields) {
                query.addFacetField(facet);
            }
        }

        // TODO #1142: add rows and offset parameters
        CONTROLER.limit(query, request.getRows());

        return query;
    }

    private static FacetedResponse buildResponse(QueryResponse response, FacetedRequest request) {
        if (response == null) {
            return null;
        }
        // maintain content
        List<IndexRow> content = SolrUtil.toIndexRows(response.getResults());

        // maintain value Counts
        Map<String, Map<String, Long>> facetCounts;
        Map<String, Long> valueCounts;
        List<FacetField.Count> values;

        List<FacetField> fields = response.getFacetFields();
        if (fields != null) {
            facetCounts = new HashMap<String, Map<String, Long>>(fields.size());

            for (FacetField facetField : fields) {
                values = facetField.getValues();
                valueCounts = new HashMap<String, Long>(values.size());

                for (FacetField.Count value : values) {
                    valueCounts.put(value.getName(), value.getCount());
                }

                facetCounts.put(facetField.getName(), valueCounts);
            }

        } else {
            facetCounts = Collections.emptyMap();
        }

        // TODO #1142: support rows and offset here!

        return FacetUtil.buildFacetedResponse(request, content, facetCounts);
    }
}