/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.webui.servlet;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.dspace.app.webui.util.JSPManager;
import org.dspace.app.webui.util.UIUtil;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.handle.HandleManager;
import org.dspace.search.DSQuery;
import org.dspace.search.QueryArgs;
import org.dspace.search.QueryResults;
/**
* Servlet that provides funcionality for searching the repository using a
* controlled vocabulary as a basis for selecting the search keywords.
*
* @author Miguel Ferreira
* @version $Revision$
*/
public class ControlledVocabularySearchServlet extends DSpaceServlet
{
// the log
private static Logger log = Logger
.getLogger(ControlledVocabularySearchServlet.class);
// the jsp that displays the HTML version of controlled-vocabulary
private static final String SEARCH_JSP = "/controlledvocabulary/search.jsp";
// the jsp that will show the search results
private static final String RESULTS_JSP = "/controlledvocabulary/results.jsp";
/**
* Handles requests
*/
protected void doDSGet(Context context, HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException,
SQLException, AuthorizeException
{
String action = request.getParameter("action") == null ? "" : request
.getParameter("action");
if (action.equals("search"))
{
List<String> keywords = extractKeywords(request);
String query = join(keywords, " or ");
doSearch(context, request, query);
JSPManager.showJSP(request, response, RESULTS_JSP);
}
else if (action.equals("filter"))
{
String filter = request.getParameter("filter");
request.getSession().setAttribute("conceptsearch.filter", filter);
JSPManager.showJSP(request, response, SEARCH_JSP);
}
else
{
JSPManager.showJSP(request, response, SEARCH_JSP);
}
}
/**
* Collects the selected terms from the HTML taxonomy displayed on the
* search form
*
* @param request
* The HttpServletRequest
* @return A Vector with the selected terms from the taxonomy.
*/
private List<String> extractKeywords(HttpServletRequest request)
{
List<String> keywords = new ArrayList<String>();
Enumeration enumeration = request.getParameterNames();
while (enumeration.hasMoreElements())
{
String element = (String) enumeration.nextElement();
if (element.startsWith("cb_"))
{
keywords.add("\"" + request.getParameter(element) + "\"");
}
}
return keywords;
}
/**
* Searches the repository and and puts the results in the request object
*
* @param context
* The DSpace context
* @param request
* The request object
* @param query
* The query expression
* @throws IOException
* @throws SQLException
*/
private void doSearch(Context context, HttpServletRequest request,
String query) throws IOException, SQLException
{
// Get the query
// String query = request.getParameter("query");
int start = UIUtil.getIntParameter(request, "start");
String advanced = request.getParameter("advanced");
// can't start earlier than 0 in the results!
if (start < 0)
{
start = 0;
}
List<String> itemHandles = new ArrayList<String>();
List<String> collectionHandles = new ArrayList<String>();
List<String> communityHandles = new ArrayList<String>();
Item[] resultsItems;
Collection[] resultsCollections;
Community[] resultsCommunities;
QueryResults qResults = null;
QueryArgs qArgs = new QueryArgs();
// if the "advanced" flag is set, build the query string from the
// multiple query fields
if (advanced != null)
{
query = qArgs.buildQuery(request);
}
// Ensure the query is non-null
if (query == null)
{
query = "";
}
// Build log information
String logInfo = "";
// Get our location
Community community = UIUtil.getCommunityLocation(request);
Collection collection = UIUtil.getCollectionLocation(request);
// get the start of the query results page
// List resultObjects = null;
qArgs.setQuery(query);
qArgs.setStart(start);
// Perform the search
if (collection != null)
{
logInfo = "collection_id=" + collection.getID() + ",";
// Values for drop-down box
request.setAttribute("community", community);
request.setAttribute("collection", collection);
qResults = DSQuery.doQuery(context, qArgs, collection);
}
else if (community != null)
{
logInfo = "community_id=" + community.getID() + ",";
request.setAttribute("community", community);
// Get the collections within the community for the dropdown box
request
.setAttribute("collection.array", community
.getCollections());
qResults = DSQuery.doQuery(context, qArgs, community);
}
else
{
// Get all communities for dropdown box
Community[] communities = Community.findAll(context);
request.setAttribute("community.array", communities);
qResults = DSQuery.doQuery(context, qArgs);
}
// now instantiate the results and put them in their buckets
for (int i = 0; i < qResults.getHitHandles().size(); i++)
{
String myHandle = qResults.getHitHandles().get(i);
Integer myType = qResults.getHitTypes().get(i);
// add the handle to the appropriate lists
switch (myType.intValue())
{
case Constants.ITEM:
itemHandles.add(myHandle);
break;
case Constants.COLLECTION:
collectionHandles.add(myHandle);
break;
case Constants.COMMUNITY:
communityHandles.add(myHandle);
break;
}
}
int numCommunities = communityHandles.size();
int numCollections = collectionHandles.size();
int numItems = itemHandles.size();
// Make objects from the handles - make arrays, fill them out
resultsCommunities = new Community[numCommunities];
resultsCollections = new Collection[numCollections];
resultsItems = new Item[numItems];
for (int i = 0; i < numItems; i++)
{
String myhandle = itemHandles.get(i);
Object o = HandleManager.resolveToObject(context, myhandle);
resultsItems[i] = (Item) o;
if (resultsItems[i] == null)
{
throw new SQLException("Query \"" + query
+ "\" returned unresolvable handle: " + myhandle);
}
}
for (int i = 0; i < collectionHandles.size(); i++)
{
String myhandle = collectionHandles.get(i);
Object o = HandleManager.resolveToObject(context, myhandle);
resultsCollections[i] = (Collection) o;
if (resultsCollections[i] == null)
{
throw new SQLException("Query \"" + query
+ "\" returned unresolvable handle: " + myhandle);
}
}
for (int i = 0; i < communityHandles.size(); i++)
{
String myhandle = communityHandles.get(i);
Object o = HandleManager.resolveToObject(context, myhandle);
resultsCommunities[i] = (Community) o;
if (resultsCommunities[i] == null)
{
throw new SQLException("Query \"" + query
+ "\" returned unresolvable handle: " + myhandle);
}
}
// Log
log.info(LogManager.getHeader(context, "search", logInfo + "query=\""
+ query + "\",results=(" + resultsCommunities.length + ","
+ resultsCollections.length + "," + resultsItems.length + ")"));
// Pass in some page qualities
// total number of pages
int pageTotal = 1 + ((qResults.getHitCount() - 1) / qResults
.getPageSize());
// current page being displayed
int pageCurrent = 1 + (qResults.getStart() / qResults.getPageSize());
// pageLast = min(pageCurrent+9,pageTotal)
int pageLast = ((pageCurrent + 9) > pageTotal) ? pageTotal
: (pageCurrent + 9);
// pageFirst = max(1,pageCurrent-9)
int pageFirst = ((pageCurrent - 9) > 1) ? (pageCurrent - 9) : 1;
// Pass the results to the display JSP
request.setAttribute("items", resultsItems);
request.setAttribute("communities", resultsCommunities);
request.setAttribute("collections", resultsCollections);
request.setAttribute("pagetotal", Integer.valueOf(pageTotal));
request.setAttribute("pagecurrent", Integer.valueOf(pageCurrent));
request.setAttribute("pagelast", Integer.valueOf(pageLast));
request.setAttribute("pagefirst", Integer.valueOf(pageFirst));
request.setAttribute("queryresults", qResults);
// And the original query string
request.setAttribute("query", query);
}
/**
* Joins each element present in a list with a separator
*
* @param list
* The list of elements
* @param separator
* The separator that will be used between each element
* @return A string with all the elements concatened and separated by the
* provided connector
*/
public static String join(List<String> list, String separator)
{
StringBuilder result = new StringBuilder();
for (String entry : list)
{
if (result.length() > 0)
{
result.append(separator);
}
result.append(entry);
}
return result.toString();
}
/**
* Handle posts
*/
protected void doDSPost(Context context, HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException,
SQLException, AuthorizeException
{
doDSGet(context, request, response);
}
}