org.freeeed.search.web.solr.SolrSearchService.java Source code

Java tutorial

Introduction

Here is the source code for org.freeeed.search.web.solr.SolrSearchService.java

Source

/*
 *
 * Copyright SHMsoft, Inc. 
 *
 * 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 org.freeeed.search.web.solr;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.freeeed.search.web.WebConstants;
import org.freeeed.search.web.configuration.Configuration;
import org.freeeed.search.web.model.solr.SolrDocument;
import org.freeeed.search.web.model.solr.SolrResult;
import org.freeeed.search.web.session.SolrSessionObject;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

/**
 * 
 * Class SolrSearch.
 * 
 * Do the actual Solr search.
 * 
 * @author ilazarov.
 * 
 *
 */
public class SolrSearchService {
    private static final Logger log = Logger.getLogger(SolrSearchService.class);

    private Configuration configuration;
    private DocumentParser solrDocumentParser;

    /**
     * Search in Solr for the given query.
     * 
     * @param query
     * @param from
     * @param rows
     * @return
     */
    public SolrResult search(String query, int from, int rows) {
        return search(query, from, rows, "gl-search-field", false, null);
    }

    /**
     * Search in Solr for the given query.
     * 
     * @param query
     * @param from
     * @param rows
     * @param defaultField
     * @param highlight
     * @return
     */
    public SolrResult search(String query, int from, int rows, String defaultField, boolean highlight,
            String fields) {
        log.debug("Searching: " + query);

        String searchResult = searchSolr(query, from, rows, defaultField, highlight, fields);

        if (searchResult != null) {
            Document doc = createDOM(searchResult);
            if (doc != null) {
                return buildResult(doc);
            }
        }

        return null;
    }

    public Set<String> getKeywords(String query, int from, int rows, String defaultField, boolean highlight) {
        Set<String> result = new HashSet<String>();

        log.debug("Getting keywords for: " + query);

        String searchResult = searchSolr(query, from, rows, defaultField, highlight, null);

        if (searchResult != null) {
            Document doc = createDOM(searchResult);
            if (doc != null) {
                return getHighlight(doc);
            }
        }

        return result;
    }

    private Set<String> getHighlight(Document solrDoc) {
        Set<String> result = new HashSet<String>();

        Element root = solrDoc.getDocumentElement();
        NodeList lists = root.getElementsByTagName("lst");
        for (int i = 0; i < lists.getLength(); i++) {
            Element lstEl = (Element) lists.item(i);
            String name = lstEl.getAttribute("name");
            if (("highlighting").equals(name)) {
                NodeList markedStrings = lstEl.getElementsByTagName("str");
                for (int j = 0; j < markedStrings.getLength(); j++) {
                    Element strEl = (Element) markedStrings.item(j);
                    String str = strEl.getTextContent();
                    int start = str.indexOf("<em>");
                    while (start > -1) {
                        int end = str.indexOf("</em>", start);
                        if (end != -1) {
                            String word = str.substring(start + 4, end);
                            result.add(word);
                        }

                        start = str.indexOf("<em>", end);
                    }
                }
            }
        }

        return result;
    }

    /**
     * Parse the given DOM to SolrResult object.
     * 
     * @param query
     * @param solrDoc
     * @return
     */
    private SolrResult buildResult(Document solrDoc) {
        SolrResult result = new SolrResult();

        NodeList responseList = solrDoc.getElementsByTagName("result");
        Element responseEl = (Element) responseList.item(0);
        int totalSize = Integer.parseInt(responseEl.getAttribute("numFound"));

        result.setTotalSize(totalSize);

        NodeList documentsList = responseEl.getElementsByTagName("doc");

        Map<String, SolrDocument> solrDocuments = new HashMap<String, SolrDocument>();
        for (int i = 0; i < documentsList.getLength(); i++) {
            Element documentEl = (Element) documentsList.item(i);

            Map<String, List<String>> data = new HashMap<String, List<String>>();

            NodeList fieldsList = documentEl.getChildNodes();
            for (int j = 0; j < fieldsList.getLength(); j++) {
                Element field = (Element) fieldsList.item(j);
                String name = field.getAttribute("name");
                List<String> value = new ArrayList<String>();

                //multivalues
                if (field.getNodeName().equals("arr")) {
                    NodeList strList = field.getChildNodes();
                    for (int k = 0; k < strList.getLength(); k++) {
                        Node strNode = strList.item(k);
                        value.add(strNode.getTextContent());
                    }
                } else {
                    value.add(field.getTextContent());
                }

                data.put(name, value);
            }

            SolrDocument doc = solrDocumentParser.createSolrDocument(data);
            solrDocuments.put(doc.getDocumentId(), doc);
        }

        result.setDocuments(solrDocuments);

        return result;
    }

    /**
     * Create DOM element from the received string data.
     * 
     * @param data
     * @return
     */
    private Document createDOM(String data) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        InputSource source = new InputSource(new StringReader(data));
        try {
            return factory.newDocumentBuilder().parse(source);
        } catch (Exception e) {
            log.error("", e);
        }

        return null;
    }

    /**
     * 
     * Do the actual HTTP requst to Solr and execute the given query.
     * 
     * @param query
     * @param from
     * @param rows
     * @return
     */
    private String searchSolr(String query, int from, int rows, String defaultField, boolean highlight,
            String fields) {

        HttpServletRequest curRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                .getRequest();
        HttpSession session = curRequest.getSession();
        SolrSessionObject solrSession = (SolrSessionObject) session
                .getAttribute(WebConstants.WEB_SESSION_SOLR_OBJECT);
        if (solrSession == null || solrSession.getSelectedCase() == null) {
            return null;
        }

        String solrCore = solrSession.getSelectedCase().getSolrSourceCore();

        if (defaultField == null) {
            defaultField = "gl-search-field";
        }

        try {
            String encodedQuery = URLEncoder.encode(query, "UTF-8");
            String urlStr = configuration.getSolrEndpoint() + "/solr/" + solrCore + "/select/?q=" + encodedQuery
                    + "&start=" + from + "&rows=" + rows + "&df=" + defaultField + "&hl=" + highlight;
            if (fields != null) {
                urlStr += "&fl=" + fields;
            }

            URL url = new URL(urlStr);

            log.debug("Will execute: " + url.toString());

            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            StringBuffer resultBuff = new StringBuffer();

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                resultBuff.append(inputLine).append("\n");
            }

            in.close();

            return resultBuff.toString();
        } catch (Exception e) {
            log.error("Problem accessing Solr: ", e);
        }

        return null;
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    public void setSolrDocumentParser(DocumentParser solrDocumentParser) {
        this.solrDocumentParser = solrDocumentParser;
    }

    public static void main(String args[]) {
        SolrSearchService service = new SolrSearchService();
        Configuration conf = new Configuration();
        service.setConfiguration(conf);

        System.out.println(service.getKeywords("ivan mark ester zlati", 0, 10, "gl-search-field", true));
    }
}