[Yanel-dev] [PATCH] Pagination of search results

Mehmet Birgi mehmet.birgi at wyona.com
Wed Jul 14 16:13:45 CEST 2010


Hi All

I am attaching to this posting a patch for
/yanel-search-resource-type/src/java/org/wyona/yanel/impl/resources/search/=
SearchResource.java.
The XML delivered by the patched resource will have additional content
that can be used by XSLT for paginating search results. The changes
should be completely backward compatible as the already existing
content has not changed.

Cheers,

Memo



-- =

Mehmet Birgi
www.wyona.com
-------------- next part --------------
Index: SearchResource.java
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- SearchResource.java	(revision 51253)
+++ SearchResource.java	(working copy)
@@ -20,7 +20,12 @@
 import org.apache.commons.lang.StringEscapeUtils;
 =

 /**
- * Search resource
+ * Search resource. The configuration parameters "max-entries-per-page" an=
d "max-navigation-links"
+ * can be used in the resource configuration file to set the number of sea=
rch results per page
+ * and the number of links that will be displayed to navigate between thos=
e pages (usually at the =

+ * bottom of the page). The page numbers to be linked to will be passed to=
 the XSLT so that they can =

+ * be handled there accordingly. The current page number must be shared be=
tween java and XSLT
+ * via the request parameter "page".
  */
 public class SearchResource extends BasicXMLResource {
     =

@@ -30,23 +35,31 @@
     private static String QUERY_NAME =3D "q";
     private static String DOMAIN_NAME =3D "domain";
     private static String DEFAULT_PROVIDER =3D "yanel";
+    private static final String CURRENT_PAGE_NUMBER_REQUEST_PARAMETER_NAME=
 =3D "page";
+    private static final String MAX_ENTRIES_CONFIG_PARAMETER_NAME =3D "max=
-entries-per-page";
+    private static final int MAX_ENTRIES_DEFAULT =3D 10;
+    private static final String MAX_PAGINATION_LINKS_CONFIG_PARAMETER_NAME=
 =3D "max-navigation-links";
+    private static final int MAX_PAGINATION_LINKS_DEFAULT =3D 5;
 =

+    private static int maxEntries =3D MAX_ENTRIES_DEFAULT;
+    private static int maxLinks =3D MAX_PAGINATION_LINKS_DEFAULT;
+
     /**
      * @see org.wyona.yanel.core.api.attributes.ViewableV2#getView(String)
      */
     public View getView(String viewId) throws Exception {
-        String provider =3D getRequest().getParameter(PROVIDER_NAME);
+        String provider =3D getEnvironment().getRequest().getParameter(PRO=
VIDER_NAME);
         if (provider !=3D null && !provider.equals(DEFAULT_PROVIDER)) {
             ExternalSearchProvider esp =3D getExternalSearchProvider(provi=
der);
             if (esp !=3D null) {
                 View view =3D new View();
                 view.setResponse(false); // this resource writes the respo=
nse itself in order to do a server side redirect
 =

-                javax.servlet.http.HttpServletResponse response =3D getRes=
ponse();
+                javax.servlet.http.HttpServletResponse response =3D getEnv=
ironment().getResponse();
                 response.setStatus(307); // Temporary redirect (http://www=
.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
 =

-                String query =3D getRequest().getParameter(QUERY_NAME);
-                String domain =3D getRequest().getParameter(DOMAIN_NAME);
+                String query =3D getEnvironment().getRequest().getParamete=
r(QUERY_NAME);
+                String domain =3D getEnvironment().getRequest().getParamet=
er(DOMAIN_NAME);
                 String site=3D"";
                 if (domain !=3D null) site =3D "+site:" + domain; // TODO:=
 This will work for Google and bing, but is this true for all search engine=
s?
                 response.setHeader("Location", esp.getURL() + query + site=
);
@@ -67,14 +80,14 @@
         StringBuilder sb =3D new StringBuilder("<?xml version=3D\"1.0\"?>"=
);
         sb.append("<y:search xmlns:y=3D\"http://www.wyona.org/yanel/search=
/1.0\">");
 =

-        String provider =3D getRequest().getParameter(PROVIDER_NAME);
+        String provider =3D getEnvironment().getRequest().getParameter(PRO=
VIDER_NAME);
         if (provider =3D=3D null) {
             provider =3D DEFAULT_PROVIDER;
             log.warn("No search provider specified! Default provider will =
be used: " + provider);
         }
         sb.append("<y:provider id=3D\"" + provider + "\">" + provider + "<=
/y:provider>");
 =

-        String query =3D getRequest().getParameter(QUERY_NAME);
+        String query =3D getEnvironment().getRequest().getParameter(QUERY_=
NAME);
         if (query !=3D null && query.length() > 0) {
             sb.append("<y:query>" + StringEscapeUtils.escapeXml(query) + "=
</y:query>");
             try {
@@ -93,8 +106,67 @@
                 }
 =

                 if (results !=3D null && results.length > 0) {
-                    sb.append("<y:results>");
-                    for (int i =3D 0; i < results.length; i++) {
+                    boolean paginate =3D getPaginationParameters();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Max number of search results per page i=
s set to " + maxEntries);
+                        log.debug("Max number of results page links is set=
 to " + maxLinks);
+                        if (paginate) log.debug("Results will be paginated=
"); =

+                            else log.debug("Results won't be paginated");
+                    }
+                    int currentPageNumber =3D 1;
+                    if (paginate) {
+                        String currentPageNumberStr =3D getEnvironment().g=
etRequest().getParameter
+                            (CURRENT_PAGE_NUMBER_REQUEST_PARAMETER_NAME);
+                        if (currentPageNumberStr =3D=3D null || 0 =3D=3D c=
urrentPageNumberStr.length()){
+                            throw new RuntimeException("Pagination error: =
Couldn't get current " +
+                            		"page number, parameter not present in reque=
st");
+                        } else {
+                            currentPageNumber =3D Integer.parseInt(current=
PageNumberStr.trim());
+                            if (log.isDebugEnabled()) {
+                                log.debug("The currently diplayed results =
page number is " + =

+                                        currentPageNumber);
+                            }
+                        }
+                    }
+                    int totalResults =3D results.length;
+                    int totalPages =3D (totalResults / maxEntries) + 1; =

+                    int firstLink =3D currentPageNumber - (maxLinks / 2);
+                    int lastLink =3D firstLink + maxLinks;
+                    if (log.isDebugEnabled()) {
+                        log.debug("Total number of results =3D " + totalRe=
sults);
+                        log.debug("Total number of pages =3D " + totalPage=
s);
+                        log.debug("First link page number =3D " + firstLin=
k);
+                        log.debug("Last link page number =3D " + lastLink);
+                    }
+                    sb.append("<y:pages>");
+                    if (currentPageNumber > 1) {
+                        sb.append("<y:previous>" + (currentPageNumber - 1)=
 + "</y:previous>");
+                    }
+                    for (int pageNumber =3D firstLink; pageNumber < lastLi=
nk; pageNumber++) {
+                        if (pageNumber <=3D 0) continue;
+                        if (pageNumber > totalPages) break;
+                        sb.append("<y:page");
+                        if (pageNumber =3D=3D currentPageNumber) {
+                            sb.append(" selected=3D'true'");
+                        }
+                        sb.append(">" + pageNumber + "</y:page>");
+                    }
+                    if (currentPageNumber < totalPages) {
+                        sb.append("<y:next>" + (currentPageNumber + 1) + "=
</y:next>");
+                    }
+                    sb.append("</y:pages>");
+                    =

+                    sb.append("<y:results page-number=3D'" + currentPageNu=
mber + "'>");
+                    int numberOfEntries;
+                    int startingEntry =3D 0;
+                    if (paginate) {
+                        numberOfEntries =3D maxEntries;
+                        startingEntry =3D (currentPageNumber - 1) * number=
OfEntries;
+                    } else {
+                        numberOfEntries =3D totalResults; =

+                    }
+                    for (int i =3D startingEntry; i < (startingEntry + num=
berOfEntries); i++) {
+                        if (i >=3D totalResults) break;
                         sb.append("<y:result url=3D\"" + results[i].getURL=
() + "\">");
                         if (results[i].getTitle() !=3D null) {
                             log.debug("Title: " + results[i].getTitle());
@@ -127,6 +199,28 @@
     }
 =

     /**
+     * Tries to read the pagination parameters from the resource configura=
tion.
+     * @param maxEntries
+     * @param maxLinks
+     * @return True if at least one parameter could be read, false otherwi=
se.
+     * @throws Exception
+     */
+    private boolean getPaginationParameters() throws Exception {
+        boolean paginate =3D false;
+        String maxEntriesStr =3D getResourceConfigProperty(MAX_ENTRIES_CON=
FIG_PARAMETER_NAME);
+        if (maxEntriesStr !=3D null && 0 !=3D maxEntriesStr.length()){
+            maxEntries =3D Integer.parseInt(maxEntriesStr.trim());
+            paginate =3D true;
+        }
+        String maxLinksStr =3D getResourceConfigProperty(MAX_PAGINATION_LI=
NKS_CONFIG_PARAMETER_NAME);
+        if (maxLinksStr !=3D null && 0 !=3D maxLinksStr.length()){
+            maxLinks =3D Integer.parseInt(maxLinksStr.trim());
+            paginate =3D true;
+        }
+        return paginate;
+    }
+
+    /**
      * @param query Search terms
      */
     private Result[] getLocalResults(String query) throws Exception {


More information about the Yanel-development mailing list