/**
* SearchGreenstone.java
* Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.expeditee.agents;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import org.expeditee.gio.gesture.StandardGestureActions;
import org.expeditee.greenstone.Greenstone3Connection;
import org.expeditee.greenstone.Query;
import org.expeditee.greenstone.QueryOutcome;
import org.expeditee.greenstone.Result;
import org.expeditee.greenstone.ResultDocument;
import org.expeditee.gui.AttributeValuePair;
import org.expeditee.gui.DisplayController;
import org.expeditee.gui.Frame;
import org.expeditee.gui.FrameCreator;
import org.expeditee.gui.FrameGraphics;
import org.expeditee.gui.MessageBay;
import org.expeditee.items.Text;
public class SearchGreenstone extends SearchAgent {
private static String _fullCaseSearchQuery = null;
private static boolean _doCasefolding = true;
private static boolean _doStemming = false;
protected static Greenstone3Connection _gsdl = null;
public static Greenstone3Connection getConnection() {
return _gsdl;
}
private static String _maxResults = "10";
private static boolean _showAbstract = false;
private static boolean _showKeywords = false;
private static boolean _showAuthors = false;
private static boolean _showDate = false;
private String _thisMaxResults = "10";
private int _indexChoice = 1;
private static boolean _getAllMetadata = true;
private static int _locationChoice = 1;
private static String[] _indexKeys = { "TX", "TI", "JO", "BO", "CR", "KE" };
protected static Vector _currentResultSet = null;
private boolean _useLastSearchResults = false;
/**
* dateMap is a hash table. The keys are year values. the data associated
* with each key is a Vector of document IDs therefore, for the current
* result set you can get the set of years in which the results were
* published, and for each year you can get the set of documents published
* in that year
*
* If you want to introduce additional mappings (eg document written by
* authors) you should introduce additional structures here (HashMap used in
* the same way as dateMap will probably suffice
*
*/
protected static Map> _dateMap = new HashMap>();
protected static Map> _pageCountMap = new HashMap>();
protected static Map _titleMap = new HashMap();
public SearchGreenstone(int resultsCount, String searchText) {
super(searchText);
_thisMaxResults = resultsCount + "";
_fullCaseSearchQuery = searchText;
}
public SearchGreenstone(String searchText) {
super(searchText);
_thisMaxResults = _maxResults;
_fullCaseSearchQuery = searchText;
}
public SearchGreenstone(int resultsCount) {
this(null);
_thisMaxResults = resultsCount + "";
}
public SearchGreenstone() {
super(null);
_useLastSearchResults = true;
}
public static void init(Frame settings) {
if (settings == null)
return;
_maxResults = "10";
_showAbstract = false;
_showKeywords = false;
_showAuthors = false;
_showDate = false;
_locationChoice = 1;
// Set the settings
for (Text item : settings.getBodyTextItems(false)) {
AttributeValuePair avp = new AttributeValuePair(item.getText());
if (avp.isAnnotation())
continue;
String attribute = avp.getAttributeOrValue().toLowerCase();
if (attribute.equals("campus"))
_locationChoice = 0;
else if (attribute.equals("autoconnect"))
connect();
else if (attribute.equals("maxresults")) {
try {
_maxResults = avp.getValue();
} catch (Exception e) {
}
} else if (attribute.equals("dostemming"))
_doStemming = true;
else if (attribute.startsWith("showabstract"))
_showAbstract = true;
else if (attribute.startsWith("showauthor"))
_showAuthors = true;
else if (attribute.startsWith("showkeyword"))
_showKeywords = true;
else if (attribute.startsWith("showdate"))
_showDate = true;
}
}
public static void connect() {
if (_gsdl == null)
_gsdl = new Greenstone3Connection(_locationChoice);
}
protected String getResultsTitle() {
return this.getClass().getSimpleName() + "[" + getCursorText() + "]";
}
@Override
protected Frame process(Frame frame) {
String resultsTitle = getResultsTitle();
_results.setTitle(resultsTitle);
if (!_useLastSearchResults) {
connect();
doQuery(_pattern);
} else if (_currentResultSet != null) {
Text newText = DisplayController.getCurrentFrame().createNewText(getCursorText());
_clicked = newText;
StandardGestureActions.pickup(newText);
}
if (_currentResultSet == null || _currentResultSet.size() == 0) {
MessageBay.errorMessage(getNoResultsMessage());
return null;
}
createResults();
_results.save();
String resultFrameName = _results.getName();
if (_clicked != null) {
_clicked.setLink(resultFrameName);
_clicked.setText(resultsTitle);
}
return _results.getFirstFrame();
}
protected String getNoResultsMessage() {
return "Could not find Greenstone query text";
}
/**
* @return
*/
protected String getCursorText() {
return _fullCaseSearchQuery;
}
protected void createResults() {
viewByScore(_currentResultSet, _results);
}
/**
* TODO make this more efficient so the maps are loaded on demand...
*
* @param queryText
*/
protected void doQuery(String queryText) {
_pageCountMap.clear();
_dateMap.clear();
_titleMap.clear();
Query query = createQuery(queryText);
QueryOutcome queryOutcome = _gsdl.issueQueryToServer(query);
if (queryOutcome != null)
_currentResultSet = getResultSetMetadata(queryOutcome);
}
private Query createQuery(String queryText) {
Query query = new Query();
// set the query options
query.setQueryText(queryText);
query.setIndex(_indexKeys[_indexChoice]);
query.setMaxDocsToReturn(_thisMaxResults);
if (_doStemming) {
query.setStemming("1");
} else {
query.setStemming("0");
}
if (_doCasefolding) {
query.setCasefolding("1");
} else {
query.setCasefolding("0");
}
return query;
}
public Vector getResultSetMetadata(QueryOutcome queryOutcome) {
Vector results = queryOutcome.getResults();
for (Result result : results) {
getResultMetadata(result);
}
return results;
}
private void getResultMetadata(Result result) {
String docID = result.getDocID();
_gsdl.getDocumentMetadataFromServer(docID, "Title");
_gsdl.getDocumentMetadataFromServer(docID, "Date");
if (_getAllMetadata) {
_gsdl.getDocumentMetadataFromServer(docID, "Date");
_gsdl.getDocumentMetadataFromServer(docID, "Booktitle");
_gsdl.getDocumentMetadataFromServer(docID, "Journal");
_gsdl.getDocumentMetadataFromServer(docID, "Creator");
_gsdl.getDocumentMetadataFromServer(docID, "Keywords");
_gsdl.getDocumentMetadataFromServer(docID, "Publisher");
_gsdl.getDocumentMetadataFromServer(docID, "Abstract");
_gsdl.getDocumentMetadataFromServer(docID, "Pages");
_gsdl.getDocumentMetadataFromServer(docID, "Number");
_gsdl.getDocumentMetadataFromServer(docID, "Volume");
}
}
/*
* given the Vector of result items (ordered by descending relevance to the
* query) this method iterates through them and constructs an HTML document
* and has it rendered in the result window
*
* This is the default presentation for results
*
* You can modify this method as you wish to change the HTML for the default
* presentation
*
* Some useful method calls are illustrated here - if you have the ID of a
* document you can get all data stored for it with ResultDocument rd =
* gsdl.getDocument(docID); - a ResultDocument object has a set of methods
* for getting metadata values for that document most metadata is a single
* value, but authors and keywords can have multiple values and these are
* stored in a Vector
*
* The IF condition for 'Title' shows how to construct a link that can be
* clicked on and then dealt with by the handleLinkClick() method
*
*/
public void viewByScore(Vector results, FrameCreator resultsCreator) {
for (Result result : results) {
String docID = result.getDocID();
ResultDocument rd = _gsdl.getDocument(docID);
int docRank = result.getRank();
addText(rd, resultsCreator, (docRank + 1) + ". " + rd.getTitle());
}
}
protected String getDetails(ResultDocument rd) {
StringBuffer resultText = new StringBuffer("");
if (rd.metadataExists("Title")) {
resultText.append("title: " + rd.getTitle()).append('\n');
}
if (rd.metadataExists("Date")) {
resultText.append("date: " + rd.getDate()).append('\n');
}
if (rd.metadataExists("Booktitle")) {
resultText.append("booktitle: " + rd.getBooktitle()).append('\n');
}
if (rd.metadataExists("Pages")) {
resultText.append("pages: " + rd.getPages()).append('\n');
}
if (rd.metadataExists("Journal")) {
resultText.append("journal: " + rd.getJournal()).append('\n');
}
if (rd.metadataExists("Volume")) {
resultText.append("volume: " + rd.getVolume()).append('\n');
}
if (rd.metadataExists("Number")) {
resultText.append("number: " + rd.getNumber()).append('\n');
}
if (rd.metadataExists("Editor")) {
resultText.append("editor: " + rd.getEditor()).append('\n');
}
if (rd.metadataExists("Publisher")) {
resultText.append("publisher: " + rd.getPublisher()).append('\n');
}
if (rd.metadataExists("Abstract")) {
resultText.append("abstract: " + rd.getAbstract()).append('\n');
}
for (String author : rd.getAuthors()) {
resultText.append("author: " + author).append('\n');
}
for (String keyword : rd.getKeywords()) {
resultText.append("keyword: " + keyword).append('\n');
}
resultText.deleteCharAt(resultText.length() - 1);
return resultText.toString();
}
@Override
public Frame getResultFrame() {
if (_useLastSearchResults && _currentResultSet == null)
return null;
return super.getResultFrame();
}
protected void addText(ResultDocument rd, FrameCreator results, String text) {
// Put the details on a separate frame
FrameCreator details = new FrameCreator(rd.getTitle());
details.addText(getDetails(rd), null, null, null, true);
if (_showDate && rd.metadataExists("Date"))
text += ", " + rd.getDate();
if (_showAbstract && rd.metadataExists("Abstract"))
text += "\n " + rd.getAbstract();
if (_showAuthors && rd.metadataExists("Creator"))
text += "\nAuthors" + rd.getAuthors().toString();
if (_showKeywords && rd.getKeywords().size() > 0)
text += "\nKeywords" + rd.getKeywords().toString();
results.addText(text, null, details.getName(), "getTextFromChildFrame",
false);
DisplayController.requestRefresh(true);
}
public static void clearSession() {
getConnection().getSessionResults().clear();
_currentResultSet = null;
}
}