private List<PagingLink> getPagingLinks( int startIndex, int hitsPerPage, int hitsLength, int maxHitSize, String baseUrl, ParamMap params) { List<PagingLink> pagingLinks = new ArrayList<PagingLink>(); // No paging links if only one page of results if (hitsLength <= hitsPerPage) { return pagingLinks; } for (int i = 0; i < hitsLength; i += hitsPerPage) { params.put("startIndex", String.valueOf(i)); if (i < maxHitSize - hitsPerPage) { int pageNumber = i / hitsPerPage + 1; if (i >= startIndex && i < (startIndex + hitsPerPage)) { pagingLinks.add(new PagingLink(pageNumber)); } else { pagingLinks.add(new PagingLink(pageNumber, baseUrl, params)); } } else { pagingLinks.add(new PagingLink("more...", baseUrl, params)); } } return pagingLinks; }
private String getNextPageLink(int startIndex, int hitsPerPage, String baseUrl, ParamMap params) { params.put("startIndex", String.valueOf(startIndex + hitsPerPage)); // return new PagingLink("Next", baseUrl, params); return UrlBuilder.getUrl(baseUrl, params); }
@Override protected ResponseValues processRequest(VitroRequest vreq) { // There may be other non-html formats in the future Format format = getFormat(vreq); boolean wasXmlRequested = Format.XML == format; log.debug("xml was the requested format"); boolean wasHtmlRequested = !wasXmlRequested; try { Portal portal = vreq.getPortal(); PortalFlag portalFlag = vreq.getPortalFlag(); // make sure an IndividualDao is available if (vreq.getWebappDaoFactory() == null || vreq.getWebappDaoFactory().getIndividualDao() == null) { log.error("Could not get webappDaoFactory or IndividualDao"); throw new Exception("Could not access model."); } IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao(); VClassGroupDao grpDao = vreq.getWebappDaoFactory().getVClassGroupDao(); VClassDao vclassDao = vreq.getWebappDaoFactory().getVClassDao(); String alphaFilter = vreq.getParameter("alpha"); int startIndex = 0; try { startIndex = Integer.parseInt(vreq.getParameter("startIndex")); } catch (Throwable e) { startIndex = 0; } log.debug("startIndex is " + startIndex); int hitsPerPage = defaultHitsPerPage; try { hitsPerPage = Integer.parseInt(vreq.getParameter("hitsPerPage")); } catch (Throwable e) { hitsPerPage = defaultHitsPerPage; } log.debug("hitsPerPage is " + hitsPerPage); int maxHitSize = defaultMaxSearchSize; if (startIndex >= defaultMaxSearchSize - hitsPerPage) maxHitSize = startIndex + defaultMaxSearchSize; if (alphaFilter != null) { maxHitSize = maxHitSize * 2; hitsPerPage = maxHitSize; } log.debug("maxHitSize is " + maxHitSize); String qtxt = vreq.getParameter(VitroQuery.QUERY_PARAMETER_NAME); Analyzer analyzer = getAnalyzer(getServletContext()); Query query = null; try { query = getQuery(vreq, portalFlag, analyzer, qtxt); log.debug("query for '" + qtxt + "' is " + query.toString()); } catch (ParseException e) { return doBadQuery(portal, qtxt, format); } IndexSearcher searcherForRequest = LuceneIndexFactory.getIndexSearcher(getServletContext()); TopDocs topDocs = null; try { topDocs = searcherForRequest.search(query, null, maxHitSize); } catch (Throwable t) { log.error("in first pass at search: " + t); // this is a hack to deal with odd cases where search and index threads interact try { wait(150); topDocs = searcherForRequest.search(query, null, maxHitSize); } catch (Exception ex) { log.error(ex); String msg = makeBadSearchMessage(qtxt, ex.getMessage()); if (msg == null) { msg = "The search request contained errors."; } return doFailedSearch(msg, qtxt, format); } } if (topDocs == null || topDocs.scoreDocs == null) { log.error("topDocs for a search was null"); String msg = "The search request contained errors."; return doFailedSearch(msg, qtxt, format); } int hitsLength = topDocs.scoreDocs.length; if (hitsLength < 1) { return doNoHits(qtxt, format); } log.debug("found " + hitsLength + " hits"); int lastHitToShow = 0; if ((startIndex + hitsPerPage) > hitsLength) { lastHitToShow = hitsLength; } else { lastHitToShow = startIndex + hitsPerPage - 1; } List<Individual> beans = new LinkedList<Individual>(); for (int i = startIndex; i < topDocs.scoreDocs.length; i++) { try { if ((i >= startIndex) && (i <= lastHitToShow)) { Document doc = searcherForRequest.doc(topDocs.scoreDocs[i].doc); String uri = doc.get(Entity2LuceneDoc.term.URI); Individual ent = new IndividualImpl(); ent.setURI(uri); ent = iDao.getIndividualByURI(uri); if (ent != null) beans.add(ent); } } catch (Exception e) { log.error("problem getting usable Individuals from search " + "hits" + e.getMessage()); } } ParamMap pagingLinkParams = new ParamMap(); pagingLinkParams.put("querytext", qtxt); pagingLinkParams.put("hitsPerPage", String.valueOf(hitsPerPage)); if (wasXmlRequested) { pagingLinkParams.put(XML_REQUEST_PARAM, "1"); } /* Start putting together the data for the templates */ Map<String, Object> body = new HashMap<String, Object>(); String classGroupParam = vreq.getParameter("classgroup"); boolean classGroupFilterRequested = false; if (!StringUtils.isEmpty(classGroupParam)) { VClassGroup grp = grpDao.getGroupByURI(classGroupParam); classGroupFilterRequested = true; if (grp != null && grp.getPublicName() != null) body.put("classGroupName", grp.getPublicName()); } String typeParam = vreq.getParameter("type"); boolean typeFiltereRequested = false; if (!StringUtils.isEmpty(typeParam)) { VClass type = vclassDao.getVClassByURI(typeParam); typeFiltereRequested = true; if (type != null && type.getName() != null) body.put("typeName", type.getName()); } /* Add classgroup and type refinement links to body */ if (wasHtmlRequested) { // Search request includes no classgroup and no type, so add classgroup search refinement // links. if (!classGroupFilterRequested && !typeFiltereRequested) { List<VClassGroup> classgroups = getClassGroups(grpDao, topDocs, searcherForRequest); List<VClassGroupSearchLink> classGroupLinks = new ArrayList<VClassGroupSearchLink>(classgroups.size()); for (VClassGroup vcg : classgroups) { if (vcg.getPublicName() != null) { classGroupLinks.add(new VClassGroupSearchLink(qtxt, vcg)); } } body.put("classGroupLinks", classGroupLinks); // Search request is for a classgroup, so add rdf:type search refinement links // but try to filter out classes that are subclasses } else if (classGroupFilterRequested && !typeFiltereRequested) { List<VClass> vClasses = getVClasses(vclassDao, topDocs, searcherForRequest); List<VClassSearchLink> vClassLinks = new ArrayList<VClassSearchLink>(vClasses.size()); for (VClass vc : vClasses) { vClassLinks.add(new VClassSearchLink(qtxt, vc)); } body.put("classLinks", vClassLinks); pagingLinkParams.put("classgroup", classGroupParam); // This case is never displayed } else if (!StringUtils.isEmpty(alphaFilter)) { body.put("alphas", getAlphas(topDocs, searcherForRequest)); alphaSortIndividuals(beans); } else { pagingLinkParams.put("type", typeParam); } } // Convert search result individuals to template model objects body.put( "individuals", ListedIndividualTemplateModel.getIndividualTemplateModelList(beans, vreq)); body.put("querytext", qtxt); body.put("title", qtxt + " - " + portal.getAppName() + " Search Results"); body.put("hitsLength", hitsLength); body.put("startIndex", startIndex); body.put( "pagingLinks", getPagingLinks( startIndex, hitsPerPage, hitsLength, maxHitSize, vreq.getServletPath(), pagingLinkParams)); if (startIndex != 0) { body.put( "prevPage", getPreviousPageLink(startIndex, hitsPerPage, vreq.getServletPath(), pagingLinkParams)); } if (startIndex < (hitsLength - hitsPerPage)) { body.put( "nextPage", getNextPageLink(startIndex, hitsPerPage, vreq.getServletPath(), pagingLinkParams)); } String template = templateTable.get(format).get(Result.PAGED); return new TemplateResponseValues(template, body); } catch (Throwable e) { return doSearchError(e, format); } }