KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > improve > struts > taglib > layout > pager > PagerTag


1 package fr.improve.struts.taglib.layout.pager;
2
3 import java.util.Date JavaDoc;
4
5 import javax.servlet.http.HttpServletRequest JavaDoc;
6 import javax.servlet.jsp.JspException JavaDoc;
7 import javax.servlet.jsp.tagext.Tag JavaDoc;
8
9 import fr.improve.struts.taglib.layout.LayoutTagSupport;
10 import fr.improve.struts.taglib.layout.collection.BaseCollectionTag;
11 import fr.improve.struts.taglib.layout.collection.CollectionTag;
12 import fr.improve.struts.taglib.layout.el.Expression;
13 import fr.improve.struts.taglib.layout.event.EndLayoutEvent;
14 import fr.improve.struts.taglib.layout.event.LayoutEventListener;
15 import fr.improve.struts.taglib.layout.event.StartLayoutEvent;
16 import fr.improve.struts.taglib.layout.skin.BadSkinConfigurationException;
17 import fr.improve.struts.taglib.layout.skin.Skin;
18 import fr.improve.struts.taglib.layout.sort.SortUtil;
19 import fr.improve.struts.taglib.layout.util.IPagerRenderer;
20 import fr.improve.struts.taglib.layout.util.LayoutUtils;
21 import fr.improve.struts.taglib.layout.util.TagUtils;
22
23 /**
24  * Limits the number of items displayed in a collection
25  * <br>
26  * @see BaseCollectionTag BaseCollectionTag
27  *
28  * @author: Jean-Noel Ribette
29  **/

30 public class PagerTag
31     extends LayoutTagSupport
32     implements LayoutEventListener, PagerStatusListener {
33
34     public static final String JavaDoc PAGE_NUMBER_KEY = "pagerPage";
35     public static final String JavaDoc PAGER_SESSION_KEY = "pagerSessionId";
36     protected static final String JavaDoc PAGER_INDEX = "fr.improve.struts.taglib.layout.pager.PagerTag.PAGER_INDEX";
37     protected static final String JavaDoc PAGER_INDEX_CURRENT_PAGE = "fr.improve.struts.taglib.layout.pager.PagerTag.PAGER_INDEX_CURRENT_PAGE";
38     
39     protected static final String JavaDoc BOTTOM = "bottom";
40     protected static final String JavaDoc TOP = "top";
41     protected static final String JavaDoc BOTH = "both";
42         
43     protected String JavaDoc url;
44     protected String JavaDoc maxPageItems;
45     protected String JavaDoc jspMaxPageItems;
46     
47     /**
48      * Total number of elements in the list.
49      */

50     protected int size;
51     protected int numberOfPage;
52     protected String JavaDoc linksLocation = BOTTOM;
53     private String JavaDoc pagerId = null;
54     protected String JavaDoc sessionPagerId = null;
55     
56     protected String JavaDoc previousMsgKey = "layout.pager.previous.label";
57     protected String JavaDoc nextMsgKey = "layout.pager.next.label";
58     
59     protected String JavaDoc previousImgKey = "layout.pager.previous.img";
60     protected String JavaDoc nextImgKey = "layout.pager.next.img";
61     
62     protected static final String JavaDoc MAX_PAGE_ITEMS_PROPERTY = "layout.pager.maxPageItems";
63     protected static final String JavaDoc MAX_LINKS_PROPERTY = "layout.pager.maxLinks";
64     public static final String JavaDoc DISPLAY_DIRECT_LINK = "layout.pager.displayDirect";
65     
66     protected String JavaDoc gotoProperty = "layout.pager.goto";
67     
68     protected String JavaDoc width;
69     protected String JavaDoc align;
70     protected String JavaDoc styleClass;
71     protected String JavaDoc jspStyleClass;
72     
73     /**
74      * Pager renderer.
75      */

76     protected IPagerRenderer renderer;
77     
78     
79     protected void initDynamicValues() {
80         jspStyleClass = styleClass;
81         if (styleClass==null){
82             styleClass = LayoutUtils.getSkin(pageContext.getSession()).getProperty("styleclass.pager",null);
83         }
84     }
85     protected void reset() {
86         styleClass = jspStyleClass;
87         jspStyleClass = null;
88     }
89     /**
90      * Process pager status event.
91      */

92     public Object JavaDoc processPagerStatusEvent(PagerStatusEvent in_event) throws JspException JavaDoc {
93             Integer JavaDoc[] lc_infos = new Integer JavaDoc[4];
94             lc_infos[0] = new Integer JavaDoc(getCurrentPage());
95             lc_infos[1] = new Integer JavaDoc(numberOfPage);
96             lc_infos[2] = new Integer JavaDoc(size);
97             lc_infos[3] = new Integer JavaDoc(maxPageItems);
98             return lc_infos;
99     }
100             
101     /**
102      * Process StartLayout events.
103      */

104     public Object JavaDoc processStartLayoutEvent(StartLayoutEvent in_event) throws JspException JavaDoc {
105         Tag JavaDoc lc_source = in_event.getSource();
106         if (lc_source instanceof PagerContainer) {
107             PagerContainer lc_pagerContainer = (PagerContainer) lc_source;
108             lc_pagerContainer.setOffset(getIndexFirstItem());
109             lc_pagerContainer.setLength(getIndexLastItem() - getIndexFirstItem());
110             
111             // ask for sort.
112
((CollectionTag) lc_pagerContainer).setSortType(CollectionTag.SORT_PAGER);
113             
114             if (TOP.equalsIgnoreCase(getLinksLocation())
115                     || BOTH.equalsIgnoreCase(getLinksLocation())) {
116                 // put an anchor so that the javascript knows where to add the pager
117
new StartLayoutEvent(this, null).send();
118                 
119                 StringBuffer JavaDoc lc_pagerAnchor = new StringBuffer JavaDoc();
120                 lc_pagerAnchor.append("<td colspan=\"");
121                 lc_pagerAnchor.append(String.valueOf(LayoutUtils.getSkin(pageContext.getSession()).getFieldInterface().getColumnNumber()));
122                 if (styleClass!=null) {
123                     lc_pagerAnchor.append("\" class=\"");
124                     lc_pagerAnchor.append(styleClass);
125                 }
126                 lc_pagerAnchor.append("\"><a id=\"");
127                 lc_pagerAnchor.append(pagerId + "Anchor");
128                 lc_pagerAnchor.append("\"/></td>");
129                 
130                 TagUtils.write(pageContext, lc_pagerAnchor.toString());
131                 new EndLayoutEvent(this, null).send();
132             }
133         }
134         // Resent the event.
135
return in_event.sendToParent(this);
136     }
137     
138     /**
139      * Process EndLayout events
140      */

141     public Object JavaDoc processEndLayoutEvent(EndLayoutEvent in_event) throws JspException JavaDoc {
142         Tag JavaDoc lc_source = in_event.getSource();
143         boolean lc_printPager = false;
144         if (lc_source instanceof PagerContainer) {
145                 PagerContainer lc_pagerContainerTag = (PagerContainer) lc_source;
146                 setSize(lc_pagerContainerTag.getSize());
147                 
148                 url = SortUtil.getURLForCollection("", (HttpServletRequest JavaDoc)pageContext.getRequest());
149                 lc_printPager = true;
150         }
151         // Print the pager
152
if (lc_printPager) {
153             // Compute the page number.
154
computePageNumbers();
155             
156             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
157             doPrintTag(sb);
158             // prints the pager at the bottom
159
TagUtils.write(pageContext, sb.toString());
160             
161             if (size >= Integer.parseInt(maxPageItems)) {
162                 if (TOP.equalsIgnoreCase(getLinksLocation())
163                         || BOTH.equalsIgnoreCase(getLinksLocation())) {
164                     // use javascript to copy the pager at the anchor
165
StringBuffer JavaDoc js = new StringBuffer JavaDoc();
166                     js.append("<script>");
167                     
168                     // clone and add the node close to the anchor
169
js.append("document.getElementById('");
170                     js.append(pagerId+"Anchor");
171                     js.append("').parentNode.insertBefore(document.getElementById('");
172                     js.append(pagerId);
173                     js.append("').cloneNode(true), document.getElementById('");
174                     js.append(pagerId+"Anchor");
175                     js.append("'));");
176                     
177                     // rename the new node
178
js.append("document.getElementById('");
179                     js.append(pagerId);
180                     js.append("').setAttribute('id','");
181                     js.append(pagerId+"Top");
182                     js.append("');");
183                     
184                     if (TOP.equalsIgnoreCase(getLinksLocation())) {
185                         // If on ly TOP, then the pager of the bottom must be removed
186
js.append("document.getElementById('");
187                         js.append(pagerId);
188                         js.append("').parentNode.removeChild(document.getElementById('");
189                         js.append(pagerId);
190                         js.append("'));");
191                     }
192                     
193                     js.append("</script>");
194                     
195                     TagUtils.write(pageContext, js.toString());
196                 }
197             }
198             
199         }
200         // Resent the event.
201
return in_event.sendToParent(this);
202     }
203
204     public int doEndLayoutTag() throws JspException JavaDoc {
205         url = null;
206         size = 0;
207         numberOfPage = 0;
208         maxPageItems = jspMaxPageItems;
209         jspMaxPageItems = null;
210         return EVAL_PAGE;
211     }
212     
213     public int doStartLayoutTag() throws JspException JavaDoc {
214         // compute the default max number of items per page.
215
computeDefaultMaxPageItems();
216         
217         // create a unique identifier for this pager
218
pagerId = "pager" + new Date JavaDoc().getTime();
219         
220         // to be sure that we won't have the same Date if there's another pager in the page
221
try {Thread.sleep(1);} catch (InterruptedException JavaDoc e) {}
222                
223         addIndex ();
224         return EVAL_BODY_INCLUDE;
225     }
226     
227     /**
228      * Initialize the maxPageItems.
229      * If a value is specified in the jsp, use it and evaluate it if it is an EL.
230      * If no value is specified, use the default value in the skin configuration file.
231      */

232     protected void computeDefaultMaxPageItems() {
233         jspMaxPageItems = maxPageItems;
234         maxPageItems = Expression.evaluate(maxPageItems, pageContext);
235         if (maxPageItems==null) {
236             maxPageItems = LayoutUtils.getSkin(pageContext.getSession()).getProperty(MAX_PAGE_ITEMS_PROPERTY);
237         }
238     }
239     
240     /**
241      * Initialize the number of pages.
242      */

243     protected void computePageNumbers() {
244         int l_maxPageItems = Integer.parseInt(maxPageItems);
245         numberOfPage = (int) Math.ceil((double)getSize() / (double)l_maxPageItems);
246     }
247
248     /**
249      * Add current index of this pager to pageContext
250      *
251      */

252     protected void addIndex () {
253         String JavaDoc l_index = (String JavaDoc) pageContext.getAttribute(PAGER_INDEX);
254         if (l_index == null) {
255             l_index = "0";
256         } else {
257             l_index = String.valueOf(Integer.parseInt(l_index) + 1);
258         }
259         pageContext.setAttribute(PAGER_INDEX, l_index);
260     }
261     public void release() {
262         styleClass = null;
263         maxPageItems = null;
264         linksLocation = BOTTOM;
265         pagerId = null;
266         align = null;
267         sessionPagerId = null;
268         super.release();
269     }
270     /**
271      * Creation date: (15/06/01 15:38:19)
272      * @return java.lang.String
273      */

274     public java.lang.String JavaDoc getUrl() {
275         return url;
276     }
277     /**
278      * Creation date: (15/06/01 15:38:19)
279      * @param newUrl java.lang.String
280      */

281     public void setUrl(java.lang.String JavaDoc newUrl) {
282         url = newUrl;
283     }
284
285     /**
286      * Gets the maxPageItems
287      * @return Returns a String
288      */

289     public String JavaDoc getMaxPageItems() {
290         return maxPageItems;
291     }
292     /**
293      * Sets the maxPageItems
294      * @param maxPageItems The maxPageItems to set
295      */

296
297     public void setMaxPageItems(String JavaDoc in_maxPageItems) throws JspException JavaDoc {
298         String JavaDoc l_errorMessageNumber =
299             "PagerTag : invalid attribut : maxPageItems should be a number";
300         String JavaDoc l_errorMessageNumberBiggerThanOne =
301             "PagerTat : invalid attribut : maxPageItems should be a number bigger than 0";
302
303         try {
304             int l_maxPageItems = Integer.parseInt(in_maxPageItems);
305
306             if (l_maxPageItems < 1) {
307                 throw new JspException JavaDoc(l_errorMessageNumberBiggerThanOne);
308             }
309         } catch (NumberFormatException JavaDoc enfe) {
310             throw new JspException JavaDoc(l_errorMessageNumber);
311         }
312
313         maxPageItems = in_maxPageItems;
314     }
315     /**
316      * Return current index of this tag in page
317      * @return java.lang.String
318      */

319     protected String JavaDoc getPagerIndex() {
320         return (String JavaDoc) pageContext.getAttribute(PAGER_INDEX);
321     }
322     /**
323      * Return current pager index of this tag for this jsp page
324      * @param in_pagerIndex
325      * @return
326      */

327     protected Integer JavaDoc getCurrentPagePagerIndex(String JavaDoc in_pagerIndex) {
328         return (Integer JavaDoc) pageContext.getSession().getAttribute(((HttpServletRequest JavaDoc)pageContext.getRequest()).getServletPath() + PAGER_INDEX_CURRENT_PAGE + in_pagerIndex);
329     }
330     /**
331      * set current pager index of this tag for this jsp page
332      * @param in_pagerIndex
333      * @param in_currentPage
334      */

335     protected void setCurrentPagePagerIndex(String JavaDoc in_pagerIndex, int in_currentPage) {
336         pageContext.getSession().setAttribute(((HttpServletRequest JavaDoc)pageContext.getRequest()).getServletPath() + PAGER_INDEX_CURRENT_PAGE + in_pagerIndex, new Integer JavaDoc(in_currentPage));
337     }
338     protected int getCurrentPage() {
339         // Compute currentPage or restore it form pageContext
340
String JavaDoc l_pagerIndex = getPagerIndex();
341         // Get the index of pager (ie collection) to sort or change page
342
String JavaDoc l_collectionIndex = pageContext.getRequest().getParameter(SortUtil.SORTUTIL_COLLECTION);
343         
344         //If null, where are not comming from a pager action, and the collection
345
//may have changed.
346
// TODO is it possible to check if the collection has changed ?
347
if (l_collectionIndex==null) {
348         
349             if (sessionPagerId!=null && pageContext.getSession().getAttribute(sessionPagerId)!=null){
350                 return new Integer JavaDoc((String JavaDoc)pageContext.getSession().getAttribute(sessionPagerId)).intValue();
351             }
352             return 0;
353         }
354         
355         // If not equals, it is NOT to sort or change page
356
if (!l_pagerIndex.equals(l_collectionIndex)) {
357             
358             if (sessionPagerId!=null && pageContext.getSession().getAttribute(sessionPagerId)!=null){
359                 return new Integer JavaDoc((String JavaDoc)pageContext.getSession().getAttribute(sessionPagerId)).intValue();
360             }
361     
362             if (getCurrentPagePagerIndex(l_pagerIndex) != null) {
363                 return getCurrentPagePagerIndex(l_pagerIndex).intValue();
364             }
365             // value by default
366
return 0;
367         }
368         
369         // It is diffent, so compute again
370
int lc_currentPage = -1;
371         String JavaDoc lc_possibleValue =
372             pageContext.getRequest().getParameter(PAGE_NUMBER_KEY);
373         if (lc_possibleValue != null) {
374             try {
375                 lc_currentPage = Integer.parseInt(lc_possibleValue);
376             } catch (NumberFormatException JavaDoc nfe) {
377                 // do nothing
378
}
379         } else if (lc_currentPage == -1) {
380             Integer JavaDoc lc_integerPossibleValue =
381                 (Integer JavaDoc) pageContext.getRequest().getAttribute(PAGE_NUMBER_KEY);
382             if (lc_integerPossibleValue != null) {
383                 lc_currentPage = lc_integerPossibleValue.intValue();
384             }
385         }
386         if (lc_currentPage == -1) {
387             lc_currentPage = 0;
388         }
389         // save current page
390
setCurrentPagePagerIndex(l_pagerIndex, lc_currentPage);
391         
392         if (sessionPagerId !=null && pageContext.getSession().getAttribute(sessionPagerId)!=null){
393             pageContext.getSession().setAttribute(sessionPagerId,String.valueOf(lc_currentPage));
394         }
395         return lc_currentPage;
396     }
397     
398     public String JavaDoc getURL(int in_page) {
399         String JavaDoc l_url = url;
400         if (l_url.indexOf("?")==-1) {
401             l_url += "?";
402         } else {
403             l_url += "&";
404         }
405         l_url += PAGE_NUMBER_KEY;
406         l_url += "=";
407         l_url += in_page;
408         if (sessionPagerId!=null) {
409             l_url += "&";
410             l_url += PAGER_SESSION_KEY;
411             l_url += "=";
412             l_url += sessionPagerId;
413         }
414         return l_url;
415     }
416
417     public int getIndexFirstItem() {
418         int l_currentPage = getCurrentPage();
419         int l_maxPageItems = Integer.parseInt(maxPageItems);
420         return l_currentPage * l_maxPageItems;
421
422     }
423     public int getIndexLastItem() {
424         int l_currentPage = getCurrentPage();
425         int l_maxPageItems = Integer.parseInt(maxPageItems);
426         return (l_currentPage + 1) * l_maxPageItems;
427     }
428
429     public void setSize(int in_size) {
430         size = in_size;
431     }
432     public int getSize() {
433         return size;
434     }
435     
436     /**
437      * Generate the pager links.
438      **/

439     public void doPrintTag(StringBuffer JavaDoc in_buffer) throws JspException JavaDoc {
440         int l_maxPageItems = Integer.parseInt(maxPageItems);
441         int l_currentPage = getCurrentPage();
442         
443         if (size<l_maxPageItems) {
444             return;
445         }
446         
447         Skin skin = LayoutUtils.getSkin(pageContext.getSession());
448         renderer = skin.getPagerRenderer();
449         
450         // Start.
451
renderer.doStartPager(this, in_buffer);
452         
453         // Previous section.
454
doPrintPrevious(in_buffer, l_currentPage, skin);
455         
456         // Main section
457
numberOfPage = doPrintMain(in_buffer, l_maxPageItems, l_currentPage);
458
459         // Next section
460
doPrintNext(in_buffer, l_maxPageItems, l_currentPage, skin);
461         
462         // Direct go section
463
doPrintDirect(in_buffer, l_maxPageItems, l_currentPage, skin);
464
465         //End.
466
renderer.doEndPager(this, in_buffer);
467     }
468     
469     /**
470      * Print a link to the previous page.
471      * This method used to generate the link itself,
472      * but now delegates the generation to the renderer.
473      */

474     protected void doPrintPrevious(StringBuffer JavaDoc in_buffer, int in_currentPage, Skin in_skin) {
475         renderer.doPrintPrevious(this, in_buffer, in_currentPage);
476     }
477     
478     /**
479      * Print links to pages.
480      * This method used to generate the link itself,
481      * but now delegates the generation to the renderer.
482      */

483     protected int doPrintMain(StringBuffer JavaDoc in_buffer, int in_maxPageItems, int in_currentPage) {
484         renderer.doPrintMain(this, in_buffer, in_maxPageItems, in_currentPage);
485         return numberOfPage;
486     }
487     
488     /**
489      * Print a link to the next page.
490      * This method used to generate the link itself,
491      * but now delegates the generation to the renderer.
492      */

493     protected void doPrintNext(StringBuffer JavaDoc in_buffer, int in_maxPageItems, int in_currentPage, Skin in_skin) {
494         renderer.doPrintNext(this, in_buffer, in_maxPageItems, in_currentPage);
495     }
496     
497     /**
498      * Print an input box to type in the page number.
499      * This method used to generate the HTML itself,
500      * but now delegates the generaton to the renderer.
501      */

502     protected void doPrintDirect(StringBuffer JavaDoc in_buffer, int in_maxPageItems, int in_currentPage, Skin in_skin) throws JspException JavaDoc {
503         if (Boolean.valueOf(LayoutUtils.getSkin(pageContext.getSession()).getProperty(PagerTag.DISPLAY_DIRECT_LINK)).booleanValue()) {
504             renderer.doPrintDirect(this, in_buffer, in_maxPageItems, in_currentPage);
505         }
506     }
507     
508     /**
509      * Compute the maximum number of links to display (configured in the skin).
510      */

511     public int computeMaxLinks() {
512         String JavaDoc s = LayoutUtils.getSkin(pageContext.getSession()).getProperty(MAX_LINKS_PROPERTY);
513         int i;
514         try {
515             i = Integer.parseInt(s);
516         } catch (NumberFormatException JavaDoc e) {
517             throw new BadSkinConfigurationException("The layout.pager.maxLinksProperty is not a number: " + s);
518         }
519         return i;
520     }
521     
522     /**
523      * While generating the links to the different pages,
524      * return true if a link to a specific pages must be displayed or not.
525      * This code is used to not display to many links.
526      */

527     public boolean shouldDisplay(int in_index, int in_displayed, int in_size, int in_maxSize) {
528         if (in_maxSize>in_size) {
529             // No size control, limit has not been reached.
530
return true;
531         }
532         if (in_index==0) {
533             // Always display the first link.
534
return true;
535         }
536         if (in_index==in_size-1) {
537             // Always display the last link.
538
return true;
539         }
540         if (in_displayed==in_index) {
541             // Always display the current page.
542
return true;
543         }
544         if (in_displayed==in_index-1) {
545             // Always display the previous page.
546
return true;
547         }
548         if (in_displayed==in_index+1) {
549             // Always display the next page.
550
return true;
551         }
552         
553         return false;
554     }
555
556     /**
557      * Sets the styleClass.
558      * @param styleClass The styleClass to set
559      */

560     public void setStyleClass(String JavaDoc styleClass) {
561         this.styleClass = styleClass;
562     }
563     public String JavaDoc getStyleClass() {
564         return styleClass;
565     }
566
567     /**
568      * Sets the width.
569      * @param width The width to set
570      */

571     public void setWidth(String JavaDoc width) {
572         this.width = width;
573     }
574     
575     /**
576      * @return Returns the linksLocation.
577      */

578     public final String JavaDoc getLinksLocation()
579     {
580         return linksLocation;
581     }
582     /**
583      * @param linksLocation The linksLocation to set.
584      */

585     public final void setLinksLocation(String JavaDoc linksLocation)
586     {
587         this.linksLocation = linksLocation;
588     }
589     /**
590      * Retourne l'identifiant unique g?n?r? lors du doStartTag
591      * et qui permet d'identifier le tag "table" qui englobe
592      * tout le rendu du PagerTag.
593      * (de sorte ? pouvoir par la suite le d?placer avec du Javascript)
594      *
595      * @return Returns the pagerId.
596      */

597     public final String JavaDoc getPagerId()
598     {
599         return pagerId;
600     }
601     
602     public void setAlign(String JavaDoc in_align) {
603         align = in_align;
604     }
605     public String JavaDoc getAlign() {
606         return align;
607     }
608
609     public String JavaDoc getSessionPagerId() {
610         return sessionPagerId;
611     }
612
613     public void setSessionPagerId(String JavaDoc sessionPagerId) {
614         this.sessionPagerId = sessionPagerId;
615     }
616     public String JavaDoc getNextImgKey() {
617         return nextImgKey;
618     }
619     public void setNextImgKey(String JavaDoc nextImgKey) {
620         this.nextImgKey = nextImgKey;
621     }
622     public String JavaDoc getNextMsgKey() {
623         return nextMsgKey;
624     }
625     public void setNextMsgKey(String JavaDoc nextMsgKey) {
626         this.nextMsgKey = nextMsgKey;
627     }
628     public String JavaDoc getPreviousImgKey() {
629         return previousImgKey;
630     }
631     public void setPreviousImgKey(String JavaDoc previousImgKey) {
632         this.previousImgKey = previousImgKey;
633     }
634     public String JavaDoc getPreviousMsgKey() {
635         return previousMsgKey;
636     }
637     public void setPreviousMsgKey(String JavaDoc previousMsgKey) {
638         this.previousMsgKey = previousMsgKey;
639     }
640     public String JavaDoc getGotoProperty() {
641         return gotoProperty;
642     }
643     public void setGotoProperty(String JavaDoc gotoProperty) {
644         this.gotoProperty = gotoProperty;
645     }
646     public String JavaDoc getWidth() {
647         return width;
648     }
649     public int getNumberOfPage() {
650         return numberOfPage;
651     }
652 }
Popular Tags