package org.greenstone.gsdl3.service;
// Greenstone classes
import org.greenstone.gdbm.*;
import org.greenstone.gsdl3.util.*;
// XML classes
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import java.util.HashMap;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.*; //Document;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Hits;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.index.Term;
import java.io.File;
/**
*
* @author Katherine Don
* @version $Revision: 5991 $
*/
public class LuceneSearch
extends ServiceRack {
// the services on offer
// these strings must match what is found in the properties file
protected static final String TEXT_QUERY_SERVICE = "TextQuery";
protected static final String QUERY_PARAM = "query";
public boolean configure(Element info, Element extra_info) {
System.out.println("Configuring LuceneSearch");
Element tq_service = this.doc.createElement(GSXML.SERVICE_ELEM);
tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
this.short_service_info.appendChild(tq_service);
// look for format info
String path = GSPath.appendLink(GSXML.SEARCH_ELEM, GSXML.FORMAT_ELEM);
Element format = (Element) GSXML.getNodeByPath(extra_info, path);
if (format != null) {
System.out.println("found format :"+this.converter.getString(format));
this.format_info_map.put(TEXT_QUERY_SERVICE, this.doc.importNode(format, true));
}
return true;
}
protected Element getServiceDescription(String service, String lang, String subset) {
if (!service.equals(TEXT_QUERY_SERVICE)) {
return null;
}
Element tq_service = this.doc.createElement(GSXML.SERVICE_ELEM);
tq_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_QUERY);
tq_service.setAttribute(GSXML.NAME_ATT, TEXT_QUERY_SERVICE);
if (subset==null || subset.equals(GSXML.DISPLAY_TEXT_ELEM)) {
tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(TEXT_QUERY_SERVICE+".name", lang)));
tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_SUBMIT, getTextString(TEXT_QUERY_SERVICE+".submit", lang)));
tq_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(TEXT_QUERY_SERVICE+".description", lang)));
}
if (subset==null || subset.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
Element param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
Element param = GSXML.createParameterDescription(this.doc, QUERY_PARAM, getTextString("param."+QUERY_PARAM, lang), GSXML.PARAM_TYPE_STRING, null, null, null);
param_list.appendChild(param);
tq_service.appendChild(param_list);
}
return tq_service;
}
/** Process a text query - implemented by concrete subclasses */
protected Element processTextQuery(Element request) {
// Create a new (empty) result message
Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
result.setAttribute(GSXML.FROM_ATT, TEXT_QUERY_SERVICE);
result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
Element doc_node_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
result.appendChild(doc_node_list);
Element metadata_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
result.appendChild(metadata_list);
// Get the parameters of the request
Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
if (param_list == null) {
System.err.println("LuceneSearch Error: TextQuery request had no paramList.");
GSXML.addMetadata(this.doc, metadata_list, "numDocsMatched", "0");
return result; // Return the empty result
}
// Process the request parameters
HashMap params = GSXML.extractParams(param_list, false);
// Make sure a query has been specified
String query_string = (String) params.get(QUERY_PARAM);
if (query_string == null || query_string.equals("")) {
System.err.println("LuceneSearch Error: TextQuery request had no query string.");
GSXML.addMetadata(this.doc, metadata_list, "numDocsMatched", "0");
return result; // Return the empty result
}
try {
String index_dir = GSFile.collectionIndexDir(this.site_home, this.cluster_name);
index_dir += File.separator+"idx";
Searcher searcher = new IndexSearcher(index_dir);
Analyzer analyzer = new StandardAnalyzer();
Term term = new Term("content", query_string);
Query query = new TermQuery(term);
Hits hits = searcher.search(query);
GSXML.addMetadata(this.doc, metadata_list, "numDocsMatched", ""+hits.length());
for (int i=0; i