001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/velocity/tags/sakai_2-4-1/tool/src/java/org/sakaiproject/cheftool/PagedResourceActionII.java $
003: * $Id: PagedResourceActionII.java 7946 2006-04-19 03:13:07Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.cheftool;
021:
022: import java.util.List;
023: import java.util.Vector;
024:
025: import org.sakaiproject.cheftool.api.Menu;
026: import org.sakaiproject.cheftool.api.MenuItem;
027: import org.sakaiproject.cheftool.menu.MenuDivider;
028: import org.sakaiproject.cheftool.menu.MenuEntry;
029: import org.sakaiproject.cheftool.menu.MenuField;
030: import org.sakaiproject.courier.api.ObservingCourier;
031: import org.sakaiproject.event.api.SessionState;
032: import org.sakaiproject.util.ResourceLoader;
033: import org.sakaiproject.util.StringUtil;
034:
035: /**
036: * <p>
037: * PagedResourceAction is a base class that handles paged display of lists of Resourecs with service support for paging.
038: * </p>
039: */
040: public abstract class PagedResourceActionII extends
041: VelocityPortletPaneledAction {
042: protected static ResourceLoader rb_praII = new ResourceLoader(
043: "velocity-tool");
044:
045: /** The default number of messages per page. */
046: protected final static int DEFAULT_PAGE_SIZE = 20;
047:
048: /** portlet configuration parameter names. */
049: protected static final String PARAM_PAGESIZE = "pagesize";
050:
051: /** state attribute names. */
052: protected static final String STATE_VIEW_ID = "view-id";
053:
054: protected static final String STATE_TOP_PAGE_MESSAGE = "msg-top";
055:
056: protected static final String STATE_PAGESIZE = "page-size";
057:
058: protected static final String STATE_NUM_MESSAGES = "num-messages";
059:
060: protected static final String STATE_NEXT_PAGE_EXISTS = "msg-next-page";
061:
062: protected static final String STATE_PREV_PAGE_EXISTS = "msg-prev-page";
063:
064: protected static final String STATE_FIRST_PAGE_EXISTS = "msg-first-page";
065:
066: protected static final String STATE_LAST_PAGE_EXISTS = "msg-last-page";
067:
068: protected static final String STATE_GO_NEXT_PAGE = "msg-go-next-page";
069:
070: protected static final String STATE_GO_PREV_PAGE = "msg-go-prev-page";
071:
072: protected static final String STATE_GO_NEXT = "msg-go-next";
073:
074: protected static final String STATE_GO_PREV = "msg-go-prev";
075:
076: protected static final String STATE_NEXT_EXISTS = "msg-next";
077:
078: protected static final String STATE_PREV_EXISTS = "msg-prev";
079:
080: protected static final String STATE_GO_FIRST_PAGE = "msg-go-first-page";
081:
082: protected static final String STATE_GO_LAST_PAGE = "msg-go-last-page";
083:
084: protected static final String STATE_SEARCH = "search";
085:
086: protected static final String STATE_MANUAL_REFRESH = "manual";
087:
088: /** Form fields. */
089: protected static final String FORM_SEARCH = "search";
090:
091: // for navigation to a certain page
092: protected static final String STATE_TOTAL_PAGENUMBER = "total_page_number";
093:
094: protected static final String STATE_CURRENT_PAGE = "current-page";
095:
096: protected static final String FORM_PAGE_NUMBER = "page_number";
097:
098: protected static final String STATE_GOTO_PAGE = "goto-page";
099:
100: protected final static int[] PAGESIZES = { 5, 10, 20, 50, 100, 200 };
101:
102: /**
103: * Implement this to return a list of all the resources in this record range, with search and sorting applied.
104: *
105: * @param first
106: * The first record to include (1 based).
107: * @param last
108: * The last record to include (inclusive, 1 based).
109: */
110: protected abstract List readResourcesPage(SessionState state,
111: int first, int last);
112:
113: /**
114: * Implement this to return the number of records that are currently selected.
115: */
116: protected abstract int sizeResources(SessionState state);
117:
118: /**
119: * Return the total page number
120: */
121: protected int totalPageNumber(SessionState state) {
122: return ((Integer) state.getAttribute(STATE_TOTAL_PAGENUMBER))
123: .intValue();
124:
125: } // totalPageNumber
126:
127: /**
128: * Populate the state object, if needed, concerning paging
129: */
130: protected void initState(SessionState state,
131: VelocityPortlet portlet, JetspeedRunData rundata) {
132: super .initState(state, portlet, rundata);
133:
134: if (state.getAttribute(STATE_PAGESIZE) == null) {
135: state.setAttribute(STATE_PAGESIZE, new Integer(
136: DEFAULT_PAGE_SIZE));
137: PortletConfig config = portlet.getPortletConfig();
138:
139: try {
140: Integer size = new Integer(config
141: .getInitParameter(PARAM_PAGESIZE));
142: if (size.intValue() <= 0) {
143: size = new Integer(DEFAULT_PAGE_SIZE);
144: if (Log.getLogger("chef").isDebugEnabled())
145: Log
146: .debug(
147: "chef",
148: this
149: + ".initState: size parameter invalid: "
150: + config
151: .getInitParameter(PARAM_PAGESIZE));
152: }
153: state.setAttribute(STATE_PAGESIZE, size);
154: } catch (Exception any) {
155: if (Log.getLogger("chef").isDebugEnabled())
156: Log.debug("chef", this
157: + ".initState: size parameter invalid: "
158: + any.toString());
159: state.setAttribute(STATE_PAGESIZE, new Integer(
160: DEFAULT_PAGE_SIZE));
161: }
162: }
163:
164: if (state.getAttribute(STATE_CURRENT_PAGE) == null) {
165: state.setAttribute(STATE_CURRENT_PAGE, new Integer(1));
166: }
167:
168: if (state.getAttribute(STATE_TOTAL_PAGENUMBER) == null) {
169: state.setAttribute(STATE_TOTAL_PAGENUMBER, new Integer(1));
170: }
171: // ** From NewPageResourceAction -->
172:
173: } // initState
174:
175: /**
176: * Add the menus for a view mode for paging.
177: */
178: protected void addViewPagingMenus(Menu bar, SessionState state) {
179: bar.add(new MenuEntry(rb_praII.getString("viepag.prev"), (state
180: .getAttribute(STATE_PREV_EXISTS) != null),
181: "doView_prev"));
182: bar.add(new MenuEntry(rb_praII.getString("viepag.next"), (state
183: .getAttribute(STATE_NEXT_EXISTS) != null),
184: "doView_next"));
185:
186: } // addViewPagingMenus
187:
188: /**
189: * Add the menus for a list mode for paging.
190: */
191: protected void addListPagingMenus(Menu bar, SessionState state) {
192: bar.add(new MenuEntry(rb_praII.getString("lispag.first"),
193: (state.getAttribute(STATE_PREV_PAGE_EXISTS) != null),
194: "doList_first"));
195: bar.add(new MenuEntry(rb_praII.getString("lispag.prev"), (state
196: .getAttribute(STATE_PREV_PAGE_EXISTS) != null),
197: "doList_prev"));
198: bar.add(new MenuEntry(rb_praII.getString("lispag.next"), (state
199: .getAttribute(STATE_NEXT_PAGE_EXISTS) != null),
200: "doList_next"));
201: bar.add(new MenuEntry(rb_praII.getString("lispag.last"), (state
202: .getAttribute(STATE_NEXT_PAGE_EXISTS) != null),
203: "doList_last"));
204:
205: } // addListPagingMenus
206:
207: /**
208: * Add the menus for search.
209: */
210: protected void addSearchMenus(Menu bar, SessionState state) {
211: bar.add(new MenuDivider());
212: bar.add(new MenuField(FORM_SEARCH, "toolbar", "doSearch",
213: (String) state.getAttribute(STATE_SEARCH)));
214: bar.add(new MenuEntry(rb_praII.getString("sea.sea"), null,
215: true, MenuItem.CHECKED_NA, "doSearch", "toolbar"));
216: if (state.getAttribute(STATE_SEARCH) != null) {
217: bar.add(new MenuEntry(rb_praII.getString("sea.cleasea"),
218: "doSearch_clear"));
219: }
220:
221: } // addSearchMenus
222:
223: /**
224: * Add the menus for manual / auto - refresh.
225: */
226: protected void addRefreshMenus(Menu bar, SessionState state) {
227: // only offer if there's an observer
228: ObservingCourier observer = (ObservingCourier) state
229: .getAttribute(STATE_OBSERVER);
230: if (observer == null)
231: return;
232:
233: bar.add(new MenuDivider());
234: bar.add(new MenuEntry((observer.getEnabled() ? rb_praII
235: .getString("ref.manref") : rb_praII
236: .getString("ref.autoref")), "doAuto"));
237: if (!observer.getEnabled()) {
238: bar.add(new MenuEntry(rb_praII.getString("ref.refresh"),
239: "doRefresh"));
240: }
241:
242: } // addRefreshMenus
243:
244: /**
245: * Prepare the current page of messages to display.
246: *
247: * @return List of MailArchiveMessage to display on this page.
248: */
249: protected List prepPage(SessionState state) {
250: // access the page size
251: int pageSize = ((Integer) state.getAttribute(STATE_PAGESIZE))
252: .intValue();
253:
254: // cleanup prior prep
255: state.removeAttribute(STATE_NUM_MESSAGES);
256:
257: // are we going next or prev, first or last page?
258: boolean goNextPage = state.getAttribute(STATE_GO_NEXT_PAGE) != null;
259: boolean goPrevPage = state.getAttribute(STATE_GO_PREV_PAGE) != null;
260: boolean goFirstPage = state.getAttribute(STATE_GO_FIRST_PAGE) != null;
261: boolean goLastPage = state.getAttribute(STATE_GO_LAST_PAGE) != null;
262: state.removeAttribute(STATE_GO_NEXT_PAGE);
263: state.removeAttribute(STATE_GO_PREV_PAGE);
264: state.removeAttribute(STATE_GO_FIRST_PAGE);
265: state.removeAttribute(STATE_GO_LAST_PAGE);
266:
267: // are we going next or prev message?
268: boolean goNext = state.getAttribute(STATE_GO_NEXT) != null;
269: boolean goPrev = state.getAttribute(STATE_GO_PREV) != null;
270: state.removeAttribute(STATE_GO_NEXT);
271: state.removeAttribute(STATE_GO_PREV);
272:
273: boolean goViewPage = state.getAttribute(STATE_GOTO_PAGE) != null;
274:
275: // if we have no prev page and do have a top message, then we will stay "pined" to the top
276: boolean pinToTop = ((state.getAttribute(STATE_TOP_PAGE_MESSAGE) != null)
277: && (state.getAttribute(STATE_PREV_PAGE_EXISTS) == null)
278: && !goNextPage
279: && !goPrevPage
280: && !goNext
281: && !goPrev
282: && !goFirstPage && !goLastPage && !goViewPage);
283:
284: // how many messages, total
285: int numMessages = sizeResources(state);
286:
287: if (numMessages == 0) {
288: return new Vector();
289: }
290:
291: // set the total page number
292: int totalPageNumber = 1;
293: if ((numMessages % pageSize) > 0) {
294: totalPageNumber = numMessages / pageSize + 1;
295: } else {
296: totalPageNumber = numMessages / pageSize;
297: }
298: state.setAttribute(STATE_TOTAL_PAGENUMBER, new Integer(
299: totalPageNumber));
300:
301: // save the number of messges
302: state
303: .setAttribute(STATE_NUM_MESSAGES, new Integer(
304: numMessages));
305:
306: // find the position of the message that is the top first on the page
307: int posStart = 0;
308: Integer topPageMessage = (Integer) state
309: .getAttribute(STATE_TOP_PAGE_MESSAGE);
310: if (topPageMessage != null) {
311: posStart = topPageMessage.intValue();
312: }
313:
314: // if going to a certain page
315: if (state.getAttribute(STATE_GOTO_PAGE) != null) {
316: int gotoPage = ((Integer) state
317: .getAttribute(STATE_GOTO_PAGE)).intValue();
318: int currentPage = ((Integer) state
319: .getAttribute(STATE_CURRENT_PAGE)).intValue();
320: posStart += pageSize * (gotoPage - currentPage);
321: }
322:
323: // if going to the next page, adjust
324: else if (goNextPage) {
325: posStart += pageSize;
326: }
327:
328: // if going to the prev page, adjust
329: else if (goPrevPage) {
330: posStart -= pageSize;
331: if (posStart < 0)
332: posStart = 0;
333: }
334:
335: // if going to the first page, adjust
336: else if (goFirstPage) {
337: posStart = 0;
338: }
339:
340: // if going to the last page, adjust
341: else if (goLastPage) {
342: posStart = numMessages - pageSize;
343: if (posStart < 0)
344: posStart = 0;
345: }
346:
347: // pinning
348: if (pinToTop) {
349: posStart = 0;
350: }
351:
352: // compute the end to a page size, adjusted for the number of messages available
353: int posEnd = posStart + (pageSize - 1);
354: if (posEnd >= numMessages)
355: posEnd = numMessages - 1;
356: int numMessagesOnThisPage = (posEnd - posStart) + 1;
357:
358: // select the messages on this page
359: List messagePage = readResourcesPage(state, posStart + 1,
360: posEnd + 1);
361:
362: // save which message is at the top of the page
363: state.setAttribute(STATE_TOP_PAGE_MESSAGE,
364: new Integer(posStart));
365:
366: // which message starts the next page (if any)
367: int next = posStart + pageSize;
368: if (next < numMessages) {
369: state.setAttribute(STATE_NEXT_PAGE_EXISTS, "");
370: } else {
371: state.removeAttribute(STATE_NEXT_PAGE_EXISTS);
372: }
373:
374: // which message ends the prior page (if any)
375: int prev = posStart - 1;
376: if (prev >= 0) {
377: state.setAttribute(STATE_PREV_PAGE_EXISTS, "");
378: } else {
379: state.removeAttribute(STATE_PREV_PAGE_EXISTS);
380: }
381:
382: state.removeAttribute(STATE_FIRST_PAGE_EXISTS);
383: state.removeAttribute(STATE_LAST_PAGE_EXISTS);
384: if (totalPageNumber != 1) {
385: if (posStart > 0) {
386: state.setAttribute(STATE_FIRST_PAGE_EXISTS, "");
387: }
388: if (posStart + pageSize < numMessages) {
389: state.setAttribute(STATE_LAST_PAGE_EXISTS, "");
390: }
391: }
392:
393: if (state.getAttribute(STATE_VIEW_ID) != null) {
394: int viewPos = ((Integer) state.getAttribute(STATE_VIEW_ID))
395: .intValue();
396:
397: // are we moving to the next message
398: if (goNext) {
399: // advance
400: viewPos++;
401: if (viewPos >= numMessages)
402: viewPos = numMessages - 1;
403: }
404:
405: // are we moving to the prev message
406: if (goPrev) {
407: // retreat
408: viewPos--;
409: if (viewPos < 0)
410: viewPos = 0;
411: }
412:
413: // update the view message
414: state.setAttribute(STATE_VIEW_ID, new Integer(viewPos));
415:
416: // if the view message is no longer on the current page, adjust the page
417: // Note: next time through this will get processed
418: if (viewPos < posStart) {
419: state.setAttribute(STATE_GO_PREV_PAGE, "");
420: } else if (viewPos > posEnd) {
421: state.setAttribute(STATE_GO_NEXT_PAGE, "");
422: }
423:
424: if (viewPos > 0) {
425: state.setAttribute(STATE_PREV_EXISTS, "");
426: } else {
427: state.removeAttribute(STATE_PREV_EXISTS);
428: }
429:
430: if (viewPos < numMessages - 1) {
431: state.setAttribute(STATE_NEXT_EXISTS, "");
432: } else {
433: state.removeAttribute(STATE_NEXT_EXISTS);
434: }
435: }
436:
437: if (state.getAttribute(STATE_GOTO_PAGE) != null) {
438: state.setAttribute(STATE_CURRENT_PAGE, state
439: .getAttribute(STATE_GOTO_PAGE));
440: state.removeAttribute(STATE_GOTO_PAGE);
441: }
442:
443: return messagePage;
444:
445: } // prepPage
446:
447: /**
448: * Handle a request to change the page size of search list.
449: */
450: public void doChange_pagesize(RunData data, Context context) {
451: SessionState state = ((JetspeedRunData) data)
452: .getPortletSessionState(((JetspeedRunData) data)
453: .getJs_peid());
454:
455: String newPageSize = data.getParameters().getString(
456: "selectPageSize");
457: if (newPageSize == null) {
458: state.setAttribute(STATE_PAGESIZE, new Integer(
459: DEFAULT_PAGE_SIZE));
460: state.setAttribute("inter_size", new Integer(
461: DEFAULT_PAGE_SIZE));
462: } else {
463: state.setAttribute(STATE_PAGESIZE, Integer
464: .valueOf(newPageSize));
465: state.setAttribute("inter_size", Integer
466: .valueOf(newPageSize));
467: }
468: } // doChange_pagesize
469:
470: public void pagingInfoToContext(SessionState state, Context context) {
471: if (state.getAttribute(STATE_NUM_MESSAGES) != null) {
472: context.put("allMsgNumber", state.getAttribute(
473: STATE_NUM_MESSAGES).toString());
474: context.put("allMsgNumberInt", state
475: .getAttribute(STATE_NUM_MESSAGES));
476: }
477:
478: // find the position of the message that is the top first on the page
479: if ((state.getAttribute(STATE_TOP_PAGE_MESSAGE) != null)
480: && (state.getAttribute(STATE_PAGESIZE) != null)) {
481: int topMsgPos = ((Integer) state
482: .getAttribute(STATE_TOP_PAGE_MESSAGE)).intValue() + 1;
483: context.put("topMsgPos", Integer.toString(topMsgPos));
484: int btmMsgPos = topMsgPos
485: + ((Integer) state.getAttribute(STATE_PAGESIZE))
486: .intValue() - 1;
487: if (state.getAttribute(STATE_NUM_MESSAGES) != null) {
488: int allMsgNumber = ((Integer) state
489: .getAttribute(STATE_NUM_MESSAGES)).intValue();
490: if (btmMsgPos > allMsgNumber)
491: btmMsgPos = allMsgNumber;
492: }
493: context.put("btmMsgPos", Integer.toString(btmMsgPos));
494: }
495:
496: boolean goPPButton = state.getAttribute(STATE_PREV_PAGE_EXISTS) != null;
497: context.put("goPPButton", Boolean.toString(goPPButton));
498: boolean goNPButton = state.getAttribute(STATE_NEXT_PAGE_EXISTS) != null;
499: context.put("goNPButton", Boolean.toString(goNPButton));
500:
501: boolean goFPButton = state
502: .getAttribute(STATE_FIRST_PAGE_EXISTS) != null;
503: context.put("goFPButton", Boolean.toString(goFPButton));
504: boolean goLPButton = state.getAttribute(STATE_LAST_PAGE_EXISTS) != null;
505: context.put("goLPButton", Boolean.toString(goLPButton));
506:
507: context.put("pagesize", state.getAttribute(STATE_PAGESIZE));
508: context.put("pagesizes", PAGESIZES);
509:
510: } // pagingInfoToContext
511:
512: /**
513: * Clean up all state value for paging.
514: */
515: public void cleanStatePaging(SessionState state) {
516: state.removeAttribute("inter_size");
517: state.removeAttribute(STATE_NUM_MESSAGES);
518: state.removeAttribute(STATE_TOP_PAGE_MESSAGE);
519: state.removeAttribute(STATE_NEXT_PAGE_EXISTS);
520: state.removeAttribute(STATE_PREV_PAGE_EXISTS);
521:
522: } // cleanState
523:
524: /**
525: * Handle a view indecated page request
526: */
527: public void doView_page(RunData runData, Context context) {
528: // access the portlet element id to find our state
529: String peid = ((JetspeedRunData) runData).getJs_peid();
530: SessionState state = ((JetspeedRunData) runData)
531: .getPortletSessionState(peid);
532:
533: // set the flag to go to the next item on the next view
534: String page = runData.getParameters().getString(
535: FORM_PAGE_NUMBER);
536: state.setAttribute(STATE_GOTO_PAGE, new Integer(page));
537:
538: } // doView_page
539:
540: /**
541: * Handle a next-message (view) request.
542: */
543: public void doView_next(RunData runData, Context context) {
544: // access the portlet element id to find our state
545: String peid = ((JetspeedRunData) runData).getJs_peid();
546: SessionState state = ((JetspeedRunData) runData)
547: .getPortletSessionState(peid);
548:
549: // set the flag to go to the next message on the next view
550: state.setAttribute(STATE_GO_NEXT, "");
551:
552: // set the page number
553: int page = ((Integer) state.getAttribute(STATE_CURRENT_PAGE))
554: .intValue();
555: state.setAttribute(STATE_CURRENT_PAGE, new Integer(page + 1));
556:
557: } // doView_next
558:
559: /**
560: * Handle a first-message page (list) request.
561: */
562: public void doList_first(RunData runData, Context context) {
563: // access the portlet element id to find our state
564: String peid = ((JetspeedRunData) runData).getJs_peid();
565: SessionState state = ((JetspeedRunData) runData)
566: .getPortletSessionState(peid);
567:
568: // set the flag to go to the next message on the next view
569: state.setAttribute(STATE_GO_FIRST_PAGE, "");
570:
571: // set the page number
572: state.setAttribute(STATE_CURRENT_PAGE, new Integer(1));
573:
574: } // doList_first
575:
576: /**
577: * Handle a last-message page (list) request.
578: */
579: public void doList_last(RunData runData, Context context) {
580: // access the portlet element id to find our state
581: String peid = ((JetspeedRunData) runData).getJs_peid();
582: SessionState state = ((JetspeedRunData) runData)
583: .getPortletSessionState(peid);
584:
585: // set the flag to go to the next message on the next view
586: state.setAttribute(STATE_GO_LAST_PAGE, "");
587:
588: // set the page number
589: state.setAttribute(STATE_CURRENT_PAGE, new Integer(
590: totalPageNumber(state)));
591:
592: } // doList_last
593:
594: /**
595: * Handle a next-page (list) request.
596: */
597: public void doList_next(RunData runData, Context context) {
598: // access the portlet element id to find our state
599: String peid = ((JetspeedRunData) runData).getJs_peid();
600: SessionState state = ((JetspeedRunData) runData)
601: .getPortletSessionState(peid);
602:
603: // set the flag to go to the next page on the next list
604: state.setAttribute(STATE_GO_NEXT_PAGE, "");
605:
606: // %%% ?? doList(runData, context);
607:
608: // set the page number
609: int page = ((Integer) state.getAttribute(STATE_CURRENT_PAGE))
610: .intValue();
611: state.setAttribute(STATE_CURRENT_PAGE, new Integer(page + 1));
612:
613: } // doList_next
614:
615: /**
616: * Handle a prev-message (view) request.
617: */
618: public void doView_prev(RunData runData, Context context) {
619: // access the portlet element id to find our state
620: String peid = ((JetspeedRunData) runData).getJs_peid();
621: SessionState state = ((JetspeedRunData) runData)
622: .getPortletSessionState(peid);
623:
624: // set the flag to go to the prev message on the next view
625: state.setAttribute(STATE_GO_PREV, "");
626:
627: // set the page number
628: int page = ((Integer) state.getAttribute(STATE_CURRENT_PAGE))
629: .intValue();
630: state.setAttribute(STATE_CURRENT_PAGE, new Integer(page - 1));
631:
632: } // doView_prev
633:
634: /**
635: * Handle a prev-page (list) request.
636: */
637: public void doList_prev(RunData runData, Context context) {
638: // access the portlet element id to find our state
639: String peid = ((JetspeedRunData) runData).getJs_peid();
640: SessionState state = ((JetspeedRunData) runData)
641: .getPortletSessionState(peid);
642:
643: // set the flag to go to the prev page on the next list
644: state.setAttribute(STATE_GO_PREV_PAGE, "");
645:
646: // set the page number
647: int page = ((Integer) state.getAttribute(STATE_CURRENT_PAGE))
648: .intValue();
649: state.setAttribute(STATE_CURRENT_PAGE, new Integer(page - 1));
650:
651: } // doList_prev
652:
653: /**
654: * Handle a Search request.
655: */
656: public void doSearch(RunData runData, Context context) {
657: // access the portlet element id to find our state
658: String peid = ((JetspeedRunData) runData).getJs_peid();
659: SessionState state = ((JetspeedRunData) runData)
660: .getPortletSessionState(peid);
661:
662: // read the search form field into the state object
663: String search = StringUtil.trimToNull(runData.getParameters()
664: .getString(FORM_SEARCH));
665:
666: // set the flag to go to the prev page on the next list
667: if (search == null) {
668: state.removeAttribute(STATE_SEARCH);
669: } else {
670: state.setAttribute(STATE_SEARCH, search);
671: }
672:
673: // start paging again from the top of the list
674: resetPaging(state);
675:
676: // if we are searching, turn off auto refresh
677: if (search != null) {
678: ObservingCourier observer = (ObservingCourier) state
679: .getAttribute(STATE_OBSERVER);
680: if (observer != null) {
681: observer.disable();
682: }
683: }
684:
685: // else turn it back on
686: else {
687: enableObserver(state);
688: }
689:
690: } // doSearch
691:
692: /**
693: * Handle a Search Clear request.
694: */
695: public void doSearch_clear(RunData runData, Context context) {
696: // access the portlet element id to find our state
697: String peid = ((JetspeedRunData) runData).getJs_peid();
698: SessionState state = ((JetspeedRunData) runData)
699: .getPortletSessionState(peid);
700:
701: // clear the search
702: state.removeAttribute(STATE_SEARCH);
703:
704: // start paging again from the top of the list
705: resetPaging(state);
706:
707: // turn on auto refresh
708: enableObserver(state);
709:
710: } // doSearch_clear
711:
712: /**
713: * Reset to the first page
714: */
715: protected void resetPaging(SessionState state) {
716: // we are changing the sort, so start from the first page again
717: state.removeAttribute(STATE_TOP_PAGE_MESSAGE);
718:
719: state.setAttribute(STATE_CURRENT_PAGE, new Integer(1));
720:
721: } // resetPaging
722:
723: /**
724: * Toggle auto-update
725: */
726: public void doAuto(RunData data, Context context) {
727: // access the portlet element id to find our state
728: String peid = ((JetspeedRunData) data).getJs_peid();
729: SessionState state = ((JetspeedRunData) data)
730: .getPortletSessionState(peid);
731:
732: // get the observer
733: ObservingCourier observer = (ObservingCourier) state
734: .getAttribute(STATE_OBSERVER);
735: if (observer != null) {
736: boolean enabled = observer.getEnabled();
737: if (enabled) {
738: observer.disable();
739: state.setAttribute(STATE_MANUAL_REFRESH, "manual");
740: } else {
741: observer.enable();
742: state.removeAttribute(STATE_MANUAL_REFRESH);
743: }
744: }
745:
746: } // doAuto
747:
748: /**
749: * The action for when the user want's an update
750: */
751: public void doRefresh(RunData data, Context context) {
752: // access the portlet element id to find our state
753: String peid = ((JetspeedRunData) data).getJs_peid();
754: SessionState state = ((JetspeedRunData) data)
755: .getPortletSessionState(peid);
756:
757: } // doRefresh
758:
759: /**
760: * Enable the observer, unless we are in search mode, where we want it disabled.
761: */
762: public void enableObserver(SessionState state) {
763: // get the observer
764: ObservingCourier observer = (ObservingCourier) state
765: .getAttribute(STATE_OBSERVER);
766: if (observer != null) {
767: // we leave it disabled if we are searching, or if the user has last selected to be manual
768: if ((state.getAttribute(STATE_SEARCH) != null)
769: || (state.getAttribute(STATE_MANUAL_REFRESH) != null)) {
770: observer.disable();
771: } else {
772: observer.enable();
773: }
774: }
775:
776: } // enableObserver
777:
778: } // PagedResourceAction
|