diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/Controllers.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/Controllers.java index af26a622d..77215f7fa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/Controllers.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/Controllers.java @@ -26,7 +26,7 @@ public class Controllers { public static final String ENTITY = "/entity"; public static final String ENTITY_PROP_LIST = "/entityPropList"; - public static final String ENTITY_LIST = "/EntityList"; + public static final String ENTITY_LIST = "/entitylist"; public static final String BROWSE_CONTROLLER = "browsecontroller"; public static final String RETRY_URL = "editForm"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityListController.java index 374bdb8fe..fae6c190f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/EntityListController.java @@ -2,24 +2,47 @@ package edu.cornell.mannlib.vitro.webapp.controller; -import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.flags.FlagException; -import edu.cornell.mannlib.vitro.webapp.web.jsptags.InputElementFormattingTag; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.PrefixQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.TopDocs; + +import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.beans.Portal; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; +import edu.cornell.mannlib.vitro.webapp.controller.TabEntitiesController.PageRecord; +import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.flags.FlagException; +import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc; +import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexFactory; +import edu.cornell.mannlib.vitro.webapp.utils.FlagMathUtils; public class EntityListController extends VitroHttpServlet { + public static final int ENTITY_LIST_CONTROLLER_MAX_RESULTS = 30000; + public static final int INDIVIDUALS_PER_PAGE = 30; + long startTime = -1; private static final Log log = LogFactory.getLog(EntityListController.class.getName()); @@ -47,14 +70,13 @@ public class EntityListController extends VitroHttpServlet { String vitroClassIdStr=req.getParameter("vclassId"); if (vitroClassIdStr!=null && !vitroClassIdStr.equals("")) { try { - //TODO have to change this so vclass's group and entity count are populated - vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr); - if (vclass == null) { - log.error("Couldn't retrieve vclass "+vitroClassIdStr); - res.sendRedirect(Controllers.BROWSE_CONTROLLER+"?"+req.getQueryString()); - } - } catch (Exception ex) { - throw new HelpException("EntityListController: request parameter 'vclassId' must be a URI string"); + vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr); + if (vclass == null) { + log.error("Couldn't retrieve vclass "+vitroClassIdStr); + res.sendRedirect(Controllers.BROWSE_CONTROLLER+"?"+req.getQueryString()); + } + } catch (Exception ex) { + throw new HelpException("EntityListController: request parameter 'vclassId' must be a URI string"); } } } else if (obj instanceof VClass) { @@ -63,9 +85,12 @@ public class EntityListController extends VitroHttpServlet { throw new HelpException("EntityListController: attribute 'vclass' must be of type " + VClass.class.getName() ); } - if (vclass!=null){ - doVClass(req, res, vclass); - } + + if (vclass!=null) + doVClass(vreq, res, vclass); + else + log.debug("no vclass found for " + obj); + } catch (HelpException help){ doHelp(res); } catch (Throwable e) { @@ -88,17 +113,78 @@ public class EntityListController extends VitroHttpServlet { * @throws ServletException * @throws IOException */ - private void doVClass(HttpServletRequest request, HttpServletResponse res, VClass vclass) + private void doVClass(VitroRequest request, HttpServletResponse res, VClass vclass) throws ServletException, IOException, FlagException { - VitroRequest vreq = new VitroRequest(request); + IndexSearcher index = LuceneIndexFactory.getIndexSearcher(getServletContext()); + boolean isSinglePortal = request.getWebappDaoFactory().getPortalDao().isSinglePortal(); - //get list of entities, - List entities = vreq.getWebappDaoFactory().getIndividualDao().getIndividualsByVClass(vclass); - request.setAttribute("entities",entities); - - if (entities == null) { - log.error("entities list is null"); + Portal portal = request.getPortal(); + int portalId = 1; + if( portal != null ) + portalId = portal.getPortalId(); + + + String alpha = request.getParameter("alpha"); + int page = getPage(request); + IndividualDao indDao = request.getWebappDaoFactory().getIndividualDao(); + + //make lucene query for this rdf:type + Query query = getQuery(vclass.getURI(),alpha, isSinglePortal, portalId); + + //execute lucene query for individuals of the specified type + TopDocs docs = index.search(query, null, + ENTITY_LIST_CONTROLLER_MAX_RESULTS, + new Sort(Entity2LuceneDoc.term.NAMEUNANALYZED)); + + if( docs == null ){ + log.error("Search of lucene index returned null"); + throw new ServletException("Search of lucene index returned null"); } + + //get list of individuals for the search results + int size = docs.totalHits; + // don't get all the results, only get results for the requestedSize + List individuals = new ArrayList(INDIVIDUALS_PER_PAGE); + int individualsAdded = 0; + int ii = (page-1)*INDIVIDUALS_PER_PAGE; + while( individualsAdded < INDIVIDUALS_PER_PAGE && ii < size ){ + ScoreDoc hit = docs.scoreDocs[ii]; + if (hit != null) { + Document doc = index.doc(hit.doc); + if (doc != null) { + String uri = doc.getField(Entity2LuceneDoc.term.URI).stringValue(); + Individual ind = indDao.getIndividualByURI( uri ); + individuals.add( ind ); + individualsAdded++; + } else { + log.warn("no document found for lucene doc id " + hit.doc); + } + } else { + log.debug("hit was null"); + } + ii++; + } + + + request.setAttribute("servlet",Controllers.ENTITY_LIST); + request.setAttribute("vclassId", vclass.getURI()); + request.setAttribute("controllerParam","vclassId=" + URLEncoder.encode(vclass.getURI(),"UTF-8")); + request.setAttribute("count", size); + + if( size > INDIVIDUALS_PER_PAGE ){ + request.setAttribute("showPages", Boolean.TRUE); + List pageRecords = TabEntitiesController.makePagesList(size, INDIVIDUALS_PER_PAGE, page); + request.setAttribute("pages", pageRecords); + } + request.setAttribute("showAlpha","1"); + request.setAttribute("letters",Controllers.getLetters()); + request.setAttribute("alpha",alpha); + + request.setAttribute("totalCount", size); + request.setAttribute("entities",individuals); + if (individuals == null) + log.debug("entities list is null for vclass " + vclass.getURI()); + VClassGroup classGroup=vclass.getGroup(); if (classGroup==null) { @@ -107,16 +193,9 @@ public class EntityListController extends VitroHttpServlet { request.setAttribute("title",classGroup.getPublicName()); request.setAttribute("subTitle",vclass.getName()/* + " ("+vclass.getEntityCount()+")"*/); } - request.setAttribute("bodyJsp",Controllers.ENTITY_LIST_JSP); - - //here you could have a search css - //String css = ""; - //request.setAttribute("css",css); - - ////////////////////////////////////////////////////////////////////// + //FINALLY: send off to the BASIC_JSP to get turned into html - // - + request.setAttribute("bodyJsp",Controllers.ENTITY_LIST_JSP); RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP); // use this for more direct debugging: RequestDispatcher rd = request.getRequestDispatcher(Controllers.ENTITY_LIST_JSP); @@ -125,7 +204,63 @@ public class EntityListController extends VitroHttpServlet { rd.include(request,res); } + private int getPage(VitroRequest request) { + String pageStr = request.getParameter("page"); + if( pageStr != null ){ + try{ + return Integer.parseInt(pageStr); + }catch(NumberFormatException nfe){ + log.debug("could not parse page parameter"); + return 1; + } + }else{ + return 1; + } + } + private BooleanQuery getQuery(String vclassUri, String alpha , boolean isSinglePortal, int portalId){ + BooleanQuery query = new BooleanQuery(); + try{ + //query term for rdf:type + query.add( + new TermQuery( new Term(Entity2LuceneDoc.term.RDFTYPE, vclassUri)), + BooleanClause.Occur.MUST ); + + //check for portal filtering + if( ! isSinglePortal ){ + if( portalId < 16 ){ //could be a normal portal + query.add( + new TermQuery( new Term(Entity2LuceneDoc.term.PORTAL, Integer.toString(1 << portalId ))), + BooleanClause.Occur.MUST); + }else{ //could be a combined portal + BooleanQuery tabQueries = new BooleanQuery(); + Long[] ids= FlagMathUtils.numeric2numerics(portalId); + for( Long id : ids){ + tabQueries.add( + new TermQuery( new Term(Entity2LuceneDoc.term.PORTAL,id.toString()) ), + BooleanClause.Occur.SHOULD); + } + query.add(tabQueries,BooleanClause.Occur.MUST); + } + } + + //Add alpha filter if it is needed + Query alphaQuery = null; + if( alpha != null && !"".equals(alpha) && alpha.length() == 1){ + alphaQuery = + new PrefixQuery(new Term(Entity2LuceneDoc.term.NAMEUNANALYZED, alpha.toLowerCase())); + query.add(alphaQuery,BooleanClause.Occur.MUST); + } + + log.debug("Query: " + query); + return query; + }catch (Exception ex){ + log.error(ex,ex); + return new BooleanQuery(); + } + } + + private void doHelp(HttpServletResponse res) throws IOException, ServletException { ServletOutputStream out = res.getOutputStream(); @@ -140,5 +275,5 @@ public class EntityListController extends VitroHttpServlet { public HelpException(String string) { super(string); } - } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/TabEntitiesController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/TabEntitiesController.java index 9e230fad4..3739c1ac8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/TabEntitiesController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/TabEntitiesController.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.controller; import java.io.IOException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -113,9 +114,9 @@ public void doGet( HttpServletRequest req, HttpServletResponse response ) } req.setAttribute("tabId", tab.getTabId()); request.setAttribute("controllerParam","primary=" + tab.getTabId()); - - String alpha = request.getParameter("alpha"); - boolean doAlphaFilter = false; + + String alpha = request.getParameter("alpha"); + boolean doAlphaFilter = false; if(( alpha != null && alpha.length() == 1) ){ doAlphaFilter = true; request.setAttribute("alpha", alpha.toUpperCase()); diff --git a/webapp/web/templates/entity/entityList.jsp b/webapp/web/templates/entity/entityList.jsp index b6ce049cc..f039e49fc 100644 --- a/webapp/web/templates/entity/entityList.jsp +++ b/webapp/web/templates/entity/entityList.jsp @@ -37,6 +37,7 @@ <% /*

${pageTime} milliseconds

*/ %> +
  • @@ -101,5 +102,7 @@ ${requestScope.suppText} + + \ No newline at end of file diff --git a/webapp/web/templates/entity/entityListForTabs.jsp b/webapp/web/templates/entity/entityListForTabs.jsp index bd383feee..3dc36ad93 100644 --- a/webapp/web/templates/entity/entityListForTabs.jsp +++ b/webapp/web/templates/entity/entityListForTabs.jsp @@ -88,11 +88,7 @@
  • -
    -<<<<<<< HEAD:webapp/web/templates/entity/entityListForTabs.jsp -
- -======= + <%-- Show pages to select from --%> @@ -124,5 +120,6 @@ if( request.getAttribute("alpha") != null && ! "all".equalsIgnoreCase((String)re ->>>>>>> c91e65e... Fixing page index on lucene based tabs. NIHVIVO-1143:webapp/web/templates/entity/entityListForTabs.jsp - + + + diff --git a/webapp/web/templates/entity/entityListPages.jsp b/webapp/web/templates/entity/entityListPages.jsp new file mode 100644 index 000000000..02ef8bf3a --- /dev/null +++ b/webapp/web/templates/entity/entityListPages.jsp @@ -0,0 +1,32 @@ +<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%><%/* this odd thing points to something in web.xml */ %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> + +<%-- Show pages to select from --%> +<% +if( request.getAttribute("alpha") != null && ! "all".equalsIgnoreCase((String)request.getAttribute("alpha"))) { + request.setAttribute("pageAlpha",request.getAttribute("alpha")); +}else{ + request.setAttribute("pageAlpha",request.getAttribute("all")); +} +%> + + +
+ + Pages: + + + ${page.index} + + ${requestScope.pageAlpha} + + + + ${page.text} + + + ${page.text} + + +
+
\ No newline at end of file