001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/message/tags/sakai_2-4-1/message-tool/tool/src/java/org/sakaiproject/message/tool/SynopticMessageAction.java $
003: * $Id: SynopticMessageAction.java 22615 2007-03-14 19:53:58Z chmaurer@iupui.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.message.tool;
021:
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Vector;
025:
026: import org.sakaiproject.cheftool.Context;
027: import org.sakaiproject.cheftool.JetspeedRunData;
028: import org.sakaiproject.cheftool.PortletConfig;
029: import org.sakaiproject.cheftool.RunData;
030: import org.sakaiproject.cheftool.VelocityPortlet;
031: import org.sakaiproject.cheftool.VelocityPortletPaneledAction;
032: import org.sakaiproject.cheftool.api.Menu;
033: import org.sakaiproject.cheftool.menu.MenuImpl;
034: import org.sakaiproject.component.cover.ComponentManager;
035: import org.sakaiproject.content.cover.ContentTypeImageService;
036: import org.sakaiproject.event.api.SessionState;
037: import org.sakaiproject.exception.PermissionException;
038: import org.sakaiproject.message.api.MessageService;
039: import org.sakaiproject.site.cover.SiteService;
040: import org.sakaiproject.time.api.Time;
041: import org.sakaiproject.time.cover.TimeService;
042: import org.sakaiproject.tool.api.Placement;
043: import org.sakaiproject.tool.api.Tool;
044: import org.sakaiproject.tool.cover.ToolManager;
045: import org.sakaiproject.util.ResourceLoader;
046: import org.sakaiproject.util.StringUtil;
047:
048: /**
049: * <p>
050: * SynopticMessageAction is a the Sakai synopsis tool for messages (chat, announcement, discussion).
051: * </p>
052: */
053: public class SynopticMessageAction extends VelocityPortletPaneledAction {
054:
055: private static ResourceLoader rb = new ResourceLoader("recent");
056:
057: /** portlet configuration parameter names. */
058: private static final String PARAM_CHANNEL = "channel";
059:
060: private static final String PARAM_DAYS = "days";
061:
062: private static final String PARAM_ITEMS = "items";
063:
064: private static final String PARAM_LENGTH = "length";
065:
066: private static final String PARAM_SHOW_BODY = "show-body";
067:
068: private static final String PARAM_SHOW_NEWLINES = "show-newlines";
069:
070: private static final String PARAM_SERVICE = "message-service";
071:
072: private static final String PARAM_SHOW_SUBJECT = "show-subject";
073:
074: /** Configure form field names. */
075: private static final String FORM_CHANNEL = "channel";
076:
077: private static final String FORM_DAYS = "days";
078:
079: private static final String FORM_ITEMS = "items";
080:
081: private static final String FORM_LENGTH = "length";
082:
083: private static final String FORM_SHOW_BODY = "show-body";
084:
085: private static final String FORM_SHOW_SUBJECT = "show-subject";
086:
087: /** Control form field names. */
088: private static final String FORM_MESSAGE = "message";
089:
090: /** state attribute names. */
091: private static final String STATE_CHANNEL_REF = "channelId";
092:
093: private static final String STATE_ERROR = "error";
094:
095: private static final String STATE_SERVICE = "service";
096:
097: private static final String STATE_SERVICE_NAME = "service-name";
098:
099: private static final String STATE_UPDATE = "update";
100:
101: private static final String STATE_CHANNEL_PROBLEM = "channel-problem";
102:
103: private static final String STATE_DAYS = "days";
104:
105: private static final String STATE_AFTER_DATE = "afterdate";
106:
107: private static final String STATE_ITEMS = "items";
108:
109: private static final String STATE_LENGTH = "length";
110:
111: private static final String STATE_SHOW_BODY = "show-body";
112:
113: private static final String STATE_SHOW_SUBJECT = "show-subject";
114:
115: private static final String STATE_SHOW_NEWLINES = "show-newlines";
116:
117: private static final String STATE_SUBJECT_OPTION = "allow-option-of-showing-subject";
118:
119: /**
120: * Populate the state object, if needed - override to do something!
121: */
122: protected void initState(SessionState state,
123: VelocityPortlet portlet, JetspeedRunData rundata) {
124: super .initState(state, portlet, rundata);
125:
126: if (state.getAttribute(STATE_CHANNEL_REF) == null) {
127: PortletConfig config = portlet.getPortletConfig();
128:
129: MessageService service = (MessageService) state
130: .getAttribute(STATE_SERVICE);
131: if (service == null) {
132: // which message service?
133: String serviceName = config
134: .getInitParameter(PARAM_SERVICE);
135:
136: // deal with old CHEF 1.2.10 settings
137: if (serviceName.startsWith("org.chefproject")) {
138: // get the registered setting, ignoring the placement
139: serviceName = config
140: .get3InitParameter(PARAM_SERVICE)[1];
141: }
142:
143: state.setAttribute(STATE_SERVICE_NAME, serviceName);
144:
145: service = getMessageService(serviceName);
146: state.setAttribute(STATE_SERVICE, service);
147: }
148:
149: // read the channel from configuration, or, if not specified, use the default for the page
150: String channel = StringUtil.trimToNull(config
151: .getInitParameter(PARAM_CHANNEL));
152: if (channel == null) {
153: channel = service.channelReference(ToolManager
154: .getCurrentPlacement().getContext(),
155: SiteService.MAIN_CONTAINER);
156: }
157: state.setAttribute(STATE_CHANNEL_REF, channel);
158:
159: // read the days parameter
160: if (state.getAttribute(STATE_DAYS) == null) {
161: int days = 10;
162: try {
163: days = Integer.parseInt(config
164: .getInitParameter(PARAM_DAYS));
165: } catch (Exception e) {
166: }
167:
168: state.setAttribute(STATE_DAYS, new Integer(days));
169:
170: long startTime = System.currentTimeMillis()
171: - ((long) days * 24l * 60l * 60l * 1000l);
172: state.setAttribute(STATE_AFTER_DATE, TimeService
173: .newTime(startTime));
174: }
175:
176: // read the items parameter
177: if (state.getAttribute(STATE_ITEMS) == null) {
178: try {
179: state.setAttribute(STATE_ITEMS, new Integer(config
180: .getInitParameter(PARAM_ITEMS)));
181: } catch (Exception e) {
182: // use a default value
183: state.setAttribute(STATE_ITEMS, new Integer(3));
184: }
185: }
186:
187: // read the length parameter
188: if (state.getAttribute(STATE_LENGTH) == null) {
189: try {
190: state.setAttribute(STATE_LENGTH, new Integer(config
191: .getInitParameter(PARAM_LENGTH)));
192: } catch (Exception e) {
193: // use a default value
194: state.setAttribute(STATE_LENGTH, new Integer(50));
195: }
196: }
197:
198: // read the show-subject parameter
199: if (state.getAttribute(STATE_SHOW_SUBJECT) == null) {
200: try {
201: state
202: .setAttribute(
203: STATE_SHOW_SUBJECT,
204: new Boolean(
205: config
206: .getInitParameter(PARAM_SHOW_SUBJECT)));
207: } catch (Exception e) {
208: // use a default value
209: state.setAttribute(STATE_SHOW_SUBJECT, new Boolean(
210: false));
211: }
212: }
213:
214: // read the show-body parameter
215: if (state.getAttribute(STATE_SHOW_BODY) == null) {
216: try {
217: state.setAttribute(STATE_SHOW_BODY, new Boolean(
218: config.getInitParameter(PARAM_SHOW_BODY)));
219: } catch (Exception e) {
220: // use a default value
221: state.setAttribute(STATE_SHOW_BODY, new Boolean(
222: false));
223: }
224: }
225:
226: // read the show-newlines parameter
227: if (state.getAttribute(STATE_SHOW_NEWLINES) == null) {
228: try {
229: state
230: .setAttribute(
231: STATE_SHOW_NEWLINES,
232: new Boolean(
233: config
234: .getInitParameter(PARAM_SHOW_NEWLINES)));
235: } catch (Exception e) {
236: // use a default value
237: state.setAttribute(STATE_SHOW_NEWLINES,
238: new Boolean(false));
239: }
240: }
241:
242: // // setup the observer to notify our main panel
243: // if (state.getAttribute(STATE_OBSERVER) == null)
244: // {
245: // // the delivery location for this tool
246: // String deliveryId = clientWindowId(state, portlet.getID());
247: //
248: // // the html element to update on delivery
249: // String elementId = mainPanelUpdateId(portlet.getID());
250: //
251: // // the event resource reference pattern to watch for
252: // Reference r = new Reference(channel);
253: // String pattern = service.messageReference(r.getContext(), r.getId(), "");
254: //
255: // state.setAttribute(STATE_OBSERVER, new EventObservingCourier(deliveryId, elementId, pattern));
256: // }
257: }
258:
259: } // initState
260:
261: /**
262: * build the context for the Main panel
263: *
264: * @return (optional) template name for this panel
265: */
266: public String buildMainPanelContext(VelocityPortlet portlet,
267: Context context, RunData rundata, SessionState state) {
268:
269: context.put("tlang", rb);
270:
271: context.put("contentTypeImageService", ContentTypeImageService
272: .getInstance());
273:
274: // if the synoptic options have just been imported, we need to update
275: // the state
276: if (state.getAttribute(STATE_UPDATE) != null) {
277: updateState(state, portlet);
278: state.removeAttribute(STATE_UPDATE);
279: }
280:
281: // // TODO: TIMING
282: // if (CurrentService.getInThread("DEBUG") == null)
283: // CurrentService.setInThread("DEBUG", new StringBuffer());
284: // long startTime = System.currentTimeMillis();
285:
286: // different title of Option link for different tools.
287: Tool tool = ToolManager.getCurrentTool();
288: context.put("toolId", tool.getId());
289:
290: // handle options mode
291: if (MODE_OPTIONS.equals(state.getAttribute(STATE_MODE))) {
292: return buildOptionsPanelContext(portlet, context, rundata,
293: state);
294: }
295:
296: // build the menu
297: Menu bar = new MenuImpl(portlet, rundata, (String) state
298: .getAttribute(STATE_ACTION));
299:
300: // add options if allowed
301: addOptionsMenu(bar, (JetspeedRunData) rundata);
302: if (!bar.getItems().isEmpty()) {
303: context.put(Menu.CONTEXT_MENU, bar);
304: }
305:
306: context.put(Menu.CONTEXT_ACTION, state
307: .getAttribute(STATE_ACTION));
308:
309: // set the message length (leave as an Integer)
310: context.put("length", state.getAttribute(STATE_LENGTH));
311:
312: // set useSubject - true to display the message subject (else use the body)
313: context.put("showSubject", state
314: .getAttribute(STATE_SHOW_SUBJECT));
315:
316: // set showBody - true to display the message body
317: // message subject is always displayed for recent discussion tool - handled by vm
318: context.put("showBody", state.getAttribute(STATE_SHOW_BODY));
319:
320: // whether to show newlines in the message body, or not
321: context.put("show_newlines", ((Boolean) state
322: .getAttribute(STATE_SHOW_NEWLINES)).toString());
323:
324: try {
325: MessageService service = (MessageService) state
326: .getAttribute(STATE_SERVICE);
327: String channelRef = (String) state
328: .getAttribute(STATE_CHANNEL_REF);
329: Time afterDate = (Time) state
330: .getAttribute(STATE_AFTER_DATE);
331: int items = ((Integer) state.getAttribute(STATE_ITEMS))
332: .intValue();
333:
334: List messages = new Vector();
335: String serviceName = (String) state
336: .getAttribute(STATE_SERVICE_NAME);
337: if (serviceName != null
338: && serviceName
339: .equals("org.sakaiproject.discussion.api.DiscussionService")) {
340: // showing the draft messages of discussion
341: messages = service.getMessages(channelRef, afterDate,
342: items, false, true, false);
343: } else {
344: messages = service.getMessages(channelRef, afterDate,
345: items, false, false, false);
346: }
347: context.put("messages", messages);
348: } catch (PermissionException e) {
349: addAlert(state, rb.getString("youdonot"));
350: }
351:
352: // inform the observing courier that we just updated the page...
353: // if there are pending requests to do so they can be cleared
354: justDelivered(state);
355:
356: String rv = (String) getContext(rundata).get("template")
357: + "-List";
358:
359: // // TODO: TIMING
360: // long endTime = System.currentTimeMillis();
361: // if (endTime-startTime > /*5*/000)
362: // {
363: // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
364: // if (buf != null)
365: // {
366: // buf.insert(0,"synopticMessageAction: "
367: // + state.getAttribute(STATE_CHANNEL_REF)
368: // + " time: " + (endTime - startTime));
369: // }
370: // }
371:
372: return rv;
373:
374: } // buildMainPanelContext
375:
376: /**
377: * Setup for the options panel.
378: */
379: public String buildOptionsPanelContext(VelocityPortlet portlet,
380: Context context, RunData rundata, SessionState state) {
381: context.put("tlang", rb);
382: String serviceName = (String) state
383: .getAttribute(STATE_SERVICE_NAME);
384: String tool_title = rb.getString("tool_title");
385: String tool_name = rb.getString("tool_name");
386: String one_item = rb.getString("one_item");
387: String all_items = rb.getString("channel_analog");
388: String channel_analog = rb.getString("channel_analog");
389: Boolean allow_show_subject = new Boolean(true);
390: Boolean allow_channel_choice = new Boolean(false);
391:
392: if (serviceName
393: .equals("org.sakaiproject.discussion.api.DiscussionService")) {
394: tool_title = rb.getString("dtool_title");
395: tool_name = rb.getString("dtool_name");
396: one_item = rb.getString("done_item");
397: all_items = rb.getString("dall_items");
398: } else if (serviceName
399: .equals("org.sakaiproject.announcement.api.AnnouncementService")) {
400: tool_title = rb.getString("atool_title");
401: tool_name = rb.getString("atool_name");
402: one_item = rb.getString("aone_item");
403: all_items = rb.getString("aall_items");
404: }
405:
406: // provide "tool_title" as title for options page
407: context.put("tool_title", tool_title);
408:
409: // provide "tool_name" as name of the tool
410: context.put("tool_name", tool_name);
411:
412: // provide "one_item" as a reference to a single message
413: context.put("one_item", one_item);
414:
415: // provide "all_items" as a reference to all messages collectively
416: context.put("all_items", all_items);
417:
418: // provide "allow_show_subject" with the value for whether to allow user to choose between subject or body
419: context
420: .put("allow_show_subject", allow_show_subject
421: .toString());
422: if (allow_show_subject.booleanValue()) {
423: context.put("showBody", ((Boolean) state
424: .getAttribute(STATE_SHOW_BODY)).toString());
425:
426: // provide "showSubject" with the value for showing subject (true) or body (false)
427: context.put("showSubject", ((Boolean) state
428: .getAttribute(STATE_SHOW_SUBJECT)).toString());
429: }
430:
431: // provide "allow_channel_choice" with the value for whether to allow user to choose the channel
432: context.put("allow_channel_choice", allow_channel_choice
433: .toString());
434: if (allow_channel_choice.booleanValue()) {
435: // provide "channel_analog" with the word(s) used to refer to a channel, such as "Chat Room"
436: context.put("channel_analog", channel_analog);
437:
438: // provide "default_channel" with the dafault channel-id for the user/group
439: context.put("default_channel", SiteService.MAIN_CONTAINER);
440:
441: // provide "channel" with the current channel's id
442: String placementContext = ToolManager.getCurrentPlacement()
443: .getContext();
444: String defaultChannel = ((MessageService) state
445: .getAttribute(STATE_SERVICE)).channelReference(
446: placementContext, SiteService.MAIN_CONTAINER);
447: String sitePrefix = defaultChannel.substring(0,
448: defaultChannel
449: .lastIndexOf(SiteService.MAIN_CONTAINER));
450: String currentChannel = ((String) state
451: .getAttribute(STATE_CHANNEL_REF))
452: .substring(sitePrefix.length());
453: context.put("channel", currentChannel);
454:
455: // provide "channels" as a list of channels belonging to this site
456:
457: // // TODO: TIMING
458: // if (CurrentService.getInThread("DEBUG") == null)
459: // CurrentService.setInThread("DEBUG", new StringBuffer());
460: // long startTime = System.currentTimeMillis();
461:
462: Iterator aChannel = ((MessageService) state
463: .getAttribute(STATE_SERVICE)).getChannelIds(
464: placementContext).iterator();
465:
466: // // TODO: TIMING
467: // long endTime = System.currentTimeMillis();
468: // if (endTime-startTime > /*5*/000)
469: // {
470: // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
471: // if (buf != null)
472: // {
473: // buf.insert(0,"synopticMessageAction.options: "
474: // + state.getAttribute(STATE_CHANNEL_REF)
475: // + " time: " + (endTime - startTime));
476: // }
477: // }
478:
479: List channel_list = new Vector();
480: while (aChannel.hasNext()) {
481: String theChannel = (String) aChannel.next();
482: if (!theChannel.equals(SiteService.MAIN_CONTAINER)) {
483: channel_list.add(theChannel);
484: }
485: }
486: context.put("channels", channel_list);
487: }
488:
489: // provide "days" with the days value
490: context.put("days", ((Integer) state.getAttribute(STATE_DAYS))
491: .toString());
492:
493: // provide "items" with the items value
494: context.put("items",
495: ((Integer) state.getAttribute(STATE_ITEMS)).toString());
496:
497: // provide "length" with the items value
498: context.put("length", ((Integer) state
499: .getAttribute(STATE_LENGTH)).toString());
500:
501: // provide the form field names
502: context.put("channel_form", FORM_CHANNEL);
503: context.put("days_form", FORM_DAYS);
504: context.put("items_form", FORM_ITEMS);
505: context.put("length_form", FORM_LENGTH);
506: context.put("show_body_form", FORM_SHOW_BODY);
507: context.put("show_subject_form", FORM_SHOW_SUBJECT);
508:
509: // set the action for form processing
510: context.put("action", state.getAttribute(STATE_ACTION));
511: context.put("form-submit", BUTTON + "doUpdate");
512: context.put("form-cancel", BUTTON + "doCancel");
513:
514: context.put("selectedChars", state.getAttribute(STATE_LENGTH));
515:
516: // pick the "-customize" template based on the standard template name
517: String template = (String) getContext(rundata).get("template");
518: return template + "-customize";
519:
520: } // buildOptionsPanelContext
521:
522: /**
523: * doUpdate handles user clicking "Done" in Options panel (called for form input tags type="submit" named="eventSubmit_doUpdate")
524: */
525: public void doUpdate(RunData data, Context context) {
526: // access the portlet element id to find our state
527: String peid = ((JetspeedRunData) data).getJs_peid();
528: SessionState state = ((JetspeedRunData) data)
529: .getPortletSessionState(peid);
530:
531: String serviceName = (String) state
532: .getAttribute(STATE_SERVICE_NAME);
533:
534: boolean allow_show_subject = true;
535: boolean allow_channel_choice = false;
536:
537: // showSubject
538: if (allow_show_subject) {
539: if (serviceName
540: .equals("org.sakaiproject.discussion.api.DiscussionService")) {
541: // always show subject for Recent Discussion
542: String showBody = data.getParameters().getString(
543: FORM_SHOW_BODY);
544: try {
545: Boolean sb = new Boolean(showBody);
546: if (!sb.equals((Boolean) state
547: .getAttribute(STATE_SHOW_BODY))) {
548: state.setAttribute(STATE_SHOW_BODY, sb);
549: state.setAttribute(STATE_UPDATE, STATE_UPDATE);
550: }
551: } catch (Exception ignore) {
552: }
553: } else if (serviceName
554: .equals("org.sakaiproject.announcement.api.AnnouncementService")) {
555: String showSubject = data.getParameters().getString(
556: FORM_SHOW_SUBJECT);
557: try {
558: Boolean ss = new Boolean(showSubject);
559: if (!ss.equals((Boolean) state
560: .getAttribute(STATE_SHOW_SUBJECT))) {
561: state.setAttribute(STATE_SHOW_SUBJECT, ss);
562: state.setAttribute(STATE_UPDATE, STATE_UPDATE);
563: }
564: } catch (Exception ignore) {
565: }
566: }
567: }
568:
569: // channel
570: if (allow_channel_choice) {
571: String placementContext = ToolManager.getCurrentPlacement()
572: .getContext();
573: String newChannel = data.getParameters().getString(
574: FORM_CHANNEL);
575: String currentChannel = ((String) state
576: .getAttribute(STATE_CHANNEL_REF))
577: .substring(placementContext.length() + 1);
578:
579: if (newChannel != null
580: && !newChannel.equals(currentChannel)) {
581: String channel_ref = ((MessageService) state
582: .getAttribute(STATE_SERVICE)).channelReference(
583: placementContext, newChannel);
584: state.setAttribute(STATE_CHANNEL_REF, channel_ref);
585: if (Log.getLogger("chef").isDebugEnabled())
586: Log
587: .debug("chef", this
588: + ".doUpdate(): newChannel: "
589: + channel_ref);
590: // updateObservationOfChannel(state, peid);
591:
592: // update the tool config
593: Placement placement = ToolManager.getCurrentPlacement();
594: placement.getPlacementConfig().setProperty(
595: PARAM_CHANNEL,
596: (String) state.getAttribute(STATE_CHANNEL_REF));
597:
598: // deliver an update to the title panel (to show the new title)
599: String titleId = titlePanelUpdateId(peid);
600: schedulePeerFrameRefresh(titleId);
601: }
602: }
603:
604: // days
605: String daysValue = data.getParameters().getString(FORM_DAYS);
606: try {
607: Integer days = new Integer(daysValue);
608: if (!days.equals((Integer) state.getAttribute(STATE_DAYS))) {
609: state.setAttribute(STATE_DAYS, days);
610: state.setAttribute(STATE_UPDATE, STATE_UPDATE);
611:
612: // recompute this which is used for selecting the messages for display
613: long startTime = System.currentTimeMillis()
614: - (days.longValue() * 24l * 60l * 60l * 1000l);
615: state.setAttribute(STATE_AFTER_DATE, TimeService
616: .newTime(startTime));
617: }
618: } catch (Exception ignore) {
619: }
620:
621: // items
622: String itemsValue = data.getParameters().getString(FORM_ITEMS);
623: try {
624: Integer items = new Integer(itemsValue);
625: if (!items
626: .equals((Integer) state.getAttribute(STATE_ITEMS))) {
627: state.setAttribute(STATE_ITEMS, items);
628: state.setAttribute(STATE_UPDATE, STATE_UPDATE);
629: }
630: } catch (Exception ignore) {
631: }
632:
633: // length
634: String lengthValue = data.getParameters()
635: .getString(FORM_LENGTH);
636: try {
637: Integer length = new Integer(lengthValue);
638: if (!length.equals((Integer) state
639: .getAttribute(STATE_LENGTH))) {
640: state.setAttribute(STATE_LENGTH, length);
641: state.setAttribute(STATE_UPDATE, STATE_UPDATE);
642: }
643: } catch (Exception ignore) {
644: }
645:
646: // update the tool config
647: Placement placement = ToolManager.getCurrentPlacement();
648: placement.getPlacementConfig().setProperty(PARAM_CHANNEL,
649: (String) state.getAttribute(STATE_CHANNEL_REF));
650: placement.getPlacementConfig().setProperty(PARAM_DAYS,
651: ((Integer) state.getAttribute(STATE_DAYS)).toString());
652: placement.getPlacementConfig().setProperty(PARAM_ITEMS,
653: ((Integer) state.getAttribute(STATE_ITEMS)).toString());
654: placement.getPlacementConfig()
655: .setProperty(
656: PARAM_LENGTH,
657: ((Integer) state.getAttribute(STATE_LENGTH))
658: .toString());
659: placement.getPlacementConfig().setProperty(
660: PARAM_SHOW_BODY,
661: ((Boolean) state.getAttribute(STATE_SHOW_BODY))
662: .toString());
663: placement.getPlacementConfig().setProperty(
664: PARAM_SHOW_SUBJECT,
665: ((Boolean) state.getAttribute(STATE_SHOW_SUBJECT))
666: .toString());
667:
668: // commit the change
669: saveOptions();
670:
671: // we are done with customization... back to the main mode
672: state.removeAttribute(STATE_MODE);
673:
674: // enable auto-updates while in view mode
675: enableObservers(state);
676:
677: } // doUpdate
678:
679: /**
680: * doCancel handles user clicking "Cancel" in Options panel
681: */
682: public void doCancel(RunData data, Context context) {
683: // access the portlet element id to find our state
684: String peid = ((JetspeedRunData) data).getJs_peid();
685: SessionState state = ((JetspeedRunData) data)
686: .getPortletSessionState(peid);
687:
688: // we are done with customization... back to the main mode
689: state.removeAttribute(STATE_MODE);
690:
691: // cancel the options
692: cancelOptions();
693:
694: // enable auto-updates while in view mode
695: enableObservers(state);
696:
697: } // doCancel
698:
699: /**
700: * update state (synoptic tool options)
701: */
702: private void updateState(SessionState state, VelocityPortlet portlet) {
703: PortletConfig config = portlet.getPortletConfig();
704:
705: try {
706: int days = Integer.parseInt(config
707: .getInitParameter(PARAM_DAYS));
708: state.setAttribute(STATE_DAYS, new Integer(days));
709:
710: long startTime = System.currentTimeMillis()
711: - ((long) days * 24l * 60l * 60l * 1000l);
712: state.setAttribute(STATE_AFTER_DATE, TimeService
713: .newTime(startTime));
714:
715: state.setAttribute(STATE_ITEMS, new Integer(config
716: .getInitParameter(PARAM_ITEMS)));
717: state.setAttribute(STATE_LENGTH, new Integer(config
718: .getInitParameter(PARAM_LENGTH)));
719: state.setAttribute(STATE_SHOW_SUBJECT, new Boolean(config
720: .getInitParameter(PARAM_SHOW_SUBJECT)));
721: state.setAttribute(STATE_SHOW_BODY, new Boolean(config
722: .getInitParameter(PARAM_SHOW_BODY)));
723: state.setAttribute(STATE_SHOW_NEWLINES, new Boolean(config
724: .getInitParameter(PARAM_SHOW_NEWLINES)));
725: } catch (Exception e) {
726: // do not update the state if there are any errors
727: }
728: }
729:
730: /**
731: * Improves performance by returning the appropriate MessageService through the service Cover classes instead of through the ComponentManager (for certain well-known services)
732: */
733: private static final MessageService getMessageService(
734: String ifaceName) {
735: return (MessageService) ComponentManager.get(ifaceName);
736: }
737: }
|