Source Code Cross Referenced for DiscussionAction.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » discussion » tool » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » sakai » org.sakaiproject.discussion.tool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************************
0002:         * $URL: https://source.sakaiproject.org/svn/discussion/tags/sakai_2-4-1/discussion-tool/tool/src/java/org/sakaiproject/discussion/tool/DiscussionAction.java $
0003:         * $Id: DiscussionAction.java 19434 2006-12-12 21:03:26Z zqian@umich.edu $
0004:         ***********************************************************************************
0005:         *
0006:         * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
0007:         * 
0008:         * Licensed under the Educational Community License, Version 1.0 (the "License"); 
0009:         * you may not use this file except in compliance with the License. 
0010:         * You may obtain a copy of the License at
0011:         * 
0012:         *      http://www.opensource.org/licenses/ecl1.php
0013:         * 
0014:         * Unless required by applicable law or agreed to in writing, software 
0015:         * distributed under the License is distributed on an "AS IS" BASIS, 
0016:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
0017:         * See the License for the specific language governing permissions and 
0018:         * limitations under the License.
0019:         *
0020:         **********************************************************************************/package org.sakaiproject.discussion.tool;
0021:
0022:        import java.util.Collections;
0023:        import java.util.HashSet;
0024:        import java.util.Hashtable;
0025:        import java.util.Iterator;
0026:        import java.util.List;
0027:        import java.util.NoSuchElementException;
0028:        import java.util.Set;
0029:        import java.util.Stack;
0030:        import java.util.Vector;
0031:
0032:        import org.sakaiproject.authz.api.PermissionsHelper;
0033:        import org.sakaiproject.cheftool.Context;
0034:        import org.sakaiproject.cheftool.JetspeedRunData;
0035:        import org.sakaiproject.cheftool.PortletConfig;
0036:        import org.sakaiproject.cheftool.RunData;
0037:        import org.sakaiproject.cheftool.VelocityPortlet;
0038:        import org.sakaiproject.cheftool.VelocityPortletPaneledAction;
0039:        import org.sakaiproject.cheftool.api.Menu;
0040:        import org.sakaiproject.cheftool.api.MenuItem;
0041:        import org.sakaiproject.cheftool.menu.MenuEntry;
0042:        import org.sakaiproject.cheftool.menu.MenuImpl;
0043:        import org.sakaiproject.content.api.ContentTypeImageService;
0044:        import org.sakaiproject.content.api.FilePickerHelper;
0045:        import org.sakaiproject.discussion.api.DiscussionChannel;
0046:        import org.sakaiproject.discussion.api.DiscussionChannelEdit;
0047:        import org.sakaiproject.discussion.api.DiscussionMessage;
0048:        import org.sakaiproject.discussion.api.DiscussionMessageEdit;
0049:        import org.sakaiproject.discussion.api.DiscussionMessageHeader;
0050:        import org.sakaiproject.discussion.api.DiscussionMessageHeaderEdit;
0051:        import org.sakaiproject.discussion.cover.DiscussionService;
0052:        import org.sakaiproject.entity.api.Reference;
0053:        import org.sakaiproject.entity.api.ResourceProperties;
0054:        import org.sakaiproject.entity.api.ResourcePropertiesEdit;
0055:        import org.sakaiproject.entity.cover.EntityManager;
0056:        import org.sakaiproject.event.api.SessionState;
0057:        import org.sakaiproject.exception.IdInvalidException;
0058:        import org.sakaiproject.exception.IdUnusedException;
0059:        import org.sakaiproject.exception.IdUsedException;
0060:        import org.sakaiproject.exception.InUseException;
0061:        import org.sakaiproject.exception.PermissionException;
0062:        import org.sakaiproject.site.cover.SiteService;
0063:        import org.sakaiproject.time.cover.TimeService;
0064:        import org.sakaiproject.tool.cover.ToolManager;
0065:        import org.sakaiproject.util.FormattedText;
0066:        import org.sakaiproject.util.ParameterParser;
0067:        import org.sakaiproject.util.ResourceLoader;
0068:        import org.sakaiproject.util.StringUtil;
0069:        import org.sakaiproject.util.Validator;
0070:        import org.sakaiproject.util.Web;
0071:        import org.sakaiproject.vm.ActionURL;
0072:
0073:        /**
0074:         * <p>
0075:         * DiscussionAction is the action class for the dicussion tool.
0076:         * </p>
0077:         */
0078:        public class DiscussionAction extends VelocityPortletPaneledAction {
0079:            /* reply type */
0080:            private static final String STATE_REPLY_TOPIC = "replyToTopic";
0081:
0082:            private static final String STATE_REPLY_MSG = "replyToMsgOnly";
0083:
0084:            /** Resource bundle using current language locale */
0085:            private static ResourceLoader rb = new ResourceLoader("discussion");
0086:
0087:            /** channel exist */
0088:            private static final String CHANNEL_EXIST = "channel_exist";
0089:
0090:            /** the attachments** */
0091:            private static final String ATTACHMENTS = "threadeddiscussionII.attachments";
0092:
0093:            /** go to attachments helper view */
0094:            private static final String GO_ATTACHMENTS = "threadeddiscussionII.go_attachments";
0095:
0096:            /** the channel id ** */
0097:            private static final String STATE_CHANNEL_REF = "threadeddiscussionII.channel_id";
0098:
0099:            /** the state mode ** */
0100:            private static final String STATE_MODE = "threadeddiscussionII.state_mode";
0101:
0102:            /** the category show list ** */
0103:            private static final String STATE_CATEGORIES_SHOW_LIST = "threadeddiscussionII.state_category_show_list";
0104:
0105:            /** the sorted by ** */
0106:            private static final String STATE_SORTED_BY = "threadeddiscussionII.state_sorted_by";
0107:
0108:            /** sorted by topic * */
0109:            private static final String STATE_SORTED_BY_TOPIC = "topic";
0110:
0111:            /** sorted by author * */
0112:            private static final String STATE_SORTED_BY_AUTHOR = "author";
0113:
0114:            /** sorted by date * */
0115:            private static final String STATE_SORTED_BY_DATE = "date";
0116:
0117:            /** sorted by category alphabetically * */
0118:            private static final String STATE_SORTED_BY_CATEGORY_ALPHA = "category";
0119:
0120:            /** the sorted ascending * */
0121:            private static final String STATE_SORTED_ASC = "threadeddiscussionII.state_sorted_asc";
0122:
0123:            /** the expand all topic flag * */
0124:            private static final String STATE_EXPAND_ALL_TOPIC_FLAG = "threadeddiscussionII.state_expand_all_topic_flag";
0125:
0126:            /** the expand message flag * */
0127:            private static final String STATE_EXPAND_MESSAGE_LIST = "threadeddiscussionII.state_expand_message_list";
0128:
0129:            /** the expand category list * */
0130:            private static final String STATE_EXPAND_CATEGORY_LIST = "threadeddiscussionII.state_expand_category_list";
0131:
0132:            /** The content type image lookup service in the State. */
0133:            private static final String STATE_CONTENT_TYPE_IMAGE_SERVICE = "attachment.content_type_image_service";
0134:
0135:            /** ********** new topic context ******************** */
0136:            /** the new topic category */
0137:            private static final String NEW_TOPIC_CATEGORY = "threadeddiscussionII.new_topic_category";
0138:
0139:            /** create new category? */
0140:            private static final String NEW_TOPIC_NEW_CATEGORY = "threadeddiscussionII.new_topic_new_category";
0141:
0142:            /** the new topic message body */
0143:            private static final String NEW_TOPIC_BODY = "threadeddiscussionII.new_topic_body";
0144:
0145:            /** the new topic subject */
0146:            private static final String NEW_TOPIC_SUBJECT = "threadeddiscussionII.new_topic_subject";
0147:
0148:            /** the new topic reply message style */
0149:            private static final String NEW_TOPIC_REPLY_STYLE = "threadeddiscussionII.new_topic_reply_style";
0150:
0151:            /** ********** new category context ******************** */
0152:            private static final String NEW_CATEGORY = "threadeddiscussionII.new_category";
0153:
0154:            /** ********** draft topic context ******************** */
0155:            /** the draft message category */
0156:            private static final String DRAFT_MESSAGE_CATEGORY = "threadeddiscussionII.draft_message_category";
0157:
0158:            /** the draft message body */
0159:            private static final String DRAFT_MESSAGE_BODY = "threadeddiscussionII.draft_message_body";
0160:
0161:            /** the draft message subject */
0162:            private static final String DRAFT_MESSAGE_SUBJECT = "threadeddiscussionII.draft_message_subject";
0163:
0164:            /** the draft message reply style */
0165:            private static final String DRAFT_MESSAGE_REPLY_STYLE = "threadeddiscussionII.draft_message_reply_style";
0166:
0167:            /** ********* the respond context ******************** */
0168:            /** the respond message body */
0169:            private static final String RESPOND_BODY = "threadeddiscussionII.respond_body";
0170:
0171:            /** the respond message subject */
0172:            private static final String RESPOND_SUBJECT = "threadeddiscussionII.respond_subject";
0173:
0174:            /** the respond from */
0175:            private static final String RESPOND_REPLY_TO = "threadeddiscussionII.respond_reply_to";
0176:
0177:            /** the respond attachment */
0178:            private static final String RESPOND_ATTACHMENT = "threadeddiscussionII.respond_attachment";
0179:
0180:            /** ************ delete message context ******************* */
0181:            /** the delete message id * */
0182:            private static final String DELETE_MESSAGE_ID = "threadeddiscussionII.delete_message_id";
0183:
0184:            private static final String DELETE_WARNING = "delete_message_warning";
0185:
0186:            /** portlet configuration parameter names. */
0187:            private static final String PARAM_CHANNEL = "channel";
0188:
0189:            private static final String PARAM_ASCENDING = "ascending";
0190:
0191:            /** Configure form field names. */
0192:            private static final String FORM_CHANNEL = "channel";
0193:
0194:            private static final String FORM_ASCENDING = "ascending";
0195:
0196:            /** Control form field names. */
0197:            private static final String FORM_MESSAGE = "message";
0198:
0199:            /** names and values of request parameters to select sub-panels */
0200:            private static final String MONITOR_PANEL = "List";
0201:
0202:            private static final String CONTROL_PANEL = "Control";
0203:
0204:            private static final String TOOLBAR_PANEL = "Toolbar";
0205:
0206:            private static final String NEXT_PANEL = "Next";
0207:
0208:            /** state attribute names. */
0209:            private static final String STATE_ASCENDING = "ascending";
0210:
0211:            private static final String STATE_ERROR = "error";
0212:
0213:            private static final String STATE_UPDATE = "update";
0214:
0215:            /** UI messages. */
0216:            private static final String STATE_DISPLAY_MESSAGE = "display_message";
0217:
0218:            private static final String STATE_LIST_PANNEL_UPDATED = "state_list_pannel_updated";
0219:
0220:            /** the category to be deleted */
0221:            private static final String DELETE_CATEGORY = "delete_category";
0222:
0223:            /** the id of the showing content topic */
0224:            private static final String STATE_SHOW_CONTENT_TOPIC_ID = "show_content_topic_id";
0225:
0226:            /** state mode when showing the topic content */
0227:            private static final String MODE_SHOW_TOPIC_CONTENT = "mode_show_topic_content";
0228:
0229:            /** the state flag of expand all */
0230:            private static final String STATE_EXPAND_ALL_FLAG = "state_expand_all_flag";
0231:
0232:            /** state mode when showing the new topic form */
0233:            private static final String MODE_NEW_TOPIC = "mode_new_topic";
0234:
0235:            /** state mode when showing the new category form */
0236:            private static final String MODE_NEW_CATEGORY = "mode_new_category";
0237:
0238:            /** state mode when showing the reply form */
0239:            private static final String MODE_REPLY = "mode_reply";
0240:
0241:            /** state mode when showing the reply preview */
0242:            private static final String MODE_REPLY_PREVIEW = "mode_reply_preview";
0243:
0244:            /** state mode when confirm deleting category */
0245:            private static final String MODE_DELETE_CATEGORY_CONFIRM = "mode_delete_category_confirm";
0246:
0247:            /** state mode when confirm deleting message */
0248:            private static final String MODE_DELETE_MESSAGE_CONFIRM = "mode_delete_message_confirm";
0249:
0250:            /** visited messages */
0251:            private static final String VISITED_MESSAGES = "visited_messages";
0252:
0253:            /** left_right layout */
0254:            private static final String STATE_LEFT_RIGHT_LAYOUT = "state_left_right_layout";
0255:
0256:            /** search criteria */
0257:            private static final String STATE_SEARCH = "state_search";
0258:
0259:            /** boolean value indicating the need to update the current message shown */
0260:            private static final String STATE_SEARCH_REFRESH = "state_search_refresh";
0261:
0262:            /** Form fields. */
0263:            protected static final String FORM_SEARCH = "search";
0264:
0265:            /** state selected view */
0266:            private static final String STATE_SELECTED_VIEW = "state_selected_view";
0267:
0268:            /** State attribute set when we need to go into permissions mode. */
0269:            private static final String STATE_PERMISSIONS = "sakai:discussion:permissions";
0270:
0271:            /** state variable for search results */
0272:            private static final String STATE_SEARCH_RESULT = "state_search_result";
0273:
0274:            /**
0275:             * Populate the state object, if needed.
0276:             * 
0277:             * @param config
0278:             *        The portlet config.
0279:             * @param pageSessionId
0280:             *        The is of the current portal page session.
0281:             * @param elementId
0282:             *        The id of the portlet element that wants to be notified on change.
0283:             */
0284:            protected void initState(SessionState state,
0285:                    VelocityPortlet portlet, JetspeedRunData rundata) {
0286:                super .initState(state, portlet, rundata);
0287:
0288:                PortletConfig config = portlet.getPortletConfig();
0289:                String channelId = (String) state
0290:                        .getAttribute(STATE_CHANNEL_REF);
0291:                String channelExist = (String) state
0292:                        .getAttribute(CHANNEL_EXIST);
0293:                if (channelExist == null) {
0294:
0295:                    if (channelId == null) {
0296:                        // read the channel from configuration, or, if not specified, use the default for the page
0297:                        channelId = StringUtil.trimToNull(config
0298:                                .getInitParameter("channel"));
0299:                        if (channelId == null) {
0300:                            channelId = DiscussionService.channelReference(
0301:                                    ToolManager.getCurrentPlacement()
0302:                                            .getContext(),
0303:                                    SiteService.MAIN_CONTAINER);
0304:                        }
0305:                        state.setAttribute(STATE_CHANNEL_REF, channelId);
0306:                    }
0307:
0308:                    DiscussionChannel channel = null;
0309:                    try {
0310:                        channel = (DiscussionChannel) DiscussionService
0311:                                .getDiscussionChannel(channelId);
0312:                    } catch (IdUnusedException e) {
0313:                        try {
0314:                            DiscussionChannelEdit channelEdit = DiscussionService
0315:                                    .addDiscussionChannel(channelId);
0316:                            DiscussionService.commitChannel(channelEdit);
0317:                            channel = (DiscussionChannel) channelEdit;
0318:                        } catch (IdUsedException ee) {
0319:                            Log.error("chef", this  + "" + ee);
0320:                        } catch (IdInvalidException ee) {
0321:                            Log.error("chef", this  + "" + ee);
0322:                        } catch (PermissionException ee) {
0323:                            Log.error("chef", this  + "no permission");
0324:                        }
0325:                    } catch (PermissionException e) {
0326:                    }
0327:
0328:                    if (channel != null) {
0329:                        state.setAttribute(CHANNEL_EXIST, "true");
0330:
0331:                        // TODO: Note: calling addCatagory here, which uses the state's STATE_EXPAND_CATEGORY_LIST which is not yet set is not good -ggolden
0332:                        // // make sure that the channel has categories as seeded in the config
0333:                        // String[] configCategories = parseCategoryString(StringUtil.trimToNull(config.getInitParameter("categories")));
0334:                        // if (configCategories != null)
0335:                        // {
0336:                        // for (int i = 0; i < configCategories.length; i++)
0337:                        // {
0338:                        // addCategory(state, channel, configCategories[i]);
0339:                        // }
0340:
0341:                        if (state.getAttribute(STATE_CATEGORIES_SHOW_LIST) == null) {
0342:                            // get the catagories as defined without scanning all messages for more
0343:                            List categories = channel.getCategories(false);
0344:
0345:                            Hashtable h = new Hashtable();
0346:                            for (Iterator i = categories.iterator(); i
0347:                                    .hasNext();) {
0348:                                String cat = (String) i.next();
0349:
0350:                                // store the ids of topic messages
0351:                                List topicMsgIds = channel.getTopicMsgIds(cat);
0352:                                h.put(cat, topicMsgIds);
0353:                            }
0354:                            state.setAttribute(STATE_CATEGORIES_SHOW_LIST, h);
0355:
0356:                            HashSet s = new HashSet();
0357:                            s.addAll(categories);
0358:                            state.setAttribute(STATE_EXPAND_CATEGORY_LIST, s);
0359:
0360:                            Hashtable t = new Hashtable();
0361:                            for (Iterator i = categories.iterator(); i
0362:                                    .hasNext();) {
0363:                                String cat = (String) i.next();
0364:                                HashSet v = new HashSet();
0365:                                t.put(cat, v);
0366:                            }
0367:                            state.setAttribute(STATE_EXPAND_MESSAGE_LIST, t);
0368:
0369:                        }
0370:                    }
0371:
0372:                    // // setup the observer to notify our MONITOR_PANEL panel(inside the Main panel)
0373:                    // if (state.getAttribute(STATE_OBSERVER) == null)
0374:                    // {
0375:                    // // the delivery location for this tool
0376:                    // String deliveryId = clientWindowId(state, portlet.getID());
0377:                    //
0378:                    // // the html element to update on delivery
0379:                    // String elementId = mainPanelUpdateId(portlet.getID()) + "." + MONITOR_PANEL;
0380:                    //
0381:                    // // the event resource reference pattern to watch for
0382:                    // Reference r = new Reference(channelId);
0383:                    //				
0384:                    // // add message pattern
0385:                    // String pattern = DiscussionService.messageReference(r.getContext(), r.getId(), "");
0386:                    // MultipleEventsObservingCourier o = new MultipleEventsObservingCourier(deliveryId, elementId, pattern);
0387:                    // // add channel pattern
0388:                    // pattern = DiscussionService.channelReference(r.getContext(), r.getId());
0389:                    // o.addResourcePattern(pattern);
0390:                    // o.enable();
0391:                    // state.setAttribute(STATE_OBSERVER, o);
0392:                    // }
0393:                }
0394:
0395:                if (state.getAttribute(STATE_DISPLAY_MESSAGE) == null) {
0396:                    state.setAttribute(STATE_DISPLAY_MESSAGE,
0397:                            new DisplayMessage(""));
0398:                }
0399:
0400:                /** The content type image lookup service in the State. */
0401:                ContentTypeImageService iService = (ContentTypeImageService) state
0402:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE);
0403:                if (iService == null) {
0404:                    iService = org.sakaiproject.content.cover.ContentTypeImageService
0405:                            .getInstance();
0406:                    state.setAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE,
0407:                            iService);
0408:                } // if
0409:
0410:                if (state.getAttribute(STATE_SORTED_BY) == null) {
0411:                    state.setAttribute(STATE_SORTED_BY, STATE_SORTED_BY_DATE);
0412:                }
0413:
0414:                if (state.getAttribute(STATE_SORTED_ASC) == null) {
0415:                    state.setAttribute(STATE_SORTED_ASC, Boolean.TRUE
0416:                            .toString());
0417:                }
0418:
0419:                if (state.getAttribute(STATE_ASCENDING) == null) {
0420:                    state.setAttribute(STATE_ASCENDING, new Boolean(config
0421:                            .getInitParameter(PARAM_ASCENDING)));
0422:                }
0423:
0424:                if (state.getAttribute(STATE_EXPAND_ALL_FLAG) == null) {
0425:                    state.setAttribute(STATE_EXPAND_ALL_FLAG,
0426:                            new Boolean(false));
0427:                }
0428:
0429:                if (state.getAttribute(STATE_LEFT_RIGHT_LAYOUT) == null) {
0430:                    state.setAttribute(STATE_LEFT_RIGHT_LAYOUT, new Boolean(
0431:                            false));
0432:                }
0433:
0434:                if (state.getAttribute(VISITED_MESSAGES) == null) {
0435:                    state.setAttribute(VISITED_MESSAGES, new HashSet());
0436:                }
0437:
0438:                // show the list of assignment view first
0439:                if (state.getAttribute(STATE_SELECTED_VIEW) == null) {
0440:                    state.setAttribute(STATE_SELECTED_VIEW, rb
0441:                            .getString("rowlay"));
0442:                }
0443:
0444:                if (state.getAttribute(STATE_SEARCH) == null) {
0445:                    state.setAttribute(STATE_SEARCH, "");
0446:                }
0447:
0448:                // make sure the observer is in sync with state
0449:                updateObservationOfChannel(state, portlet.getID());
0450:
0451:            } // initState
0452:
0453:            /**
0454:             * Action is to use when doAttachment when "add attachments" is clicked
0455:             */
0456:            public void doAttachments(RunData data, Context context) {
0457:                String peid = ((JetspeedRunData) data).getJs_peid();
0458:                SessionState state = ((JetspeedRunData) data)
0459:                        .getPortletSessionState(peid);
0460:
0461:                // trigger the switch on the next request (which is going to happen after this action is processed with its redirect response to the build)
0462:                state.setAttribute(GO_ATTACHMENTS, GO_ATTACHMENTS);
0463:
0464:                ParameterParser params = data.getParameters();
0465:                String subject = params.getString("subject");
0466:
0467:                String mode = (String) state.getAttribute(STATE_MODE);
0468:                if (mode != null && mode.equals(MODE_NEW_TOPIC)) {
0469:                    subject = ((String) params.getString("subject"));
0470:                    if (subject != null) {
0471:                        subject = subject.trim();
0472:                    }
0473:                    state.setAttribute(NEW_TOPIC_SUBJECT, subject);
0474:
0475:                    String body = params.getCleanString("body");
0476:                    body = processFormattedTextFromBrowser(state, body);
0477:                    state.setAttribute(NEW_TOPIC_BODY, body);
0478:
0479:                    String style = params.getString("style");
0480:                    state.setAttribute(NEW_TOPIC_REPLY_STYLE, style);
0481:
0482:                    String category = ((String) params.getString("newcategory"));
0483:                    if (category != null) {
0484:                        category = category.trim();
0485:                    }
0486:                    if (category == null || category.length() == 0) {
0487:                        // no new category input
0488:                        state.setAttribute(NEW_TOPIC_NEW_CATEGORY, new Boolean(
0489:                                Boolean.FALSE.toString()));
0490:                        category = ((String) params.getString("category"));
0491:                        if (category != null) {
0492:                            category = category.trim();
0493:                        }
0494:                        state.setAttribute(NEW_TOPIC_CATEGORY, category);
0495:                    } else {
0496:                        // new category input
0497:                        state.setAttribute(NEW_TOPIC_NEW_CATEGORY, new Boolean(
0498:                                Boolean.TRUE.toString()));
0499:                        state.setAttribute(NEW_TOPIC_CATEGORY, category);
0500:                    }
0501:                } else if (mode != null && mode.equals(MODE_REPLY)) {
0502:                    // save the input infos for the respond message
0503:                    subject = params.getString("subject");
0504:                    if (subject != null) {
0505:                        subject = subject.trim();
0506:                    }
0507:                    state.setAttribute(RESPOND_SUBJECT, subject);
0508:
0509:                    String body = params.getCleanString("body");
0510:                    body = processFormattedTextFromBrowser(state, body);
0511:                    state.setAttribute(RESPOND_BODY, body);
0512:                } else {
0513:                    // must be inside control pannel editing draft message
0514:                    state.setAttribute(DRAFT_MESSAGE_BODY,
0515:                            processFormattedTextFromBrowser(state, params
0516:                                    .getCleanString("body")));
0517:                    state.setAttribute(DRAFT_MESSAGE_SUBJECT, params.getString(
0518:                            "subject").trim());
0519:                    state.setAttribute(DRAFT_MESSAGE_REPLY_STYLE, params
0520:                            .getString("style"));
0521:                }
0522:
0523:                // schedule a main refresh to excape from the control panel
0524:                schedulePeerFrameRefresh(mainPanelUpdateId(peid));
0525:            } // doAttachments
0526:
0527:            /**
0528:             * Fire up the permissions editor
0529:             */
0530:            protected void doAttachmentsNow(RunData data, Context context) {
0531:                // get into helper mode with this helper tool
0532:                startHelper(data.getRequest(), "sakai.filepicker");
0533:                SessionState state = ((JetspeedRunData) data)
0534:                        .getPortletSessionState(((JetspeedRunData) data)
0535:                                .getJs_peid());
0536:                if (state.getAttribute(ATTACHMENTS) == null) {
0537:                    state.setAttribute(ATTACHMENTS, EntityManager
0538:                            .newReferenceList());
0539:                }
0540:                state.setAttribute(FilePickerHelper.FILE_PICKER_ATTACHMENTS,
0541:                        state.getAttribute(ATTACHMENTS));
0542:
0543:            } // doAttachmentsNow
0544:
0545:            /**
0546:             * Setup our observer to be watching for change events for our channel.
0547:             */
0548:            private void updateObservationOfChannel(SessionState state,
0549:                    String peid) {
0550:            } // updateObservationOfChannel
0551:
0552:            /**
0553:             * If the state indicates an update is needed, update the portlet's configuration.
0554:             * 
0555:             * @param state
0556:             *        The session state.
0557:             * @param portlet
0558:             *        The portlet to update.
0559:             * @param data
0560:             *        The current request run data.
0561:             */
0562:            private void updatePortlet(SessionState state,
0563:                    VelocityPortlet portlet, RunData data) {
0564:                // check the flag
0565:                if (state.getAttribute(STATE_UPDATE) == null)
0566:                    return;
0567:
0568:                // change the portlet's configuration
0569:                portlet.setAttribute(PARAM_CHANNEL, (String) state
0570:                        .getAttribute(STATE_CHANNEL_REF), data);
0571:                portlet.setAttribute(PARAM_ASCENDING, ((Boolean) state
0572:                        .getAttribute(STATE_ASCENDING)).toString(), data);
0573:
0574:                // clear the flag
0575:                state.removeAttribute(STATE_UPDATE);
0576:
0577:            } // updatePortlet
0578:
0579:            /**
0580:             * build the context for the Layout panel
0581:             * 
0582:             * @return (optional) template name for this panel
0583:             */
0584:            public String buildMainPanelContext(VelocityPortlet portlet,
0585:                    Context context, RunData rundata, SessionState state) {
0586:                context.put("mainFrameId", Web.escapeJavascript("Main"
0587:                        + ToolManager.getCurrentPlacement().getId()));
0588:
0589:                context.put("tlang", rb);
0590:
0591:                String state_mode = (String) state.getAttribute(STATE_MODE);
0592:
0593:                if (state_mode != null) {
0594:                    if (state_mode.equals(MODE_SHOW_TOPIC_CONTENT)) {
0595:                        return buildContentContext(portlet, context, rundata,
0596:                                state);
0597:                    } else if (state_mode.equals(MODE_NEW_TOPIC)) {
0598:                        return buildNewTopicContext(portlet, context, rundata,
0599:                                state);
0600:                    } else if (state_mode.equals(MODE_NEW_CATEGORY)) {
0601:                        return buildNewCategoryContext(portlet, context,
0602:                                rundata, state);
0603:                    } else if (state_mode.equals(MODE_REPLY)) {
0604:                        return buildReplyContext(portlet, context, rundata,
0605:                                state);
0606:                    } else if (state_mode.equals(MODE_REPLY_PREVIEW)) {
0607:                        return buildReplyPreviewContext(portlet, context,
0608:                                rundata, state);
0609:                    } else if (state_mode.equals(MODE_DELETE_CATEGORY_CONFIRM)) {
0610:                        return buildDeleteCategoryConfirmContext(portlet,
0611:                                context, rundata, state);
0612:                    } else if (state_mode.equals(MODE_DELETE_MESSAGE_CONFIRM)) {
0613:                        return buildDeleteMessageConfirmContext(portlet,
0614:                                context, rundata, state);
0615:                    }
0616:                }
0617:
0618:                // assure that the portlet parameters are current with the user's configuration choices
0619:                updatePortlet(state, portlet, rundata);
0620:
0621:                context.put("panel-control", CONTROL_PANEL);
0622:                context.put("panel-monitor", MONITOR_PANEL);
0623:                context.put("panel-toolbar", TOOLBAR_PANEL);
0624:                context.put("panel-next", NEXT_PANEL);
0625:
0626:                context.put("layout_left_right", (Boolean) state
0627:                        .getAttribute(STATE_LEFT_RIGHT_LAYOUT));
0628:                return (String) getContext(rundata).get("template") + "-Layout";
0629:
0630:            } // buildMainPanelContext
0631:
0632:            /**
0633:             * build the context for the menu panel
0634:             * 
0635:             * @return (optional) template name for this panel
0636:             */
0637:            public String buildToolbarPanelContext(VelocityPortlet portlet,
0638:                    Context context, RunData data, SessionState state) {
0639:                // we might be on the way to a permissions...
0640:                if (state.getAttribute(STATE_PERMISSIONS) != null) {
0641:                    state.removeAttribute(STATE_PERMISSIONS);
0642:                    doPermissionsNow(data, context);
0643:                }
0644:
0645:                boolean allowNewTopic = false;
0646:                boolean allowNewCategory = false;
0647:                boolean hasPrevious = false;
0648:                boolean hasNext = false;
0649:
0650:                String channelId = (String) state
0651:                        .getAttribute(STATE_CHANNEL_REF);
0652:
0653:                try {
0654:                    // get the current channel ID from state object
0655:                    DiscussionChannel channel = DiscussionService
0656:                            .getDiscussionChannel(channelId);
0657:
0658:                    String currentId = null;
0659:                    DisplayMessage dMessage = (DisplayMessage) state
0660:                            .getAttribute(STATE_DISPLAY_MESSAGE);
0661:                    if (dMessage != null) {
0662:                        currentId = dMessage.getId();
0663:                    }
0664:                    if (currentId != null && !currentId.equals("")) {
0665:                        DiscussionMessage message = channel
0666:                                .getDiscussionMessageNoException(currentId);
0667:                        if (message != null) {
0668:                            String category = message.getDiscussionHeader()
0669:                                    .getCategory();
0670:                            Vector messageIds = new Vector();
0671:                            if (((Hashtable) state
0672:                                    .getAttribute(STATE_CATEGORIES_SHOW_LIST))
0673:                                    .get(category) != null) {
0674:                                messageIds = (Vector) ((Hashtable) state
0675:                                        .getAttribute(STATE_CATEGORIES_SHOW_LIST))
0676:                                        .get(category);
0677:                            }
0678:                            hasPrevious = (messageIds.indexOf(currentId) == 0) ? false
0679:                                    : true;
0680:                            hasNext = ((messageIds.indexOf(currentId) == messageIds
0681:                                    .size() - 1)) ? false : true;
0682:                        } else {
0683:                            hasPrevious = false;
0684:                            hasNext = false;
0685:                        }
0686:                    }
0687:
0688:                    // detect whether channel is existed
0689:                    if (channel != null) {
0690:                        allowNewTopic = channel.allowAddTopicMessage();
0691:                        allowNewCategory = channel.allowAddTopicMessage();
0692:                    } else {
0693:                        allowNewTopic = DiscussionService
0694:                                .allowAddChannel(channelId);
0695:                        allowNewCategory = DiscussionService
0696:                                .allowAddChannel(channelId);
0697:                    }
0698:                } catch (IdUnusedException e) {
0699:                    addAlert(state, rb.getString("cannotfin5"));
0700:                } catch (PermissionException e) {
0701:                    addAlert(state, rb.getString("youdonot1"));
0702:                }
0703:
0704:                // build menu
0705:                Menu bar = new MenuImpl(portlet, data,
0706:                        "ThreadedDiscussionIIAction");
0707:                bar.add(new MenuEntry(rb.getString("newtopic"), null,
0708:                        allowNewTopic, MenuItem.CHECKED_NA, "doSet_new_topic"));
0709:                bar.add(new MenuEntry(rb.getString("newcat"), null,
0710:                        allowNewCategory, MenuItem.CHECKED_NA,
0711:                        "doSet_new_category"));
0712:
0713:                if (hasPrevious) {
0714:                    bar.add(new MenuEntry(rb.getString("premess"), null, true,
0715:                            MenuItem.CHECKED_NA, "doPre_message"));
0716:                }
0717:                if (hasNext) {
0718:                    bar.add(new MenuEntry(rb.getString("nexmess"), null, true,
0719:                            MenuItem.CHECKED_NA, "doNext_message"));
0720:                }
0721:
0722:                if (!((Boolean) state.getAttribute(STATE_EXPAND_ALL_FLAG))
0723:                        .booleanValue()) {
0724:                    bar.add(new MenuEntry(rb.getString("expall"), null, true,
0725:                            MenuItem.CHECKED_NA, "doExpand_all"));
0726:                } else {
0727:                    bar.add(new MenuEntry(rb.getString("collall"), null, true,
0728:                            MenuItem.CHECKED_NA, "doCollapse_all"));
0729:                }
0730:
0731:                // Set menu state attribute
0732:                SessionState stateForMenus = ((JetspeedRunData) data)
0733:                        .getPortletSessionState(portlet.getID());
0734:                stateForMenus.setAttribute(MenuItem.STATE_MENU, bar);
0735:
0736:                // add permissions, if allowed
0737:                if (SiteService.allowUpdateSite(ToolManager
0738:                        .getCurrentPlacement().getContext())) {
0739:                    bar.add(new MenuEntry(rb.getString("permis"),
0740:                            "doPermissions"));
0741:                }
0742:
0743:                context.put(Menu.CONTEXT_MENU, bar);
0744:                context.put(Menu.CONTEXT_ACTION, state
0745:                        .getAttribute(STATE_ACTION));
0746:
0747:                /* Added this array to load the combo box options */
0748:                String[] comoptions = { rb.getString("rowlay"),
0749:                        rb.getString("collay") };
0750:                context.put("ord", comoptions);
0751:
0752:                context.put("tlang", rb);
0753:                add2ndToolbarFields(data, context);
0754:
0755:                return null;
0756:
0757:            } // buildToolbarPanelContext
0758:
0759:            /**
0760:             * build the context for the List panel
0761:             * 
0762:             * @return (optional) template name for this panel
0763:             */
0764:            public String buildListPanelContext(VelocityPortlet portlet,
0765:                    Context context, RunData rundata, SessionState state) {
0766:                context.put("tlang", rb);
0767:
0768:                String search = (String) state.getAttribute(STATE_SEARCH);
0769:                if (search == null || search.equals("")) {
0770:                    context.put("searching", Boolean.FALSE);
0771:                } else {
0772:                    context.put("searching", Boolean.TRUE);
0773:                }
0774:
0775:                String channelId = (String) state
0776:                        .getAttribute(STATE_CHANNEL_REF);
0777:
0778:                // the sorting defaults for the outline view
0779:                String sortedBy = "";
0780:                String sortedAsc = (String) state
0781:                        .getAttribute(STATE_SORTED_ASC);
0782:
0783:                // set default sort attribute
0784:                sortedBy = (String) state.getAttribute(STATE_SORTED_BY);
0785:                if ((!sortedBy.equals(STATE_SORTED_BY_TOPIC))
0786:                        && (!sortedBy.equals(STATE_SORTED_BY_AUTHOR))
0787:                        && (!sortedBy.equals(STATE_SORTED_BY_DATE))) {
0788:                    sortedBy = STATE_SORTED_BY_DATE;
0789:                    state.setAttribute(STATE_SORTED_BY, sortedBy);
0790:                }
0791:                context.put("currentSortedBy", sortedBy);
0792:                context.put("currentSortAsc", sortedAsc);
0793:
0794:                boolean allowNewTopic = false;
0795:                boolean allowRemoveCategory = false;
0796:                try {
0797:                    // get the current channel ID from state object
0798:                    DiscussionChannel channel = DiscussionService
0799:                            .getDiscussionChannel(channelId);
0800:
0801:                    // detect whether channel is existed
0802:                    if (channel != null) {
0803:                        allowNewTopic = channel.allowAddTopicMessage();
0804:                        allowRemoveCategory = channel.allowRemoveCategory();
0805:                        context.put("channel", channel);
0806:
0807:                        // get the sorted categories Vector according to the current sorting criteria
0808:                        List categories = sortedCategories(channel, sortedBy,
0809:                                sortedAsc);
0810:                        if (categories != null) {
0811:                            context.put("categories", categories);
0812:                        }
0813:
0814:                        // provide the expanded category list
0815:                        HashSet expandedCategories = (HashSet) state
0816:                                .getAttribute(STATE_EXPAND_CATEGORY_LIST);
0817:                        context.put("expandedCategoryList", expandedCategories);
0818:
0819:                        if (categories != null) {
0820:                            for (Iterator i = categories.iterator(); i
0821:                                    .hasNext();) {
0822:                                String currentCategory = (String) i.next();
0823:
0824:                                // the category is expanded; get the most recent topics
0825:                                if (expandedCategories
0826:                                        .contains(currentCategory)) {
0827:                                    Hashtable showList = (Hashtable) state
0828:                                            .getAttribute(STATE_CATEGORIES_SHOW_LIST);
0829:                                    Vector v = (Vector) showList
0830:                                            .get(currentCategory);
0831:                                    if (v == null)
0832:                                        v = new Vector();
0833:                                    Iterator topics = channel
0834:                                            .getTopics(currentCategory);
0835:                                    while (topics.hasNext()) {
0836:                                        DiscussionMessage topic = (DiscussionMessage) topics
0837:                                                .next();
0838:                                        // the topic is newly added, add the topic
0839:                                        if (!v.contains(topic.getId())) {
0840:                                            int index = 0;
0841:                                            // the replied to message has already been expanded
0842:                                            if (topic.getDiscussionHeader()
0843:                                                    .getDraft()) {
0844:                                                try {
0845:                                                    // filter out drafts not by this user (unless this user is a super user) %%% not sure I like this -zqian
0846:                                                    channel
0847:                                                            .getDiscussionMessage(topic
0848:                                                                    .getId());
0849:
0850:                                                    // if the new message is a draft message, add to the bottom of drafts
0851:                                                    int firstNondraftIndex = -1;
0852:                                                    for (int j = 0; (j < v
0853:                                                            .size() && firstNondraftIndex == -1); j++) {
0854:                                                        DiscussionMessage next = (DiscussionMessage) channel
0855:                                                                .getDiscussionMessage((String) v
0856:                                                                        .get(j));
0857:                                                        index = index + 1;
0858:                                                        if (!next
0859:                                                                .getDiscussionHeader()
0860:                                                                .getDraft()) {
0861:                                                            firstNondraftIndex = index;
0862:                                                        }
0863:                                                    }
0864:                                                    if (firstNondraftIndex == -1) {
0865:                                                        v.add(topic.getId());
0866:                                                    } else {
0867:                                                        v
0868:                                                                .add(
0869:                                                                        firstNondraftIndex,
0870:                                                                        topic
0871:                                                                                .getId());
0872:                                                    }
0873:                                                } catch (PermissionException e) {
0874:                                                } catch (IdUnusedException e) {
0875:                                                }
0876:                                            } else {
0877:                                                // add it to the end
0878:                                                v.add(topic.getId());
0879:                                            } // if-else
0880:
0881:                                        }
0882:                                    }
0883:
0884:                                    // check for the expanded message's responses
0885:                                    Hashtable t = (Hashtable) state
0886:                                            .getAttribute(STATE_EXPAND_MESSAGE_LIST);
0887:                                    HashSet s = (HashSet) t
0888:                                            .get(currentCategory);
0889:                                    if (s != null) {
0890:                                        Iterator expandMessageInCategory = ((HashSet) t
0891:                                                .get(currentCategory))
0892:                                                .iterator();
0893:                                        while (expandMessageInCategory
0894:                                                .hasNext()) {
0895:                                            DiscussionMessage nextMessage = (DiscussionMessage) expandMessageInCategory
0896:                                                    .next();
0897:                                            Iterator repliesToNextMessage = nextMessage
0898:                                                    .getReplies();
0899:                                            // only test for the direct response
0900:                                            int depth = nextMessage
0901:                                                    .getReplyToDepth() + 1;
0902:                                            while (repliesToNextMessage
0903:                                                    .hasNext()) {
0904:                                                DiscussionMessage testReply = (DiscussionMessage) repliesToNextMessage
0905:                                                        .next();
0906:                                                if ((testReply
0907:                                                        .getReplyToDepth() == depth)
0908:                                                        && (!v
0909:                                                                .contains(testReply
0910:                                                                        .getId()))) {
0911:                                                    int index = v
0912:                                                            .indexOf(nextMessage
0913:                                                                    .getId());
0914:                                                    // the replied to message has already been expanded
0915:                                                    if (testReply
0916:                                                            .getDiscussionHeader()
0917:                                                            .getDraft()) {
0918:                                                        try {
0919:                                                            // filter out drafts not by this user (unless this user is a super user) %%% not sure I like this -zqian
0920:                                                            channel
0921:                                                                    .getDiscussionMessage(testReply
0922:                                                                            .getId());
0923:
0924:                                                            // if the new message is a draft message, add to the bottom of drafts
0925:                                                            int firstNondraftIndex = -1;
0926:                                                            int k = index;
0927:                                                            while (k < v.size()
0928:                                                                    && (firstNondraftIndex == -1)) {
0929:                                                                DiscussionMessage next = (DiscussionMessage) channel
0930:                                                                        .getDiscussionMessage((String) v
0931:                                                                                .get(k));
0932:                                                                index = index + 1;
0933:                                                                if (!next
0934:                                                                        .getDiscussionHeader()
0935:                                                                        .getDraft()) {
0936:                                                                    firstNondraftIndex = index;
0937:                                                                }
0938:                                                                k++;
0939:                                                            }
0940:                                                            v
0941:                                                                    .add(
0942:                                                                            firstNondraftIndex,
0943:                                                                            testReply
0944:                                                                                    .getId());
0945:                                                        } catch (PermissionException e) {
0946:                                                        } catch (IdUnusedException e) {
0947:                                                        }
0948:
0949:                                                    } else {
0950:                                                        // if the new message is not a draft message, add to the bottom of non-drafts
0951:                                                        index = v
0952:                                                                .indexOf(nextMessage
0953:                                                                        .getId()) + 1;
0954:                                                        String id = nextMessage
0955:                                                                .getId();
0956:                                                        String replyToId = id;
0957:                                                        while (replyToId
0958:                                                                .equals(id)
0959:                                                                && index < v
0960:                                                                        .size()) {
0961:                                                            DiscussionMessage m = (DiscussionMessage) channel
0962:                                                                    .getDiscussionMessage((String) v
0963:                                                                            .get(index));
0964:                                                            String newId = m
0965:                                                                    .getDiscussionHeader()
0966:                                                                    .getReplyTo();
0967:                                                            if (!newId
0968:                                                                    .equals(id)) {
0969:                                                                replyToId = newId;
0970:                                                            } else {
0971:                                                                index++;
0972:                                                            }
0973:                                                        }
0974:                                                        v.add(index, testReply
0975:                                                                .getId());
0976:                                                    } // if-else: draft vs. non draft
0977:                                                } // if: the message is not contained in the show list
0978:                                            } // while: check for all response to the message
0979:                                        } // while: check for all opened message
0980:                                    } // if: there is expanded message
0981:
0982:                                    // update the show list in that category
0983:                                    showList.put(currentCategory, v);
0984:
0985:                                    state.setAttribute(
0986:                                            STATE_CATEGORIES_SHOW_LIST,
0987:                                            showList);
0988:                                } // if: for every opened category
0989:                            } // for: for all categories
0990:                        } // if: categories not null
0991:
0992:                        Vector searchResultList = new Vector();
0993:                        if (state.getAttribute(STATE_SEARCH_RESULT) != null) {
0994:                            searchResultList = (Vector) state
0995:                                    .getAttribute(STATE_SEARCH_RESULT);
0996:                            if (searchResultList.size() > 0) {
0997:                                // if the current message is not in result list, make the current message to be the first one of search result
0998:                                state.setAttribute(STATE_DISPLAY_MESSAGE,
0999:                                        new DisplayMessage(
1000:                                                (String) searchResultList
1001:                                                        .get(0)));
1002:                                state.removeAttribute(STATE_SEARCH_REFRESH);
1003:                            }
1004:                            context.put("searchResultList", searchResultList);
1005:                        }
1006:
1007:                        // provide the category show list
1008:                        context.put("categoriesShowList", state
1009:                                .getAttribute(STATE_CATEGORIES_SHOW_LIST));
1010:                        // the topics has been expanded for outline
1011:                        context.put("expandAllTopics", state
1012:                                .getAttribute(STATE_EXPAND_ALL_TOPIC_FLAG));
1013:                        // provide the expanded message list
1014:                        context.put("expandedMessageList", state
1015:                                .getAttribute(STATE_EXPAND_MESSAGE_LIST));
1016:                    } else {
1017:                        allowNewTopic = DiscussionService
1018:                                .allowAddChannel(channelId);
1019:                    }
1020:
1021:                    if (state.getAttribute(STATE_DISPLAY_MESSAGE) != null) {
1022:                        DisplayMessage d = (DisplayMessage) state
1023:                                .getAttribute(STATE_DISPLAY_MESSAGE);
1024:                        try {
1025:                            channel.getDiscussionMessage(d.getId());
1026:                            context.put("currentMessage", state
1027:                                    .getAttribute(STATE_DISPLAY_MESSAGE));
1028:                        } catch (Exception e) {
1029:                            // current displayed message no longer exist, refresh the control pannel
1030:                            state.removeAttribute(STATE_DISPLAY_MESSAGE);
1031:                            String peid = ((JetspeedRunData) rundata)
1032:                                    .getJs_peid();
1033:                            schedulePeerFrameRefresh(VelocityPortletPaneledAction
1034:                                    .mainPanelUpdateId(peid)
1035:                                    + "." + CONTROL_PANEL);
1036:                        }
1037:                    }
1038:
1039:                    // inform the observing courier that we just updated the page...
1040:                    // if there are pending requests to do so they can be cleared
1041:                    justDelivered(state);
1042:                } catch (IdUnusedException e) {
1043:                    addAlert(state, rb.getString("cannotfin5"));
1044:                } catch (PermissionException e) {
1045:                    addAlert(state, rb.getString("youdonot2"));
1046:                }
1047:
1048:                context.put("allowEditChannel", new Boolean(DiscussionService
1049:                        .allowEditChannel(channelId)));
1050:                context
1051:                        .put("action", (String) state
1052:                                .getAttribute(STATE_ACTION));
1053:                context.put("service", DiscussionService.getInstance());
1054:                context.put("contentTypeImageService", state
1055:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1056:
1057:                context.put("allow_new_topic", new Boolean(allowNewTopic));
1058:                context.put("allow_new_category", new Boolean(allowNewTopic));
1059:                context.put("allow_remove_category", new Boolean(
1060:                        allowRemoveCategory));
1061:
1062:                context.put("panel-control", CONTROL_PANEL);
1063:                context.put("panel-monitor", MONITOR_PANEL);
1064:                context.put("panel-target", MONITOR_PANEL);
1065:                context.put("updated", (String) state
1066:                        .getAttribute(STATE_LIST_PANNEL_UPDATED));
1067:                state.setAttribute(STATE_LIST_PANNEL_UPDATED, "false");
1068:
1069:                context.put("visitedMessages", state
1070:                        .getAttribute(VISITED_MESSAGES));
1071:
1072:                if (state.getAttribute(DELETE_WARNING) != null) {
1073:                    addAlert(state, (String) state.getAttribute(DELETE_WARNING));
1074:                    state.removeAttribute(DELETE_WARNING);
1075:                }
1076:
1077:                return null;
1078:
1079:            } // buildListPanelContext
1080:
1081:            /**
1082:             * build the context for the Control panel (has a send field)
1083:             * 
1084:             * @return (optional) template name for this panel
1085:             */
1086:            public String buildControlPanelContext(VelocityPortlet portlet,
1087:                    Context context, RunData rundata, SessionState state) {
1088:                // we might be on the way to attachments...
1089:                if (state.getAttribute(GO_ATTACHMENTS) != null) {
1090:                    state.removeAttribute(GO_ATTACHMENTS);
1091:                    doAttachmentsNow(rundata, context);
1092:                }
1093:
1094:                context.put("tlang", rb);
1095:                String channelId = (String) state
1096:                        .getAttribute(STATE_CHANNEL_REF);
1097:                DiscussionChannel channel = null;
1098:                try {
1099:                    channel = DiscussionService.getDiscussionChannel(channelId);
1100:
1101:                    // possible error message
1102:                    String error = (String) state.getAttribute(STATE_ERROR);
1103:                    if (error != null) {
1104:                        context.put("message", error);
1105:                    }
1106:
1107:                    // is this user going to be able to post?
1108:                    boolean allowed = false;
1109:
1110:                    // if no channel, we can check the user's allow add discussion Channel(channelId)
1111:                    if (channel != null) {
1112:                        allowed = channel.allowAddMessage();
1113:                    } else {
1114:                        allowed = DiscussionService.allowAddChannel(channelId);
1115:                    }
1116:                    if (!allowed) {
1117:                        context.put("message", rb.getString("youdonot5")); // %%% or no message?
1118:                    }
1119:                    context.put("allow-send", new Boolean(allowed));
1120:
1121:                    DisplayMessage dMessage = (DisplayMessage) state
1122:                            .getAttribute(STATE_DISPLAY_MESSAGE);
1123:                    if (dMessage != null) {
1124:                        String mId = dMessage.getId();
1125:                        if (!mId.equals("")) {
1126:                            try {
1127:                                DiscussionMessage m = channel
1128:                                        .getDiscussionMessage(mId);
1129:                                context.put("currentMessage", m);
1130:
1131:                                DiscussionMessageHeader mHeader = m
1132:                                        .getDiscussionHeader();
1133:                                String replyTo = (String) state
1134:                                        .getAttribute(RESPOND_REPLY_TO);
1135:                                if (state.getAttribute(ATTACHMENTS) == null) {
1136:                                    state.setAttribute(ATTACHMENTS, mHeader
1137:                                            .getAttachments());
1138:                                }
1139:                                context.put("attachments", state
1140:                                        .getAttribute(ATTACHMENTS));
1141:                                if (mHeader.getDraft()) {
1142:                                    // a draft message
1143:                                    context
1144:                                            .put(
1145:                                                    "draftCategory",
1146:                                                    state
1147:                                                            .getAttribute(DRAFT_MESSAGE_CATEGORY) != null ? state
1148:                                                            .getAttribute(DRAFT_MESSAGE_CATEGORY)
1149:                                                            : mHeader
1150:                                                                    .getCategory());
1151:                                    context
1152:                                            .put(
1153:                                                    "draftBody",
1154:                                                    state
1155:                                                            .getAttribute(DRAFT_MESSAGE_BODY) != null ? state
1156:                                                            .getAttribute(DRAFT_MESSAGE_BODY)
1157:                                                            : m.getBody());
1158:                                    context
1159:                                            .put(
1160:                                                    "draftSubject",
1161:                                                    state
1162:                                                            .getAttribute(DRAFT_MESSAGE_SUBJECT) != null ? state
1163:                                                            .getAttribute(DRAFT_MESSAGE_SUBJECT)
1164:                                                            : mHeader
1165:                                                                    .getSubject());
1166:                                    if (m.getReplyToDepth() == 0) {
1167:                                        String style = (String) state
1168:                                                .getAttribute(DRAFT_MESSAGE_REPLY_STYLE);
1169:                                        if (style == null) {
1170:                                            style = "thread";
1171:                                        }
1172:                                        context.put("draftStyle", style);
1173:                                    }
1174:                                } else {
1175:                                    // respond to posted message
1176:                                    if (replyTo == null) {
1177:                                        replyTo = "totopic";
1178:                                    }
1179:                                    context.put("replyto", replyTo);
1180:                                    context.put("subject", state
1181:                                            .getAttribute(RESPOND_SUBJECT));
1182:                                    context.put("body", state
1183:                                            .getAttribute(RESPOND_BODY));
1184:                                }
1185:
1186:                                DiscussionMessage topic = m;
1187:                                StringBuffer messagePath = new StringBuffer(
1188:                                        Validator.escapeHtml(m
1189:                                                .getDiscussionHeader()
1190:                                                .getSubject()));
1191:                                while (topic.getReplyToDepth() != 0) {
1192:                                    replyTo = topic.getDiscussionHeader()
1193:                                            .getReplyTo();
1194:                                    topic = channel
1195:                                            .getDiscussionMessage(replyTo);
1196:                                    messagePath.insert(0, Validator
1197:                                            .escapeHtml(topic
1198:                                                    .getDiscussionHeader()
1199:                                                    .getSubject()
1200:                                                    + " > "));
1201:                                }
1202:                                messagePath.insert(0, Validator
1203:                                        .escapeHtml(topic.getDiscussionHeader()
1204:                                                .getCategory()
1205:                                                + " > "));
1206:                                context.put("messagePath", messagePath
1207:                                        .toString());
1208:                                context.put("topic", topic);
1209:                                context
1210:                                        .put(
1211:                                                "style",
1212:                                                topic
1213:                                                        .getProperties()
1214:                                                        .getProperty(
1215:                                                                ResourceProperties.PROP_REPLY_STYLE));
1216:                            } catch (Exception e) {
1217:                            } // try - catch
1218:                        } // if - else
1219:                    } // based on the DisplayMessage type
1220:                    context.put("channel", channel);
1221:                } catch (IdUnusedException e) {
1222:                    addAlert(state, rb.getString("cannotfin5"));
1223:                } catch (PermissionException e) {
1224:                    addAlert(state, rb.getString("youdonot1"));
1225:                }
1226:
1227:                context.put("panel-target", CONTROL_PANEL);
1228:
1229:                // put this pannel's name for the return url
1230:                context.put("panel-control", CONTROL_PANEL);
1231:
1232:                // set the action for form processing
1233:                context.put(Menu.CONTEXT_ACTION, state
1234:                        .getAttribute(STATE_ACTION));
1235:
1236:                // set the form field name for the send button
1237:                context.put("form-submit", BUTTON + "doSend");
1238:
1239:                // set the form field name for the send button
1240:                context.put("form-message", FORM_MESSAGE);
1241:
1242:                context.put("date", TimeService.newTime());
1243:                context.put("contentTypeImageService", state
1244:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1245:
1246:                context
1247:                        .put("action", (String) state
1248:                                .getAttribute(STATE_ACTION));
1249:
1250:                return null;
1251:
1252:            } // buildControlPanelContext
1253:
1254:            /**
1255:             * build the context for showing topic content (has a send field)
1256:             * 
1257:             * @return (optional) template name for this panel
1258:             */
1259:            public String buildContentContext(VelocityPortlet portlet,
1260:                    Context context, RunData rundata, SessionState state) {
1261:                String topicId = (String) state
1262:                        .getAttribute(STATE_SHOW_CONTENT_TOPIC_ID);
1263:                context.put("tlang", rb);
1264:                try {
1265:                    DiscussionChannel channel = DiscussionService
1266:                            .getDiscussionChannel((String) state
1267:                                    .getAttribute(STATE_CHANNEL_REF));
1268:                    DiscussionMessage msg = channel
1269:                            .getDiscussionMessage(topicId);
1270:
1271:                    context.put("topic", msg);
1272:                    context.put("channel", channel);
1273:
1274:                    String cat = msg.getDiscussionHeader().getCategory();
1275:                    List topicMsgIds = channel.getTopicMsgIds(cat);
1276:                    for (int i = 0; i < topicMsgIds.size(); i++) {
1277:                        if (topicMsgIds.get(i).equals(topicId)) {
1278:                            boolean goPT = false;
1279:                            boolean goNT = false;
1280:                            if ((i - 1) >= 0) {
1281:                                goPT = true;
1282:                            }
1283:                            if ((i + 1) < topicMsgIds.size()) {
1284:                                goNT = true;
1285:                            }
1286:                            context.put("goPTButton", new Boolean(goPT));
1287:                            context.put("goNTButton", new Boolean(goNT));
1288:                        }
1289:                    }
1290:                } catch (IdUnusedException e) {
1291:                    addAlert(state, rb.getString("cannotfin1"));
1292:                } catch (PermissionException e) {
1293:                    addAlert(state, rb.getString("yodonot2"));
1294:                }
1295:
1296:                context
1297:                        .put("action", (String) state
1298:                                .getAttribute(STATE_ACTION));
1299:                context.put("contentTypeImageService", state
1300:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1301:                return (String) getContext(rundata).get("template")
1302:                        + "-topic_content";
1303:
1304:            } // buildContentContext
1305:
1306:            /**
1307:             * Responding to the request of going to next topic within the current category
1308:             */
1309:            public void doNext_topic_content(RunData data, Context context) {
1310:                SessionState state = ((JetspeedRunData) data)
1311:                        .getPortletSessionState(((JetspeedRunData) data)
1312:                                .getJs_peid());
1313:
1314:                String topicId = (String) state
1315:                        .getAttribute(STATE_SHOW_CONTENT_TOPIC_ID);
1316:
1317:                try {
1318:                    DiscussionChannel channel = DiscussionService
1319:                            .getDiscussionChannel((String) state
1320:                                    .getAttribute(STATE_CHANNEL_REF));
1321:                    DiscussionMessage msg = channel
1322:                            .getDiscussionMessage(topicId);
1323:                    String cat = msg.getDiscussionHeader().getCategory();
1324:                    List topicMsgIds = channel.getTopicMsgIds(cat);
1325:                    int index = topicMsgIds.indexOf(topicId);
1326:                    if ((index != -1) && ((index + 1) < topicMsgIds.size())) {
1327:                        String prevId = (String) (topicMsgIds.get(index + 1));
1328:                        state.setAttribute(STATE_SHOW_CONTENT_TOPIC_ID, prevId);
1329:                    }
1330:                } catch (IdUnusedException e) {
1331:                    addAlert(state, rb.getString("cannotfin1"));
1332:                } catch (PermissionException e) {
1333:                    addAlert(state, rb.getString("yodonot2"));
1334:                }
1335:
1336:                state.setAttribute(STATE_MODE, MODE_SHOW_TOPIC_CONTENT);
1337:
1338:                String peid = ((JetspeedRunData) data).getJs_peid();
1339:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
1340:                        .mainPanelUpdateId(peid));
1341:
1342:            } // doNext_topic_content
1343:
1344:            /**
1345:             * Responding to the request of going to previous topic within the current category
1346:             */
1347:            public void doPrev_topic_content(RunData data, Context context) {
1348:                SessionState state = ((JetspeedRunData) data)
1349:                        .getPortletSessionState(((JetspeedRunData) data)
1350:                                .getJs_peid());
1351:
1352:                String topicId = (String) state
1353:                        .getAttribute(STATE_SHOW_CONTENT_TOPIC_ID);
1354:
1355:                try {
1356:                    DiscussionChannel channel = DiscussionService
1357:                            .getDiscussionChannel((String) state
1358:                                    .getAttribute(STATE_CHANNEL_REF));
1359:                    DiscussionMessage msg = channel
1360:                            .getDiscussionMessage(topicId);
1361:                    String cat = msg.getDiscussionHeader().getCategory();
1362:                    List topicMsgIds = channel.getTopicMsgIds(cat);
1363:                    int index = topicMsgIds.indexOf(topicId);
1364:                    if ((index != -1) && ((index - 1) >= 0)) {
1365:                        String prevId = (String) (topicMsgIds.get(index - 1));
1366:                        state.setAttribute(STATE_SHOW_CONTENT_TOPIC_ID, prevId);
1367:                    }
1368:                } catch (IdUnusedException e) {
1369:                    addAlert(state, rb.getString("cannotfin1"));
1370:                } catch (PermissionException e) {
1371:                    addAlert(state, rb.getString("yodonot2"));
1372:                }
1373:
1374:                state.setAttribute(STATE_MODE, MODE_SHOW_TOPIC_CONTENT);
1375:
1376:                String peid = ((JetspeedRunData) data).getJs_peid();
1377:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
1378:                        .mainPanelUpdateId(peid));
1379:
1380:            } // doPrev_topic_content
1381:
1382:            /**
1383:             * build the context for creating new topic (has a send field)
1384:             * 
1385:             * @return (optional) template name for this panel
1386:             */
1387:            public String buildNewTopicContext(VelocityPortlet portlet,
1388:                    Context context, RunData rundata, SessionState state) {
1389:                // we might be on the way to attachments...
1390:                if (state.getAttribute(GO_ATTACHMENTS) != null) {
1391:                    state.removeAttribute(GO_ATTACHMENTS);
1392:                    doAttachmentsNow(rundata, context);
1393:                }
1394:
1395:                String channelId = (String) state
1396:                        .getAttribute(STATE_CHANNEL_REF);
1397:                context.put("tlang", rb);
1398:                try {
1399:                    DiscussionChannel channel = DiscussionService
1400:                            .getDiscussionChannel(channelId);
1401:                    context.put("categories", sortedCategories(channel,
1402:                            STATE_SORTED_BY_CATEGORY_ALPHA, Boolean.TRUE
1403:                                    .toString()));
1404:                    context.put("date", TimeService.newTime());
1405:                    context.put("category", state
1406:                            .getAttribute(NEW_TOPIC_CATEGORY));
1407:                    context.put("newcategory", state
1408:                            .getAttribute(NEW_TOPIC_NEW_CATEGORY));
1409:                    context.put("newtopicbody", state
1410:                            .getAttribute(NEW_TOPIC_BODY));
1411:                    context.put("newtopicsubject", state
1412:                            .getAttribute(NEW_TOPIC_SUBJECT));
1413:                    context.put("newtopicreplystyle", state
1414:                            .getAttribute(NEW_TOPIC_REPLY_STYLE));
1415:                    context.put("contentTypeImageService", state
1416:                            .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1417:                    context.put("action", (String) state
1418:                            .getAttribute(STATE_ACTION));
1419:                    context.put("attachments", state.getAttribute(ATTACHMENTS));
1420:
1421:                    // is user allowed to save drats
1422:                    context.put("allowSaveDraft", Boolean.valueOf(channel
1423:                            .allowAddDraftMessage()));
1424:
1425:                    return (String) getContext(rundata).get("template")
1426:                            + "-Newtopic";
1427:                } catch (IdUnusedException e) {
1428:                    addAlert(state, rb.getString("cannotfin5"));
1429:                } catch (PermissionException e) {
1430:                    addAlert(state, rb.getString("youarenot4"));
1431:                }
1432:
1433:                return (String) getContext(rundata).get("template") + "-Layout";
1434:
1435:            } // buildNewTopicContext
1436:
1437:            /**
1438:             * build the context for creating new category (has a send field)
1439:             * 
1440:             * @return (optional) template name for this panel
1441:             */
1442:            public String buildNewCategoryContext(VelocityPortlet portlet,
1443:                    Context context, RunData rundata, SessionState state) {
1444:                String channelId = (String) state
1445:                        .getAttribute(STATE_CHANNEL_REF);
1446:                context.put("tlang", rb);
1447:
1448:                try {
1449:                    DiscussionChannel channel = DiscussionService
1450:                            .getDiscussionChannel(channelId);
1451:                    context.put("categories", sortedCategories(channel,
1452:                            STATE_SORTED_BY_CATEGORY_ALPHA, Boolean.TRUE
1453:                                    .toString()));
1454:                    context.put("contentTypeImageService", state
1455:                            .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1456:                    context.put("action", (String) state
1457:                            .getAttribute(STATE_ACTION));
1458:                    if (state.getAttribute(NEW_CATEGORY) != null) {
1459:                        context.put("newcategory", state
1460:                                .getAttribute(NEW_CATEGORY));
1461:                    }
1462:                    return (String) getContext(rundata).get("template")
1463:                            + "-Newcategory";
1464:                } catch (IdUnusedException e) {
1465:                    addAlert(state, rb.getString("cannotfin5"));
1466:                } catch (PermissionException e) {
1467:                    addAlert(state, rb.getString("youarenot4"));
1468:                }
1469:
1470:                return (String) getContext(rundata).get("template") + "-Layout";
1471:
1472:            } // buildNewCategoryContext
1473:
1474:            /**
1475:             * build the context for confirming the delete of message (has a send field)
1476:             * 
1477:             * @return (optional) template name for this panel
1478:             */
1479:            public String buildDeleteMessageConfirmContext(
1480:                    VelocityPortlet portlet, Context context, RunData rundata,
1481:                    SessionState state) {
1482:                String channelId = (String) state
1483:                        .getAttribute(STATE_CHANNEL_REF);
1484:                context.put("tlang", rb);
1485:                try {
1486:                    DiscussionChannel channel = DiscussionService
1487:                            .getDiscussionChannel(channelId);
1488:                    DiscussionMessage message = channel
1489:                            .getDiscussionMessage((String) state
1490:                                    .getAttribute(DELETE_MESSAGE_ID));
1491:                    context.put("message", message);
1492:                    context.put("delete_messages", channel.getThread(message));
1493:
1494:                    // can the user delete all the messages in the thread?
1495:                    Iterator i = channel.getThread(message);
1496:                    boolean allowRemove = true;
1497:                    while (i.hasNext() && allowRemove) {
1498:                        allowRemove = channel
1499:                                .allowRemoveMessage((DiscussionMessage) i
1500:                                        .next());
1501:                    }
1502:                    context.put("allowRemove", Boolean.valueOf(allowRemove));
1503:
1504:                    return (String) getContext(rundata).get("template")
1505:                            + "-DeleteTopicConfirm";
1506:                } catch (IdUnusedException e) {
1507:                    addAlert(state, rb.getString("cannotfin5"));
1508:                } catch (PermissionException e) {
1509:                    addAlert(state, rb.getString("youarenot1"));
1510:                }
1511:
1512:                return (String) getContext(rundata).get("template") + "-Layout";
1513:
1514:            } // buildDeleteMessageConfirmContext
1515:
1516:            /**
1517:             * build the context for confirming the delete of category (has a send field)
1518:             * 
1519:             * @return (optional) template name for this panel
1520:             */
1521:            public String buildDeleteCategoryConfirmContext(
1522:                    VelocityPortlet portlet, Context context, RunData rundata,
1523:                    SessionState state) {
1524:
1525:                String category = (String) state.getAttribute(DELETE_CATEGORY);
1526:                context.put("tlang", rb);
1527:                context.put("category", category);
1528:
1529:                // get all the messages within the category, that will be deleted
1530:                try {
1531:                    DiscussionChannel channel = (DiscussionChannel) DiscussionService
1532:                            .getChannel((String) state
1533:                                    .getAttribute(STATE_CHANNEL_REF));
1534:                    Iterator messages = channel.getThreads(category);
1535:                    context.put("delete_messages", messages);
1536:                } catch (IdUnusedException e) {
1537:                    addAlert(state, rb.getString("cannotfin5"));
1538:                    return (String) getContext(rundata).get("template");
1539:                } catch (PermissionException e) {
1540:                    addAlert(state, rb.getString("youarenot2"));
1541:                    return (String) getContext(rundata).get("template");
1542:                }
1543:
1544:                return (String) getContext(rundata).get("template")
1545:                        + "-DeleteCategoryConfirm";
1546:
1547:            } // buildDeleteCategoryConfirmContext
1548:
1549:            /**
1550:             * build the context for the reply form (has a send field)
1551:             * 
1552:             * @return (optional) template name for this panel
1553:             */
1554:            public String buildReplyContext(VelocityPortlet portlet,
1555:                    Context context, RunData rundata, SessionState state) {
1556:                // we might be on the way to attachments...
1557:                if (state.getAttribute(GO_ATTACHMENTS) != null) {
1558:                    state.removeAttribute(GO_ATTACHMENTS);
1559:                    doAttachmentsNow(rundata, context);
1560:                }
1561:
1562:                String replyToMessageId = (String) state
1563:                        .getAttribute(RESPOND_REPLY_TO);
1564:                String channelId = (String) state
1565:                        .getAttribute(STATE_CHANNEL_REF);
1566:                context.put("tlang", rb);
1567:                try {
1568:                    DiscussionChannel channel = DiscussionService
1569:                            .getDiscussionChannel(channelId);
1570:
1571:                    // is user allowed to save drats
1572:                    context.put("allowSaveDraft", Boolean.valueOf(channel
1573:                            .allowAddDraftMessage()));
1574:
1575:                    try {
1576:                        DiscussionMessage m = channel
1577:                                .getDiscussionMessage(replyToMessageId);
1578:                        context.put("currentMessage", m);
1579:
1580:                        context.put("subject", state
1581:                                .getAttribute(RESPOND_SUBJECT));
1582:                        context.put("body", state.getAttribute(RESPOND_BODY));
1583:
1584:                        DiscussionMessage topic = m;
1585:                        String replyTo = "";
1586:                        StringBuffer replyPath = new StringBuffer(Validator
1587:                                .escapeHtml(m.getDiscussionHeader()
1588:                                        .getSubject()));
1589:                        while (topic.getReplyToDepth() != 0) {
1590:                            replyTo = topic.getDiscussionHeader().getReplyTo();
1591:                            topic = channel.getDiscussionMessage(replyTo);
1592:                            replyPath.insert(0, Validator.escapeHtml(topic
1593:                                    .getDiscussionHeader().getSubject()
1594:                                    + " > "));
1595:                        }
1596:                        replyPath.insert(0, Validator.escapeHtml(topic
1597:                                .getDiscussionHeader().getCategory()
1598:                                + " > "));
1599:                        context.put("replyPath", replyPath.toString());
1600:                        context.put("topic", topic);
1601:                    } catch (IdUnusedException e) {
1602:                        addAlert(state, rb.getString("cannotfin2"));
1603:                    } catch (PermissionException e) {
1604:                        addAlert(state, rb.getString("youarenot3"));
1605:                    }
1606:                } catch (IdUnusedException e) {
1607:                    addAlert(state, rb.getString("cannotfin5"));
1608:                } catch (PermissionException e) {
1609:                    addAlert(state, rb.getString("youarenot4"));
1610:                }
1611:
1612:                context.put("contentTypeImageService", state
1613:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1614:                context.put("attachments", state.getAttribute(ATTACHMENTS));
1615:                context
1616:                        .put("action", (String) state
1617:                                .getAttribute(STATE_ACTION));
1618:
1619:                context.put("realDate", TimeService.newTime());
1620:
1621:                return (String) getContext(rundata).get("template") + "-Reply";
1622:
1623:            } // buildReplyContext
1624:
1625:            /**
1626:             * build the context for the reply preview (has a send field)
1627:             * 
1628:             * @return (optional) template name for this panel
1629:             */
1630:            public String buildReplyPreviewContext(VelocityPortlet portlet,
1631:                    Context context, RunData rundata, SessionState state) {
1632:                String replyToId = (String) state
1633:                        .getAttribute(RESPOND_REPLY_TO);
1634:
1635:                String channelId = (String) state
1636:                        .getAttribute(STATE_CHANNEL_REF);
1637:                context.put("tlang", rb);
1638:                try {
1639:                    DiscussionChannel channel = DiscussionService
1640:                            .getDiscussionChannel(channelId);
1641:
1642:                    // is user allowed to save drats
1643:                    context.put("allowSaveDraft", Boolean.valueOf(channel
1644:                            .allowAddDraftMessage()));
1645:
1646:                    try {
1647:                        DiscussionMessage m = channel
1648:                                .getDiscussionMessage(replyToId);
1649:                        context.put("currentMessage", m);
1650:
1651:                        DiscussionMessage topic = m;
1652:                        String replyTo = "";
1653:                        while (topic.getReplyToDepth() != 0) {
1654:                            replyTo = topic.getDiscussionHeader().getReplyTo();
1655:                            topic = channel.getDiscussionMessage(replyTo);
1656:                        }
1657:                        context.put("topic", topic);
1658:                    } catch (IdUnusedException e) {
1659:                        addAlert(state, rb.getString("cannotfin2"));
1660:                    } catch (PermissionException e) {
1661:                        addAlert(state, rb.getString("youarenot3"));
1662:                    }
1663:                } catch (IdUnusedException e) {
1664:                    addAlert(state, rb.getString("cannotfin5"));
1665:                } catch (PermissionException e) {
1666:                    addAlert(state, rb.getString("youarenot4"));
1667:                }
1668:
1669:                context.put("subject", state.getAttribute(RESPOND_SUBJECT));
1670:                context.put("body", state.getAttribute(RESPOND_BODY));
1671:                context.put("attachments", state
1672:                        .getAttribute(RESPOND_ATTACHMENT));
1673:                context.put("contentTypeImageService", state
1674:                        .getAttribute(STATE_CONTENT_TYPE_IMAGE_SERVICE));
1675:
1676:                context
1677:                        .put("action", (String) state
1678:                                .getAttribute(STATE_ACTION));
1679:                return (String) getContext(rundata).get("template")
1680:                        + "-Reply_Preview";
1681:
1682:            } // buildReplyPreviewContext
1683:
1684:            /**
1685:             * Post the draft message
1686:             */
1687:            public void doPost(RunData data, Context context) {
1688:                ParameterParser params = data.getParameters();
1689:                SessionState state = ((JetspeedRunData) data)
1690:                        .getPortletSessionState(((JetspeedRunData) data)
1691:                                .getJs_peid());
1692:
1693:                String messageId = params.getString("messageId");
1694:                String subject = ((String) params.getString("subject")).trim();
1695:                if (subject.length() == 0) {
1696:                    state.setAttribute(DRAFT_MESSAGE_SUBJECT, "");
1697:                    addAlert(state, rb.getString("plespe1"));
1698:                }
1699:                String body = params.getCleanString("body");
1700:                body = processFormattedTextFromBrowser(state, body);
1701:                state.setAttribute(DRAFT_MESSAGE_BODY, body);
1702:
1703:                String style = params.getString("style");
1704:                state.setAttribute(DRAFT_MESSAGE_REPLY_STYLE, style);
1705:
1706:                if (state.getAttribute(STATE_MESSAGE) == null) {
1707:                    try {
1708:                        DiscussionChannel channel = DiscussionService
1709:                                .getDiscussionChannel((String) state
1710:                                        .getAttribute(STATE_CHANNEL_REF));
1711:                        DiscussionMessageEdit postMessage = channel
1712:                                .editDiscussionMessage(messageId);
1713:
1714:                        postMessage.getDiscussionHeaderEdit().setSubject(
1715:                                subject);
1716:                        postMessage.setBody(body);
1717:
1718:                        // add the reply style property
1719:                        if (postMessage.getReplyToDepth() == 0) {
1720:                            ResourcePropertiesEdit pEdit = postMessage
1721:                                    .getPropertiesEdit();
1722:                            pEdit.addProperty(
1723:                                    ResourceProperties.PROP_REPLY_STYLE, style);
1724:                        }
1725:                        postMessage.getDiscussionHeaderEdit().setDraft(false);
1726:                        postMessage.getDiscussionHeaderEdit()
1727:                                .replaceAttachments(
1728:                                        (List) state.getAttribute(ATTACHMENTS));
1729:
1730:                        // update time
1731:                        postMessage.getDiscussionHeaderEdit().setDate(
1732:                                TimeService.newTime());
1733:
1734:                        channel.commitMessage(postMessage);
1735:                        state.setAttribute(STATE_DISPLAY_MESSAGE,
1736:                                new DisplayMessage(postMessage.getId()));
1737:                    } catch (IdUnusedException e) {
1738:                        addAlert(state, rb.getString("cannotfin5") + " "
1739:                                + messageId + " " + rb.getString("hasnotbee"));
1740:                    } catch (PermissionException e) {
1741:                        addAlert(state, rb.getString("youarenot5") + " "
1742:                                + rb.getString("posthemes"));
1743:                    } catch (InUseException e) {
1744:                        addAlert(state, rb.getString("themess"));
1745:                    }
1746:                }
1747:
1748:                if (state.getAttribute(STATE_MESSAGE) == null) {
1749:                    state.removeAttribute(DRAFT_MESSAGE_CATEGORY);
1750:                    state.removeAttribute(DRAFT_MESSAGE_SUBJECT);
1751:                    state.removeAttribute(DRAFT_MESSAGE_BODY);
1752:                    state.removeAttribute(DRAFT_MESSAGE_REPLY_STYLE);
1753:                    state.removeAttribute(ATTACHMENTS);
1754:
1755:                    // update the list panel
1756:                    String peid = ((JetspeedRunData) data).getJs_peid();
1757:                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
1758:                            .mainPanelUpdateId(peid)
1759:                            + "." + MONITOR_PANEL);
1760:
1761:                    // post sucessful
1762:                } // if-else
1763:
1764:            } // doPost
1765:
1766:            /**
1767:             * Save the draft message
1768:             */
1769:            public void doSave(RunData data, Context context) {
1770:                ParameterParser params = data.getParameters();
1771:                SessionState state = ((JetspeedRunData) data)
1772:                        .getPortletSessionState(((JetspeedRunData) data)
1773:                                .getJs_peid());
1774:                String messageId = params.getString("messageId");
1775:                String subject = ((String) params.getString("subject")).trim();
1776:                if (subject.length() == 0) {
1777:                    state.setAttribute(DRAFT_MESSAGE_SUBJECT, "");
1778:                    addAlert(state, rb.getString("plespe1"));
1779:                }
1780:                String body = params.getCleanString("body");
1781:                body = processFormattedTextFromBrowser(state, body);
1782:                state.setAttribute(DRAFT_MESSAGE_BODY, body);
1783:
1784:                if (state.getAttribute(STATE_MESSAGE) == null) {
1785:                    try {
1786:                        DiscussionChannel channel = DiscussionService
1787:                                .getDiscussionChannel((String) state
1788:                                        .getAttribute(STATE_CHANNEL_REF));
1789:                        DiscussionMessageEdit postMessage = channel
1790:                                .editDiscussionMessage(messageId);
1791:
1792:                        postMessage.getDiscussionHeaderEdit().setSubject(
1793:                                subject);
1794:                        postMessage.setBody(body);
1795:
1796:                        // add the reply style property
1797:                        if (postMessage.getReplyToDepth() == 0) {
1798:                            String style = params.getString("style");
1799:                            state
1800:                                    .setAttribute(DRAFT_MESSAGE_REPLY_STYLE,
1801:                                            style);
1802:                            ResourcePropertiesEdit pEdit = postMessage
1803:                                    .getPropertiesEdit();
1804:                            pEdit.addProperty(
1805:                                    ResourceProperties.PROP_REPLY_STYLE, style);
1806:                        }
1807:                        postMessage.getDiscussionHeaderEdit().setDraft(true);
1808:                        postMessage.getDiscussionHeaderEdit()
1809:                                .replaceAttachments(
1810:                                        (List) state.getAttribute(ATTACHMENTS));
1811:
1812:                        // update time
1813:                        postMessage.getDiscussionHeaderEdit().setDate(
1814:                                TimeService.newTime());
1815:
1816:                        channel.commitMessage(postMessage);
1817:                        state.setAttribute(STATE_DISPLAY_MESSAGE,
1818:                                new DisplayMessage(postMessage.getId()));
1819:                    } catch (IdUnusedException e) {
1820:                        addAlert(state, rb.getString("theid") + " " + messageId
1821:                                + " " + rb.getString("hasnotbee"));
1822:                    } catch (PermissionException e) {
1823:                        addAlert(state, rb.getString("youarenot5") + " "
1824:                                + rb.getString("viemes"));
1825:                    } catch (InUseException e) {
1826:                        addAlert(state, rb.getString("themess"));
1827:                    }
1828:                }
1829:
1830:                if (state.getAttribute(STATE_MESSAGE) == null) {
1831:                    // save successful
1832:                    state.removeAttribute(ATTACHMENTS);
1833:
1834:                    // update the list panel
1835:                    String peid = ((JetspeedRunData) data).getJs_peid();
1836:                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
1837:                            .mainPanelUpdateId(peid)
1838:                            + "." + MONITOR_PANEL);
1839:                } // if-else
1840:
1841:            } // doSave
1842:
1843:            /**
1844:             * Start a new category
1845:             */
1846:            public void doNew_category(RunData data, Context context) {
1847:                SessionState state = ((JetspeedRunData) data)
1848:                        .getPortletSessionState(((JetspeedRunData) data)
1849:                                .getJs_peid());
1850:
1851:                try {
1852:                    DiscussionChannel channel = DiscussionService
1853:                            .getDiscussionChannel((String) state
1854:                                    .getAttribute(STATE_CHANNEL_REF));
1855:
1856:                    ParameterParser params = data.getParameters();
1857:                    String category = StringUtil.trimToNull((String) params
1858:                            .getString("newcategory"));
1859:
1860:                    if (category == null) {
1861:                        addAlert(state, rb.getString("pleent"));
1862:                    } else {
1863:                        state.setAttribute(NEW_CATEGORY, category);
1864:
1865:                        List categories = channel.getCategories(true);
1866:
1867:                        if (categories.contains(category)) {
1868:                            addAlert(state, rb.getString("samcat"));
1869:                        } else {
1870:                            try {
1871:                                // Note: removed code to detect that the category already exists - we just "fail" quietly to add it again -ggolden
1872:                                addCategory(state, channel, category);
1873:
1874:                                // clean the input frame
1875:                                state.removeAttribute(STATE_DISPLAY_MESSAGE);
1876:
1877:                                // clean the state mode
1878:                                state.removeAttribute(STATE_MODE);
1879:                            } catch (InUseException e) {
1880:                                addAlert(state, rb.getString("someone")
1881:                                        + " channel.");
1882:                            } catch (PermissionException e) {
1883:                                addAlert(state, rb.getString("youdonot1"));
1884:                            }
1885:                        }
1886:                    }
1887:                } catch (IdUnusedException e) {
1888:                    addAlert(state, rb.getString("cannotfin5"));
1889:                } catch (PermissionException e) {
1890:                    addAlert(state, rb.getString("youdonot1"));
1891:                }
1892:            } // doNew_category
1893:
1894:            /**
1895:             * Start a new topic
1896:             */
1897:            public void doNew_topic(RunData data, Context context) {
1898:                SessionState state = ((JetspeedRunData) data)
1899:                        .getPortletSessionState(((JetspeedRunData) data)
1900:                                .getJs_peid());
1901:                try {
1902:                    DiscussionChannel channel = DiscussionService
1903:                            .getDiscussionChannel((String) state
1904:                                    .getAttribute(STATE_CHANNEL_REF));
1905:
1906:                    ParameterParser params = data.getParameters();
1907:                    String subject = ((String) params.getString("subject"))
1908:                            .trim();
1909:                    state.setAttribute(NEW_TOPIC_SUBJECT, subject);
1910:
1911:                    String body = params.getCleanString("body");
1912:                    body = processFormattedTextFromBrowser(state, body);
1913:                    state.setAttribute(NEW_TOPIC_BODY, body);
1914:
1915:                    String style = params.getString("style");
1916:                    state.setAttribute(NEW_TOPIC_REPLY_STYLE, style);
1917:
1918:                    boolean newCategory = true;
1919:                    String category = ((String) params.getString("newcategory"))
1920:                            .trim();
1921:                    if (category.length() == 0) {
1922:                        // no new category input
1923:                        state.setAttribute(NEW_TOPIC_NEW_CATEGORY, new Boolean(
1924:                                "false"));
1925:                        category = params.getString("category") != null ? ((String) params
1926:                                .getString("category")).trim()
1927:                                : "";
1928:                        state.setAttribute(NEW_TOPIC_CATEGORY, category);
1929:                        if (category.length() == 0) {
1930:                            // no category specified
1931:                            addAlert(state, rb.getString("plecho"));
1932:                        }
1933:                        newCategory = false;
1934:                    } else {
1935:                        // get the new category
1936:                        state.setAttribute(NEW_TOPIC_NEW_CATEGORY, new Boolean(
1937:                                "true"));
1938:                        state.setAttribute(NEW_TOPIC_CATEGORY, category);
1939:                        // Note: removed the check that the category already exists - we just quietly "fail" to add it again -ggoldne
1940:                    } // if
1941:
1942:                    if (state.getAttribute(STATE_MESSAGE) == null) {
1943:                        try {
1944:                            // message is a draft?
1945:                            boolean draft = false;
1946:
1947:                            String newTopic_option = params
1948:                                    .getString("eventSubmit_doNew_topic");
1949:
1950:                            if (newTopic_option.equals(rb
1951:                                    .getString("gen.savdra")))// We put this (not code Strings) because they binds with vm
1952:                            {
1953:                                draft = true;
1954:                            } else if (newTopic_option.equals(rb
1955:                                    .getString("gen.pos"))) {
1956:                                draft = false;
1957:                            } // if: draft?
1958:
1959:                            if (subject.length() == 0) {
1960:                                addAlert(state, rb.getString("plespe2"));
1961:                            } else {
1962:                                boolean sameTopic = false;
1963:                                Iterator l = channel.getTopics(category);
1964:                                while (l.hasNext()) {
1965:                                    if (subject.equals(((DiscussionMessage) l
1966:                                            .next()).getDiscussionHeader()
1967:                                            .getSubject())) {
1968:                                        addAlert(state, rb.getString("samtop"));
1969:                                        sameTopic = true;
1970:                                    }
1971:                                }
1972:
1973:                                if (!sameTopic) {
1974:                                    // add the reply style property
1975:                                    DiscussionMessageEdit addedMessageEdit = channel
1976:                                            .addDiscussionMessage("");
1977:                                    addedMessageEdit.setBody(body);
1978:
1979:                                    DiscussionMessageHeaderEdit hEdit = addedMessageEdit
1980:                                            .getDiscussionHeaderEdit();
1981:                                    hEdit.setCategory(category);
1982:                                    hEdit.setSubject(subject);
1983:                                    hEdit.setDraft(draft);
1984:                                    hEdit.replaceAttachments((List) state
1985:                                            .getAttribute(ATTACHMENTS));
1986:
1987:                                    ResourcePropertiesEdit pEdit = addedMessageEdit
1988:                                            .getPropertiesEdit();
1989:                                    pEdit
1990:                                            .addProperty(
1991:                                                    ResourceProperties.PROP_REPLY_STYLE,
1992:                                                    style);
1993:
1994:                                    // update time
1995:                                    hEdit.setDate(TimeService.newTime());
1996:
1997:                                    channel.commitMessage(addedMessageEdit);
1998:
1999:                                    // if the category is newly added
2000:                                    if (newCategory) {
2001:                                        try {
2002:                                            addCategory(state, channel,
2003:                                                    category);
2004:                                        } catch (InUseException e) {
2005:                                            addAlert(state, rb
2006:                                                    .getString("someone")
2007:                                                    + " channel.");
2008:                                        } catch (PermissionException e) {
2009:                                            addAlert(state, rb
2010:                                                    .getString("youdonot1"));
2011:                                        }
2012:                                    }
2013:                                    setCategoryExpanded(state, category, true,
2014:                                            channel);
2015:
2016:                                    // make it the current message
2017:                                    showMessage(data, addedMessageEdit.getId());
2018:                                    String peid = ((JetspeedRunData) data)
2019:                                            .getJs_peid();
2020:                                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
2021:                                            .mainPanelUpdateId(peid)
2022:                                            + "." + CONTROL_PANEL);
2023:                                } // if-else
2024:                            }
2025:                        } catch (PermissionException e) {
2026:                            addAlert(state, rb.getString("youarenot5") + " "
2027:                                    + rb.getString("statop"));
2028:                        }
2029:                    } // if category has been specified.
2030:                } catch (IdUnusedException e) {
2031:                    addAlert(state, rb.getString("cannotfin5"));
2032:                } catch (PermissionException e) {
2033:                    addAlert(state, rb.getString("youdonot1"));
2034:                }
2035:
2036:                if (state.getAttribute(STATE_MESSAGE) == null) {
2037:                    // add new topic sucessful
2038:                    state.removeAttribute(NEW_TOPIC_NEW_CATEGORY);
2039:                    state.removeAttribute(NEW_TOPIC_CATEGORY);
2040:                    state.removeAttribute(NEW_TOPIC_SUBJECT);
2041:                    state.removeAttribute(NEW_TOPIC_BODY);
2042:                    state.removeAttribute(NEW_TOPIC_REPLY_STYLE);
2043:
2044:                    // clean the state mode
2045:                    state.removeAttribute(STATE_MODE);
2046:
2047:                } // if-else
2048:
2049:            } // doNew_topic
2050:
2051:            /**
2052:             * Handle a user posting a respond message
2053:             */
2054:            public void doRespond(RunData runData, Context context) {
2055:                // access the portlet element id to find our state
2056:                String peid = ((JetspeedRunData) runData).getJs_peid();
2057:                SessionState state = ((JetspeedRunData) runData)
2058:                        .getPortletSessionState(peid);
2059:                ParameterParser params = runData.getParameters();
2060:
2061:                // message is a draft?
2062:                boolean draft = false;
2063:
2064:                String subject = StringUtil.trimToNull((String) params
2065:                        .getString("subject"));
2066:                state.setAttribute(RESPOND_SUBJECT, subject);
2067:
2068:                // get info from input
2069:                String body = params.getCleanString("body");
2070:                body = processFormattedTextFromBrowser(state, body);
2071:                state.setAttribute(RESPOND_BODY, body);
2072:
2073:                if (subject == null) {
2074:                    addAlert(state, rb.getString("plespe1"));
2075:                } else {
2076:                    boolean replyToTopic = state
2077:                            .getAttribute(STATE_REPLY_TOPIC) != null;
2078:                    boolean replyToMsg = state.getAttribute(STATE_REPLY_MSG) != null;
2079:
2080:                    String replyToId = "";
2081:                    if (replyToMsg) {
2082:                        replyToId = params.getString("messageId");
2083:                    } else if (replyToTopic) {
2084:                        replyToId = params.getString("topicId");
2085:                    }
2086:
2087:                    if (state.getAttribute(STATE_MESSAGE) == null) {
2088:                        try {
2089:                            DiscussionChannel channel = DiscussionService
2090:                                    .getDiscussionChannel((String) state
2091:                                            .getAttribute(STATE_CHANNEL_REF));
2092:
2093:                            try {
2094:                                // get the message thread before adding a new message
2095:                                DiscussionMessage originalMessage = channel
2096:                                        .getDiscussionMessage(replyToId);
2097:                                String category = originalMessage
2098:                                        .getDiscussionHeader().getCategory();
2099:                                Vector v = (Vector) ((Hashtable) state
2100:                                        .getAttribute(STATE_CATEGORIES_SHOW_LIST))
2101:                                        .get(category);
2102:                                int index = v.indexOf(originalMessage.getId());
2103:                                Iterator l = originalMessage.getReplies();
2104:
2105:                                // insert the response message
2106:                                DiscussionMessage addedMessage = channel
2107:                                        .addDiscussionMessage(
2108:                                                category,
2109:                                                subject,
2110:                                                draft,
2111:                                                replyToId,
2112:                                                (List) state
2113:                                                        .getAttribute(ATTACHMENTS),
2114:                                                body);
2115:
2116:                                // show the added message as the current message
2117:                                showMessage(runData, addedMessage.getId());
2118:
2119:                                if (!isMessageExpanded(state, originalMessage)) {
2120:                                    // the replied to message has not been expanded
2121:                                    setMessageExpanded(state, originalMessage,
2122:                                            true, channel);
2123:                                } else {
2124:                                    if ((l == null) || (!l.hasNext())) {
2125:                                        // if there is no reply message yet
2126:                                        v.add(index + 1, addedMessage.getId());
2127:                                    } else {
2128:                                        // if the new message is not a draft message, add to the bottom of non-drafts
2129:                                        int finalIndexOfShownThread = index;
2130:                                        int finalDraftIndex = 0;
2131:                                        while (l.hasNext()) {
2132:                                            DiscussionMessage next = (DiscussionMessage) l
2133:                                                    .next();
2134:                                            if (!next.getHeader().getDraft()) {
2135:                                                finalIndexOfShownThread = v
2136:                                                        .indexOf(next.getId());
2137:                                            } else {
2138:                                                finalDraftIndex = v
2139:                                                        .indexOf(next.getId());
2140:                                            }
2141:                                        }
2142:                                        if (finalIndexOfShownThread == index) {
2143:                                            // if there is no post yet
2144:                                            finalIndexOfShownThread = finalDraftIndex;
2145:                                        }
2146:                                        v.add(finalIndexOfShownThread + 1,
2147:                                                addedMessage.getId());
2148:                                        setCategoryShowList(state, category, v);
2149:                                    } // if - else
2150:                                } // if-else
2151:
2152:                            } catch (PermissionException e) {
2153:                                addAlert(state, rb.getString("youarenot5")
2154:                                        + " " + rb.getString("res"));
2155:                            } catch (IdUnusedException e) {
2156:                                addAlert(state, rb.getString("cannotfin3"));
2157:                            }
2158:                        } catch (PermissionException e) {
2159:                            addAlert(state, rb.getString("youdonot3"));
2160:                        } catch (IdUnusedException e) {
2161:                            addAlert(state, rb.getString("cannotfin5"));
2162:                        }
2163:                    }
2164:                } // if-else
2165:
2166:                if (state.getAttribute(STATE_MESSAGE) == null) {
2167:                    state.removeAttribute(ATTACHMENTS);
2168:                    // respond sucessful
2169:                    state.removeAttribute(RESPOND_REPLY_TO);
2170:                    state.removeAttribute(RESPOND_SUBJECT);
2171:                    state.removeAttribute(RESPOND_BODY);
2172:                    state.removeAttribute(RESPOND_ATTACHMENT);
2173:                    state.removeAttribute(STATE_MODE);
2174:
2175:                } // if-else
2176:
2177:            } // doRespond
2178:
2179:            /**
2180:             * Handle a user posting a drafted respond message
2181:             */
2182:            public void doRespond_draft(RunData runData, Context context) {
2183:                // access the portlet element id to find our state
2184:                String peid = ((JetspeedRunData) runData).getJs_peid();
2185:                SessionState state = ((JetspeedRunData) runData)
2186:                        .getPortletSessionState(peid);
2187:                ParameterParser params = runData.getParameters();
2188:                // get the reply to message id
2189:                // String replyType = params.getString("replyto");
2190:                String replyType = "";
2191:
2192:                boolean replyToTopic = state.getAttribute(STATE_REPLY_TOPIC) != null;
2193:                boolean replyToMsg = state.getAttribute(STATE_REPLY_MSG) != null;
2194:
2195:                if (replyToTopic)
2196:                    replyType = "totopic";
2197:                else if (replyToMsg)
2198:                    replyType = "tomessage";
2199:
2200:                String replyToId = "";
2201:                if (replyType.equalsIgnoreCase("tomessage")) {
2202:                    replyToId = params.getString("messageId");
2203:                } else if (replyType.equalsIgnoreCase("totopic")) {
2204:                    replyToId = params.getString("topicId");
2205:                }
2206:
2207:                // get info from input
2208:                String body = params.getCleanString("body");
2209:                body = processFormattedTextFromBrowser(state, body);
2210:                String subject = ((String) params.getString("subject")).trim();
2211:
2212:                state.setAttribute(RESPOND_SUBJECT, subject);
2213:                state.setAttribute(RESPOND_BODY, body);
2214:
2215:                if (state.getAttribute(STATE_MESSAGE) == null) {
2216:                    if (subject.length() == 0) {
2217:                        addAlert(state, rb.getString("plespe1"));
2218:                    } else {
2219:                        try {
2220:                            DiscussionChannel channel = DiscussionService
2221:                                    .getDiscussionChannel((String) state
2222:                                            .getAttribute(STATE_CHANNEL_REF));
2223:
2224:                            try {
2225:                                // message is a draft?
2226:                                boolean draft = true;
2227:
2228:                                // get the message thread before adding a new message
2229:                                DiscussionMessage originalMessage = channel
2230:                                        .getDiscussionMessage(replyToId);
2231:                                String category = originalMessage
2232:                                        .getDiscussionHeader().getCategory();
2233:                                Vector v = (Vector) ((Hashtable) state
2234:                                        .getAttribute(STATE_CATEGORIES_SHOW_LIST))
2235:                                        .get(category);
2236:                                int index = v.indexOf(originalMessage.getId());
2237:                                Iterator l = originalMessage.getReplies();
2238:
2239:                                // insert the response message
2240:                                DiscussionMessage addedMessage = channel
2241:                                        .addDiscussionMessage(
2242:                                                category,
2243:                                                subject,
2244:                                                draft,
2245:                                                replyToId,
2246:                                                (List) state
2247:                                                        .getAttribute(ATTACHMENTS),
2248:                                                body);
2249:                                showMessage(runData, addedMessage.getId());
2250:
2251:                                if (!isMessageExpanded(state, originalMessage)) {
2252:                                    // the replied to message has not been expanded
2253:                                    setMessageExpanded(state, originalMessage,
2254:                                            true, channel);
2255:                                } else {
2256:                                    if ((l == null) || (!l.hasNext())) {
2257:                                        // if there is no reply message yet
2258:                                        v.add(index + 1, addedMessage.getId());
2259:                                    } else {
2260:                                        // the replied to message has already been expanded
2261:                                        // if the new message is a draft message, add to the bottom of drafts
2262:                                        int firstNondraftIndex = -1;
2263:                                        while (l.hasNext()) {
2264:                                            DiscussionMessage next = (DiscussionMessage) l
2265:                                                    .next();
2266:                                            if (next.getDiscussionHeader()
2267:                                                    .getDraft()) {
2268:                                                firstNondraftIndex = v
2269:                                                        .indexOf(next.getId());
2270:                                            }
2271:                                        }
2272:
2273:                                        if (firstNondraftIndex == -1) {
2274:                                            // no draft till now
2275:                                            firstNondraftIndex = index + 1;
2276:                                        } else {
2277:                                            // otherwise
2278:                                            firstNondraftIndex++;
2279:                                        }
2280:                                        v.add(firstNondraftIndex, addedMessage
2281:                                                .getId());
2282:                                        setCategoryShowList(state, category, v);
2283:                                    } // if - else
2284:
2285:                                } // if-else
2286:
2287:                            } catch (PermissionException e) {
2288:                                addAlert(state, rb.getString("youarenot5")
2289:                                        + " " + rb.getString("res"));
2290:                            } catch (IdUnusedException e) {
2291:                                addAlert(state, rb.getString("cannotfin3"));
2292:                            }
2293:                        } catch (PermissionException e) {
2294:                            addAlert(state, rb.getString("youdonot3"));
2295:                        } catch (IdUnusedException e) {
2296:                            addAlert(state, rb.getString("cannotfin5"));
2297:                        }
2298:                    }
2299:                } // if
2300:
2301:                if (state.getAttribute(STATE_MESSAGE) == null) {
2302:                    // respond sucessful
2303:                    state.removeAttribute(RESPOND_REPLY_TO);
2304:                    state.removeAttribute(RESPOND_SUBJECT);
2305:                    state.removeAttribute(RESPOND_BODY);
2306:                    state.removeAttribute(RESPOND_ATTACHMENT);
2307:                    state.removeAttribute(STATE_MODE);
2308:
2309:                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
2310:                            .mainPanelUpdateId(peid));
2311:                } // if-else
2312:
2313:            } // doRespondDraft
2314:
2315:            /**
2316:             * Cancel from the reply page
2317:             */
2318:            public void doCancel_reply(RunData data, Context context) {
2319:                SessionState state = ((JetspeedRunData) data)
2320:                        .getPortletSessionState(((JetspeedRunData) data)
2321:                                .getJs_peid());
2322:                state.removeAttribute(RESPOND_REPLY_TO);
2323:                state.removeAttribute(RESPOND_SUBJECT);
2324:                state.removeAttribute(RESPOND_BODY);
2325:                state.removeAttribute(RESPOND_ATTACHMENT);
2326:                state.removeAttribute(ATTACHMENTS);
2327:                state.removeAttribute(STATE_MODE);
2328:
2329:            } // doCancel_reply
2330:
2331:            /**
2332:             * Cancel from the reply preview page
2333:             */
2334:            public void doCancel_reply_preview(RunData data, Context context) {
2335:                SessionState state = ((JetspeedRunData) data)
2336:                        .getPortletSessionState(((JetspeedRunData) data)
2337:                                .getJs_peid());
2338:                state.setAttribute(STATE_MODE, MODE_REPLY);
2339:
2340:            } // doCancel_reply
2341:
2342:            /**
2343:             * confirm the deletion of category
2344:             */
2345:            public void doDelete_category_confirm(RunData data, Context context) {
2346:                SessionState state = ((JetspeedRunData) data)
2347:                        .getPortletSessionState(((JetspeedRunData) data)
2348:                                .getJs_peid());
2349:                ParameterParser params = data.getParameters();
2350:                String category = FormattedText
2351:                        .decodeNumericCharacterReferences(params
2352:                                .getString("category"));
2353:                state.setAttribute(STATE_MODE, MODE_DELETE_CATEGORY_CONFIRM);
2354:                state.setAttribute(DELETE_CATEGORY, category);
2355:
2356:                String peid = ((JetspeedRunData) data).getJs_peid();
2357:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2358:                        .mainPanelUpdateId(peid));
2359:            } // doDelete_category_confirm
2360:
2361:            /**
2362:             * cancel the deletion of category
2363:             */
2364:            public void doCancel_delete_category(RunData data, Context context) {
2365:                SessionState state = ((JetspeedRunData) data)
2366:                        .getPortletSessionState(((JetspeedRunData) data)
2367:                                .getJs_peid());
2368:                state.setAttribute(DELETE_CATEGORY, "");
2369:                state.removeAttribute(STATE_MODE);
2370:            } // doCancel_delelete_category
2371:
2372:            /**
2373:             * delete the category
2374:             */
2375:            public void doDelete_category(RunData data, Context context) {
2376:                SessionState state = ((JetspeedRunData) data)
2377:                        .getPortletSessionState(((JetspeedRunData) data)
2378:                                .getJs_peid());
2379:                ParameterParser params = data.getParameters();
2380:                String category = params.getString("category");
2381:
2382:                try {
2383:                    // remove the category from the channel
2384:                    DiscussionChannel channel = (DiscussionChannel) DiscussionService
2385:                            .getChannel((String) state
2386:                                    .getAttribute(STATE_CHANNEL_REF));
2387:                    try {
2388:                        if (!channel.removeCategory(category)) {
2389:                            state.setAttribute(DELETE_WARNING, rb
2390:                                    .getString("cannotfin7"));
2391:                        }
2392:                    } catch (InUseException e) {
2393:                        state.setAttribute(DELETE_WARNING, rb
2394:                                .getString("someone")
2395:                                + " channel. ");
2396:                    } catch (PermissionException e) {
2397:                        state.setAttribute(DELETE_WARNING, rb
2398:                                .getString("youarenot2"));
2399:                    }
2400:
2401:                    // remove the category from the set of categories expanded on the user interface
2402:                    HashSet expandedCategories = (HashSet) state
2403:                            .getAttribute(STATE_EXPAND_CATEGORY_LIST);
2404:                    expandedCategories.remove(category);
2405:                    state.setAttribute(STATE_EXPAND_CATEGORY_LIST,
2406:                            expandedCategories);
2407:                } catch (IdUnusedException e) {
2408:                    state.setAttribute(DELETE_WARNING, rb
2409:                            .getString("cannotfin5"));
2410:                } catch (PermissionException e) {
2411:                    state.setAttribute(DELETE_WARNING, rb
2412:                            .getString("youarenot2"));
2413:                }
2414:
2415:                state.setAttribute(DELETE_CATEGORY, "");
2416:                state.removeAttribute(STATE_MODE);
2417:
2418:            } // doDelete_category
2419:
2420:            /**
2421:             * confirm the deletion of message
2422:             */
2423:            public void doDelete_message_confirm(RunData data, Context context) {
2424:                SessionState state = ((JetspeedRunData) data)
2425:                        .getPortletSessionState(((JetspeedRunData) data)
2426:                                .getJs_peid());
2427:                String messageId = data.getParameters().getString("messageId");
2428:
2429:                state.setAttribute(STATE_MODE, MODE_DELETE_MESSAGE_CONFIRM);
2430:                state.setAttribute(DELETE_MESSAGE_ID, messageId);
2431:
2432:                String peid = ((JetspeedRunData) data).getJs_peid();
2433:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2434:                        .mainPanelUpdateId(peid));
2435:            } // doDelete_message_confirm
2436:
2437:            public void doDelete_message(RunData data, Context context) {
2438:                SessionState state = ((JetspeedRunData) data)
2439:                        .getPortletSessionState(((JetspeedRunData) data)
2440:                                .getJs_peid());
2441:                ParameterParser params = data.getParameters();
2442:                String messageId = params.getString("messageId");
2443:
2444:                try {
2445:                    DiscussionChannel channel = (DiscussionChannel) DiscussionService
2446:                            .getDiscussionChannel((String) state
2447:                                    .getAttribute(STATE_CHANNEL_REF));
2448:
2449:                    try {
2450:                        DiscussionMessage message = (DiscussionMessageEdit) channel
2451:                                .getMessage(messageId);
2452:                        String category = message.getDiscussionHeader()
2453:                                .getCategory();
2454:
2455:                        // remove all the replies to the message
2456:                        Iterator replies = channel.getThread(message);
2457:                        while (replies.hasNext()) {
2458:                            // remove the message from the channel
2459:                            DiscussionMessage reply = (DiscussionMessage) replies
2460:                                    .next();
2461:                            channel.removeMessage(reply.getId());
2462:
2463:                            // remove the message from the show list
2464:                            Hashtable t = (Hashtable) state
2465:                                    .getAttribute(STATE_CATEGORIES_SHOW_LIST);
2466:                            Vector v = (Vector) t.get(category);
2467:                            v.remove(reply.getId());
2468:                            t.put(category, v);
2469:                            state.setAttribute(STATE_CATEGORIES_SHOW_LIST, t);
2470:
2471:                            // remove the message from the expanded message list if necessary
2472:                            Hashtable expandMessageTable = (Hashtable) state
2473:                                    .getAttribute(STATE_EXPAND_MESSAGE_LIST);
2474:                            HashSet expandMessageCategory = (HashSet) expandMessageTable
2475:                                    .get(category);
2476:                            if (expandMessageCategory != null) {
2477:                                expandMessageCategory.remove(reply.getId());
2478:                            }
2479:                        }
2480:                        // remove the message
2481:                        channel.removeMessage(message.getId());
2482:
2483:                        // remove the message from the show list
2484:                        Hashtable t = (Hashtable) state
2485:                                .getAttribute(STATE_CATEGORIES_SHOW_LIST);
2486:                        Vector v = (Vector) t.get(category);
2487:                        v.remove(messageId);
2488:                        t.put(category, v);
2489:                        state.setAttribute(STATE_CATEGORIES_SHOW_LIST, t);
2490:
2491:                        // remove the message from the expanded message list if necessary
2492:                        Hashtable expandMessageTable = (Hashtable) state
2493:                                .getAttribute(STATE_EXPAND_MESSAGE_LIST);
2494:                        HashSet expandMessageCategory = (HashSet) expandMessageTable
2495:                                .get(category);
2496:                        if (expandMessageCategory != null) {
2497:                            expandMessageCategory.remove(messageId);
2498:                        }
2499:                    } catch (IdUnusedException e) {
2500:                        state.setAttribute(DELETE_WARNING, rb
2501:                                .getString("cannotfin6"));
2502:                    } catch (PermissionException e) {
2503:                        // addAlert(state, rb.getString("youarenot1"));
2504:                    }
2505:                } catch (IdUnusedException e) {
2506:                    state.setAttribute(DELETE_WARNING, rb
2507:                            .getString("cannotfin5"));
2508:                } catch (PermissionException e) {
2509:                    state.setAttribute(DELETE_WARNING, rb
2510:                            .getString("youarenot1"));
2511:                }
2512:
2513:                state.removeAttribute(STATE_DISPLAY_MESSAGE);
2514:                state.removeAttribute(STATE_MODE);
2515:
2516:            } // dodelete_message
2517:
2518:            /**
2519:             * cancel the deletion of message
2520:             */
2521:            public void doCancel_delete_message(RunData data, Context context) {
2522:                SessionState state = ((JetspeedRunData) data)
2523:                        .getPortletSessionState(((JetspeedRunData) data)
2524:                                .getJs_peid());
2525:                state.removeAttribute(ATTACHMENTS);
2526:                state.setAttribute(DELETE_MESSAGE_ID, "");
2527:                state.removeAttribute(STATE_MODE);
2528:            } // doCancel_delelete_category
2529:
2530:            /**
2531:             * Handle the eventSubmit_doCancel_show_topic_content command to abort the show topic content page.
2532:             */
2533:            public void doCancel_show_topic_content(RunData data) {
2534:                SessionState state = ((JetspeedRunData) data)
2535:                        .getPortletSessionState(((JetspeedRunData) data)
2536:                                .getJs_peid());
2537:                state.removeAttribute(STATE_DISPLAY_MESSAGE);
2538:                state.removeAttribute(STATE_SHOW_CONTENT_TOPIC_ID);
2539:                state.removeAttribute(STATE_MODE);
2540:
2541:            } // doCancel_show_topic_content
2542:
2543:            /**
2544:             * Handle the eventSubmit_doCancel_draft to stop showing the draft message
2545:             */
2546:            public void doCancel_draft(RunData data) {
2547:                SessionState state = ((JetspeedRunData) data)
2548:                        .getPortletSessionState(((JetspeedRunData) data)
2549:                                .getJs_peid());
2550:                state.removeAttribute(DRAFT_MESSAGE_CATEGORY);
2551:                state.removeAttribute(DRAFT_MESSAGE_SUBJECT);
2552:                state.removeAttribute(DRAFT_MESSAGE_BODY);
2553:                state.removeAttribute(DRAFT_MESSAGE_REPLY_STYLE);
2554:                state.removeAttribute(STATE_DISPLAY_MESSAGE);
2555:                state.removeAttribute(ATTACHMENTS);
2556:
2557:                String peid = ((JetspeedRunData) data).getJs_peid();
2558:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2559:                        .mainPanelUpdateId(peid)
2560:                        + "." + MONITOR_PANEL);
2561:            } // doCancel_draft
2562:
2563:            /**
2564:             * Handle the eventSubmit_doCancel_new_topic to stop showing the new topic page
2565:             */
2566:            public void doCancel_new_topic(RunData data) {
2567:                SessionState state = ((JetspeedRunData) data)
2568:                        .getPortletSessionState(((JetspeedRunData) data)
2569:                                .getJs_peid());
2570:                state.removeAttribute(NEW_TOPIC_NEW_CATEGORY);
2571:                state.removeAttribute(NEW_TOPIC_CATEGORY);
2572:                state.removeAttribute(NEW_TOPIC_SUBJECT);
2573:                state.removeAttribute(NEW_TOPIC_BODY);
2574:                state.removeAttribute(NEW_TOPIC_REPLY_STYLE);
2575:                state.removeAttribute(STATE_DISPLAY_MESSAGE);
2576:
2577:                // clean state mode
2578:                state.removeAttribute(STATE_MODE);
2579:
2580:                state.removeAttribute(ATTACHMENTS);
2581:            } // doCancel_new_topic
2582:
2583:            /**
2584:             * Handle the eventSubmit_doCancel_new_category to stop showing the new category page
2585:             */
2586:            public void doCancel_new_category(RunData data) {
2587:                SessionState state = ((JetspeedRunData) data)
2588:                        .getPortletSessionState(((JetspeedRunData) data)
2589:                                .getJs_peid());
2590:                state.removeAttribute(STATE_DISPLAY_MESSAGE);
2591:
2592:                // clean state mode
2593:                state.removeAttribute(STATE_MODE);
2594:
2595:            } // doCancel_new_category
2596:
2597:            /**
2598:             * To show the topic content when "add attachments" is clicked
2599:             */
2600:            public void doShow_topic_content(RunData data, Context context) {
2601:                SessionState state = ((JetspeedRunData) data)
2602:                        .getPortletSessionState(((JetspeedRunData) data)
2603:                                .getJs_peid());
2604:
2605:                ParameterParser params = data.getParameters();
2606:                String topicId = params.getString("topicId");
2607:                state.setAttribute(STATE_SHOW_CONTENT_TOPIC_ID, topicId);
2608:                state.setAttribute(STATE_MODE, MODE_SHOW_TOPIC_CONTENT);
2609:
2610:                String peid = ((JetspeedRunData) data).getJs_peid();
2611:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2612:                        .mainPanelUpdateId(peid));
2613:
2614:            } // doShow_topic_content
2615:
2616:            /**
2617:             * Show the discussion message
2618:             */
2619:            public void doShow(RunData data, Context context) {
2620:                ParameterParser params = data.getParameters();
2621:
2622:                // set current message id
2623:                String messageId = params.getString("messageId");
2624:
2625:                showMessage(data, messageId);
2626:                String peid = ((JetspeedRunData) data).getJs_peid();
2627:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2628:                        .mainPanelUpdateId(peid)
2629:                        + "." + TOOLBAR_PANEL);
2630:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2631:                        .mainPanelUpdateId(peid)
2632:                        + "." + CONTROL_PANEL);
2633:            } // doShow
2634:
2635:            private void showMessage(RunData data, String messageId) {
2636:                SessionState state = ((JetspeedRunData) data)
2637:                        .getPortletSessionState(((JetspeedRunData) data)
2638:                                .getJs_peid());
2639:
2640:                try {
2641:                    String channelId = (String) state
2642:                            .getAttribute(STATE_CHANNEL_REF);
2643:                    DiscussionChannel channel = DiscussionService
2644:                            .getDiscussionChannel(channelId);
2645:
2646:                    try {
2647:                        DiscussionMessage m = channel
2648:                                .getDiscussionMessage(messageId);
2649:                        DiscussionMessageHeader mHeader = m
2650:                                .getDiscussionHeader();
2651:                        if (mHeader.getDraft()) {
2652:                            state.setAttribute(DRAFT_MESSAGE_CATEGORY, mHeader
2653:                                    .getCategory());
2654:                            state.setAttribute(DRAFT_MESSAGE_BODY, m.getBody());
2655:                            state.setAttribute(DRAFT_MESSAGE_SUBJECT, mHeader
2656:                                    .getSubject());
2657:                            if (m.getReplyToDepth() == 0) {
2658:                                ResourceProperties mProperties = m
2659:                                        .getProperties();
2660:                                state.setAttribute(DRAFT_MESSAGE_REPLY_STYLE,
2661:                                        mProperties.getProperty(mProperties
2662:                                                .getNamePropReplyStyle()));
2663:                            }
2664:                            if (mHeader.getAttachments() != null
2665:                                    && mHeader.getAttachments().size() > 0) {
2666:                                state.setAttribute(ATTACHMENTS, mHeader
2667:                                        .getAttachments());
2668:                            }
2669:                        } else {
2670:                            state.removeAttribute(ATTACHMENTS);
2671:                        }
2672:                        DisplayMessage dMessage = new DisplayMessage(messageId);
2673:                        state.setAttribute(STATE_DISPLAY_MESSAGE, dMessage);
2674:
2675:                        // update the visited messages list
2676:                        HashSet visited = (HashSet) state
2677:                                .getAttribute(VISITED_MESSAGES);
2678:                        visited.add(messageId);
2679:                        state.setAttribute(VISITED_MESSAGES, visited);
2680:                    } catch (IdUnusedException e) {
2681:                        addAlert(state, rb.getString("cannotfin2"));
2682:                    } catch (PermissionException e) {
2683:                        addAlert(state, rb.getString("youarenot3"));
2684:                    }
2685:                } catch (IdUnusedException e) {
2686:                    addAlert(state, rb.getString("cannotfin5"));
2687:                } catch (PermissionException e) {
2688:                    addAlert(state, rb.getString("youarenot4"));
2689:                }
2690:            } // showMessage
2691:
2692:            /**
2693:             * Preview the response
2694:             */
2695:            public void doPreview(RunData data, Context context) {
2696:                SessionState state = ((JetspeedRunData) data)
2697:                        .getPortletSessionState(((JetspeedRunData) data)
2698:                                .getJs_peid());
2699:                ParameterParser params = data.getParameters();
2700:
2701:                // save the input infos for the respond message
2702:                // String replyType = params.getString("replyto");
2703:                String replyType = "";
2704:
2705:                boolean replyToTopic = state.getAttribute(STATE_REPLY_TOPIC) != null;
2706:                boolean replyToMsg = state.getAttribute(STATE_REPLY_MSG) != null;
2707:
2708:                if (replyToTopic)
2709:                    replyType = "totopic";
2710:                else if (replyToMsg)
2711:                    replyType = "tomessage";
2712:
2713:                String replyToId = "";
2714:                if (replyType.equalsIgnoreCase("tomessage")) {
2715:                    replyToId = params.getString("messageId");
2716:                } else if (replyType.equalsIgnoreCase("totopic")) {
2717:                    replyToId = params.getString("topicId");
2718:                }
2719:                state.setAttribute(RESPOND_REPLY_TO, replyToId);
2720:
2721:                String subject = ((String) params.getString("subject")).trim();
2722:                state.setAttribute(RESPOND_SUBJECT, StringUtil
2723:                        .trimToZero(subject));
2724:
2725:                String body = params.getCleanString("body");
2726:                body = processFormattedTextFromBrowser(state, body);
2727:                state.setAttribute(RESPOND_BODY, body);
2728:
2729:                Vector attachments = (Vector) state.getAttribute(ATTACHMENTS);
2730:                state.setAttribute(RESPOND_ATTACHMENT, attachments);
2731:
2732:                if (subject == null || subject.length() == 0) {
2733:                    addAlert(state, rb.getString("plespe1"));
2734:                }
2735:
2736:                if (state.getAttribute(STATE_MESSAGE) == null) {
2737:                    state.setAttribute(STATE_MODE, MODE_REPLY_PREVIEW);
2738:                }
2739:
2740:            } // doPreview
2741:
2742:            /**
2743:             * set the form for replying
2744:             */
2745:            public void doSet_reply(RunData data, Context context) {
2746:                SessionState state = ((JetspeedRunData) data)
2747:                        .getPortletSessionState(((JetspeedRunData) data)
2748:                                .getJs_peid());
2749:                String currentMessageId = ((DisplayMessage) state
2750:                        .getAttribute(STATE_DISPLAY_MESSAGE)).getId();
2751:                state.setAttribute(RESPOND_REPLY_TO, currentMessageId);
2752:                state.setAttribute(RESPOND_ATTACHMENT, new Vector());
2753:                state.setAttribute(STATE_MODE, MODE_REPLY);
2754:
2755:                String peid = ((JetspeedRunData) data).getJs_peid();
2756:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2757:                        .mainPanelUpdateId(peid));
2758:
2759:            } // doSet_reply
2760:
2761:            /**
2762:             * set the form for replying message only
2763:             */
2764:            public void doSet_reply_msg(RunData data, Context context) {
2765:                SessionState state = ((JetspeedRunData) data)
2766:                        .getPortletSessionState(((JetspeedRunData) data)
2767:                                .getJs_peid());
2768:                String currentMessageId = ((DisplayMessage) state
2769:                        .getAttribute(STATE_DISPLAY_MESSAGE)).getId();
2770:                state.setAttribute(RESPOND_REPLY_TO, currentMessageId);
2771:                // empty attachment to start with
2772:                state.setAttribute(ATTACHMENTS, EntityManager
2773:                        .newReferenceList());
2774:                state.setAttribute(RESPOND_ATTACHMENT, state
2775:                        .getAttribute(ATTACHMENTS));
2776:                state.setAttribute(STATE_MODE, MODE_REPLY);
2777:                state.setAttribute(STATE_REPLY_MSG, Boolean.TRUE);
2778:                state.removeAttribute(STATE_REPLY_TOPIC);
2779:
2780:                String peid = ((JetspeedRunData) data).getJs_peid();
2781:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2782:                        .mainPanelUpdateId(peid));
2783:            } // doSet_reply_msg
2784:
2785:            /**
2786:             * set the form for replying
2787:             */
2788:            public void doSet_reply_topic(RunData data, Context context) {
2789:                SessionState state = ((JetspeedRunData) data)
2790:                        .getPortletSessionState(((JetspeedRunData) data)
2791:                                .getJs_peid());
2792:                state.setAttribute(RESPOND_REPLY_TO, data.getParameters()
2793:                        .getString("topicId"));
2794:                // empty attachment to start with
2795:                state.setAttribute(ATTACHMENTS, EntityManager
2796:                        .newReferenceList());
2797:                state.setAttribute(RESPOND_ATTACHMENT, state
2798:                        .getAttribute(ATTACHMENTS));
2799:                state.setAttribute(STATE_MODE, MODE_REPLY);
2800:                state.setAttribute(STATE_REPLY_TOPIC, Boolean.TRUE);
2801:                state.removeAttribute(STATE_REPLY_MSG);
2802:
2803:                String peid = ((JetspeedRunData) data).getJs_peid();
2804:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2805:                        .mainPanelUpdateId(peid));
2806:
2807:            } // doSet_reply_topic
2808:
2809:            /**
2810:             * get the control pannel ready for input new topic
2811:             */
2812:            public void doSet_new_topic(RunData data, Context context) {
2813:                SessionState state = ((JetspeedRunData) data)
2814:                        .getPortletSessionState(((JetspeedRunData) data)
2815:                                .getJs_peid());
2816:                state.removeAttribute(ATTACHMENTS);
2817:                state.setAttribute(STATE_MODE, MODE_NEW_TOPIC);
2818:                addAlert(state, "");
2819:
2820:                String peid = ((JetspeedRunData) data).getJs_peid();
2821:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2822:                        .mainPanelUpdateId(peid));
2823:
2824:            } // doSet_new_topic
2825:
2826:            /**
2827:             * get the control pannel ready for input new category
2828:             */
2829:            public void doSet_new_category(RunData data, Context context) {
2830:                SessionState state = ((JetspeedRunData) data)
2831:                        .getPortletSessionState(((JetspeedRunData) data)
2832:                                .getJs_peid());
2833:                state.removeAttribute(ATTACHMENTS);
2834:                state.removeAttribute(NEW_CATEGORY);
2835:                state.setAttribute(STATE_MODE, MODE_NEW_CATEGORY);
2836:                addAlert(state, "");
2837:
2838:                String peid = ((JetspeedRunData) data).getJs_peid();
2839:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
2840:                        .mainPanelUpdateId(peid));
2841:
2842:            } // doSet_new_category
2843:
2844:            /**
2845:             * Setup for options. %%% Note: not sure this and doUpdate are correct, not currently invoked (no menu entry) -ggolden
2846:             */
2847:            public String buildOptionsPanelContext(VelocityPortlet portlet,
2848:                    Context context, RunData rundata, SessionState state) {
2849:                // set the action for form processing
2850:                context.put(Menu.CONTEXT_ACTION, state
2851:                        .getAttribute(STATE_ACTION));
2852:                context.put("form-submit", BUTTON + "doUpdate");
2853:
2854:                // pick the "-customize" template based on the standard template name
2855:                String template = (String) getContext(rundata).get("template");
2856:                return template + "-customize";
2857:
2858:            } // buildOptionsPanelContext
2859:
2860:            /**
2861:             * doUpdate called for form input tags type="submit" named="eventSubmit_doUpdate"
2862:             */
2863:            public void doUpdate(RunData data, Context context) {
2864:                // access the portlet element id to find our state
2865:                String peid = ((JetspeedRunData) data).getJs_peid();
2866:                SessionState state = ((JetspeedRunData) data)
2867:                        .getPortletSessionState(peid);
2868:
2869:                // channel
2870:                String channel = data.getParameters().getString(FORM_CHANNEL);
2871:                if (!channel.equals((String) state
2872:                        .getAttribute(STATE_CHANNEL_REF))) {
2873:                    state.setAttribute(STATE_CHANNEL_REF, channel);
2874:                    if (Log.getLogger("chef").isDebugEnabled())
2875:                        Log.debug("chef", this  + ".doUpdate(): channel: "
2876:                                + channel);
2877:                    updateObservationOfChannel(state, ((JetspeedRunData) data)
2878:                            .getJs_peid());
2879:                    state.setAttribute(STATE_UPDATE, STATE_UPDATE);
2880:                }
2881:
2882:                // ascending
2883:                String ascending = data.getParameters().getString(
2884:                        FORM_ASCENDING);
2885:                Boolean asc = new Boolean(ascending);
2886:                if (!asc.equals((Boolean) state.getAttribute(STATE_ASCENDING))) {
2887:                    state.setAttribute(STATE_ASCENDING, asc);
2888:                    state.setAttribute(STATE_UPDATE, STATE_UPDATE);
2889:                }
2890:
2891:                // we are done with customization
2892:                // %%% clear or change mode to something like list to leave the options mode
2893:
2894:            } // doUpdate
2895:
2896:            /**
2897:             * get the categories sorted under the sorting criteria
2898:             */
2899:            private List sortedCategories(DiscussionChannel channel,
2900:                    String sortedBy, String sortedAsc) {
2901:                // categories
2902:                List categories = channel.getCategories(true);
2903:                if (categories == null)
2904:                    return null;
2905:
2906:                // return the categories alpha sorted
2907:                Collections.sort(categories);
2908:
2909:                return categories;
2910:
2911:            } // sortedCategories
2912:
2913:            /**
2914:             * transforms the Iterator to Vector
2915:             */
2916:            private Vector iterator_to_vector(Iterator l) {
2917:                Vector v = new Vector();
2918:                while (l.hasNext()) {
2919:                    v.add(l.next());
2920:                }
2921:                return v;
2922:            } // iterator_to_vector
2923:
2924:            /**
2925:             * set the category in the expanded category list?
2926:             */
2927:            private void setCategoryExpanded(SessionState state,
2928:                    String category, boolean expand, DiscussionChannel channel) {
2929:                HashSet s = (HashSet) state
2930:                        .getAttribute(STATE_EXPAND_CATEGORY_LIST);
2931:
2932:                if (expand) {
2933:                    s.add(category);
2934:
2935:                    // the show topics in category
2936:                    Vector topics = iterator_to_vector(channel
2937:                            .getTopics(category));
2938:                    Vector drafts = new Vector();
2939:                    Vector nonDrafts = new Vector();
2940:                    Vector showTopicsList = new Vector();
2941:
2942:                    // devide the drafted messages and posted messages; drafted message come first
2943:                    for (int j = 0; j < topics.size(); j++) {
2944:                        try {
2945:                            DiscussionMessage m = (DiscussionMessage) topics
2946:                                    .get(j);
2947:
2948:                            // filter out drafts not by this user (unless this user is a super user) %%% not sure I like this -zqian
2949:                            channel.getMessage(m.getId());
2950:                            if (m.getDiscussionHeader().getDraft()) {
2951:                                drafts.add(m.getId());
2952:                            } else {
2953:                                nonDrafts.add(m.getId());
2954:                            }
2955:                        } catch (PermissionException e) {
2956:                        } catch (IdUnusedException e) {
2957:                        }
2958:                    }
2959:                    showTopicsList.addAll(drafts);
2960:                    showTopicsList.addAll(nonDrafts);
2961:                    setCategoryShowList(state, category, showTopicsList);
2962:                } else {
2963:                    s.remove(category);
2964:                    setCategoryShowList(state, category, new Vector());
2965:
2966:                    // hide the show message
2967:                    Hashtable t = (Hashtable) state
2968:                            .getAttribute(STATE_EXPAND_MESSAGE_LIST);
2969:                    t.put(category, new HashSet());
2970:                }
2971:            } // setCategoryExpanded
2972:
2973:            /**
2974:             * Toggle the state attribute
2975:             * 
2976:             * @param stateName
2977:             *        The name of the state attribute to toggle
2978:             */
2979:            private void toggleState(RunData runData, String stateName) {
2980:                // access the portlet element id to find our state
2981:                // %%% use CHEF api instead of Jetspeed to get state
2982:                String peid = ((JetspeedRunData) runData).getJs_peid();
2983:                SessionState state = ((JetspeedRunData) runData)
2984:                        .getPortletSessionState(peid);
2985:
2986:                // toggle the state setting
2987:                boolean newValue = !((Boolean) state.getAttribute(stateName))
2988:                        .booleanValue();
2989:                state.setAttribute(stateName, new Boolean(newValue));
2990:
2991:            } // toggleState
2992:
2993:            /**
2994:             * Show the whole message hireachy
2995:             */
2996:            public void doExpand_all(RunData data, Context context) {
2997:                SessionState state = ((JetspeedRunData) data)
2998:                        .getPortletSessionState(((JetspeedRunData) data)
2999:                                .getJs_peid());
3000:
3001:                try {
3002:                    DiscussionChannel channel = DiscussionService
3003:                            .getDiscussionChannel((String) state
3004:                                    .getAttribute(STATE_CHANNEL_REF));
3005:
3006:                    // the sorting defaults for the outline view
3007:                    String sortedBy = "";
3008:                    String sortedAsc = (String) state
3009:                            .getAttribute(STATE_SORTED_ASC);
3010:
3011:                    // set default sort attribute
3012:                    sortedBy = (String) state.getAttribute(STATE_SORTED_BY);
3013:                    if ((!sortedBy.equals(STATE_SORTED_BY_TOPIC))
3014:                            && (!sortedBy.equals(STATE_SORTED_BY_AUTHOR))
3015:                            && (!sortedBy.equals(STATE_SORTED_BY_DATE))) {
3016:                        sortedBy = STATE_SORTED_BY_DATE;
3017:                        state.setAttribute(STATE_SORTED_BY, sortedBy);
3018:                    }
3019:
3020:                    // get the sorted categories Vector according to the current sorting criteria
3021:                    List categories = sortedCategories(channel, sortedBy,
3022:                            sortedAsc);
3023:                    if (categories != null) {
3024:                        for (Iterator i = categories.iterator(); i.hasNext();) {
3025:                            String cat = (String) i.next();
3026:
3027:                            setCategoryExpanded(state, cat, true, channel);
3028:                            Iterator topics = channel.getTopics(cat);
3029:                            while (topics.hasNext()) {
3030:                                // expand all the message in the thread
3031:                                DiscussionMessage m = (DiscussionMessage) topics
3032:                                        .next();
3033:                                setMessageExpanded(state, m, true, channel);
3034:                                Iterator replyThread = channel.getThread(m);
3035:                                while (replyThread.hasNext()) {
3036:                                    setMessageExpanded(state,
3037:                                            (DiscussionMessage) replyThread
3038:                                                    .next(), true, channel);
3039:                                }
3040:                            }
3041:                        }
3042:                    }
3043:                } catch (IdUnusedException e) {
3044:                    addAlert(state, rb.getString("cannotfin5"));
3045:                } catch (PermissionException e) {
3046:                    addAlert(state, rb.getString("youarenot4"));
3047:                }
3048:
3049:                toggleState(data, STATE_EXPAND_ALL_FLAG);
3050:
3051:                // schedule a refresh of the "List" panel
3052:                String peid = ((JetspeedRunData) data).getJs_peid();
3053:                // String address = ((EventObservingCourier) state.getAttribute(STATE_OBSERVER)).getDeliveryId();
3054:                // String elementID = ((EventObservingCourier) state.getAttribute(STATE_OBSERVER)).getElementId();
3055:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
3056:                        + MONITOR_PANEL);
3057:
3058:            } // doExpand_all
3059:
3060:            /**
3061:             * Hide the whole message hireachy
3062:             */
3063:            public void doCollapse_all(RunData data, Context context) {
3064:                SessionState state = ((JetspeedRunData) data)
3065:                        .getPortletSessionState(((JetspeedRunData) data)
3066:                                .getJs_peid());
3067:                try {
3068:                    DiscussionChannel channel = DiscussionService
3069:                            .getDiscussionChannel((String) state
3070:                                    .getAttribute(STATE_CHANNEL_REF));
3071:
3072:                    // the sorting defaults for the outline view
3073:                    String sortedBy = "";
3074:                    String sortedAsc = (String) state
3075:                            .getAttribute(STATE_SORTED_ASC);
3076:
3077:                    // set default sort attribute
3078:                    sortedBy = (String) state.getAttribute(STATE_SORTED_BY);
3079:                    if ((!sortedBy.equals(STATE_SORTED_BY_TOPIC))
3080:                            && (!sortedBy.equals(STATE_SORTED_BY_AUTHOR))
3081:                            && (!sortedBy.equals(STATE_SORTED_BY_DATE))) {
3082:                        sortedBy = STATE_SORTED_BY_DATE;
3083:                        state.setAttribute(STATE_SORTED_BY, sortedBy);
3084:                    }
3085:                    // get the sorted categories Vector according to the current sorting criteria
3086:                    List categories = sortedCategories(channel, sortedBy,
3087:                            sortedAsc);
3088:                    if (categories != null) {
3089:                        for (Iterator i = categories.iterator(); i.hasNext();) {
3090:                            setCategoryExpanded(state, (String) i.next(),
3091:                                    false, channel);
3092:                        }
3093:                    }
3094:                } catch (IdUnusedException e) {
3095:                    addAlert(state, rb.getString("cannotfin5"));
3096:                } catch (PermissionException e) {
3097:                    addAlert(state, rb.getString("youarenot4"));
3098:                }
3099:
3100:                // remove current display message due to close of categories
3101:                state.setAttribute(STATE_DISPLAY_MESSAGE,
3102:                        new DisplayMessage(""));
3103:
3104:                toggleState(data, STATE_EXPAND_ALL_FLAG);
3105:
3106:                // schedule a refresh of the "List" panel
3107:                String peid = ((JetspeedRunData) data).getJs_peid();
3108:                // String address = ((EventObservingCourier) state.getAttribute(STATE_OBSERVER)).getDeliveryId();
3109:                // String elementID = ((EventObservingCourier) state.getAttribute(STATE_OBSERVER)).getElementId();
3110:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
3111:                        + MONITOR_PANEL);
3112:
3113:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3114:                        .mainPanelUpdateId(peid)
3115:                        + "." + CONTROL_PANEL);
3116:
3117:            } // doCollapse_all
3118:
3119:            /**
3120:             * is the message id in the expanded message list?
3121:             */
3122:            private boolean isMessageExpanded(SessionState state,
3123:                    DiscussionMessage message) {
3124:                String category = message.getDiscussionHeader().getCategory();
3125:                Hashtable expandMessageTable = (Hashtable) state
3126:                        .getAttribute(STATE_EXPAND_MESSAGE_LIST);
3127:                HashSet s = (HashSet) expandMessageTable.get(category);
3128:                if (s != null)
3129:                    return s.contains(message);
3130:                else
3131:                    return false;
3132:
3133:            } // isMessageExpanded
3134:
3135:            /**
3136:             * set the message id in the expanded message list?
3137:             */
3138:            private void setMessageExpanded(SessionState state,
3139:                    DiscussionMessage message, boolean expand,
3140:                    DiscussionChannel channel) {
3141:                // get the current category message list
3142:                String category = message.getDiscussionHeader().getCategory();
3143:                Vector v = (Vector) ((Hashtable) state
3144:                        .getAttribute(STATE_CATEGORIES_SHOW_LIST))
3145:                        .get(category);
3146:
3147:                // get the show message
3148:                Hashtable expandMessageTable = (Hashtable) state
3149:                        .getAttribute(STATE_EXPAND_MESSAGE_LIST);
3150:                HashSet expandMessageCategory = (HashSet) expandMessageTable
3151:                        .get(category);
3152:                if (expandMessageCategory == null) {
3153:                    expandMessageCategory = new HashSet();
3154:                }
3155:
3156:                // get the index of the original message
3157:                int index = v.indexOf(message.getId());
3158:
3159:                if (expand) {
3160:                    if (!expandMessageCategory.contains(message)) {
3161:                        expandMessageCategory.add(message);
3162:                    }
3163:
3164:                    // divide the drafted messages and posted messages, drafted message come first
3165:                    Vector drafts = new Vector();
3166:                    Vector nonDrafts = new Vector();
3167:                    Vector showMessagesList = new Vector();
3168:                    Vector replies = iterator_to_vector(message.getReplies());
3169:                    for (int j = 0; j < replies.size(); j++) {
3170:                        DiscussionMessage m = (DiscussionMessage) replies
3171:                                .get(j);
3172:                        try {
3173:                            // filter out drafts not by this user (unless this user is a super user) %%% not sure I like this -zqian
3174:                            channel.getDiscussionMessage(m.getId());
3175:                            if (m.getDiscussionHeader().getDraft()) {
3176:                                drafts.add(m.getId());
3177:                            } else {
3178:                                nonDrafts.add(m.getId());
3179:                            }
3180:                        } catch (IdUnusedException e) {
3181:                        } catch (PermissionException e) {
3182:                        }
3183:                    }
3184:                    showMessagesList.addAll(drafts);
3185:                    showMessagesList.addAll(nonDrafts);
3186:
3187:                    v.addAll(index + 1, showMessagesList);
3188:                } else {
3189:                    expandMessageCategory.remove(message);
3190:                    // remove the whole thread
3191:                    Vector replies = iterator_to_vector(channel
3192:                            .getThread(message));
3193:                    for (int j = 0; j < replies.size(); j++) {
3194:                        DiscussionMessage m = (DiscussionMessage) replies
3195:                                .get(j);
3196:                        if (v.contains(m.getId())) {
3197:                            v.remove(m.getId());
3198:                        }
3199:                    }
3200:                }
3201:
3202:                setCategoryShowList(state, category, v);
3203:                expandMessageTable.put(category, expandMessageCategory);
3204:            } // setMessageExpanded
3205:
3206:            /**
3207:             * set the show list for each category
3208:             */
3209:            private void setCategoryShowList(SessionState state,
3210:                    String category, Vector showList) {
3211:                Hashtable t = (Hashtable) state
3212:                        .getAttribute(STATE_CATEGORIES_SHOW_LIST);
3213:                t.put(category, showList);
3214:                state.setAttribute(STATE_CATEGORIES_SHOW_LIST, t);
3215:            } // setCategoryShowList
3216:
3217:            /**
3218:             * doExpandmessage expand the message with the content and replies
3219:             */
3220:            public void doExpand_message(RunData data, Context context) {
3221:                String messageId = data.getParameters().getString("messageId");
3222:                SessionState state = ((JetspeedRunData) data)
3223:                        .getPortletSessionState(((JetspeedRunData) data)
3224:                                .getJs_peid());
3225:
3226:                try {
3227:                    DiscussionChannel channel = DiscussionService
3228:                            .getDiscussionChannel((String) state
3229:                                    .getAttribute(STATE_CHANNEL_REF));
3230:
3231:                    try {
3232:                        setMessageExpanded(state, channel
3233:                                .getDiscussionMessage(messageId), true, channel);
3234:                        showMessage(data, messageId);
3235:                        String peid = ((JetspeedRunData) data).getJs_peid();
3236:                        schedulePeerFrameRefresh(VelocityPortletPaneledAction
3237:                                .mainPanelUpdateId(peid)
3238:                                + "." + TOOLBAR_PANEL);
3239:                        schedulePeerFrameRefresh(VelocityPortletPaneledAction
3240:                                .mainPanelUpdateId(peid)
3241:                                + "." + CONTROL_PANEL);
3242:                    } catch (IdUnusedException e) {
3243:                        addAlert(state, rb.getString("cannotfin4"));
3244:                    } catch (PermissionException e) {
3245:                        addAlert(state, rb.getString("youarenot5") + " "
3246:                                + rb.getString("toview"));
3247:                    }
3248:                } catch (IdUnusedException e) {
3249:                    addAlert(state, rb.getString("cannotfin5"));
3250:                } catch (PermissionException e) {
3251:                    addAlert(state, rb.getString("youarenot4"));
3252:                }
3253:
3254:            } // doExpand_message
3255:
3256:            /**
3257:             * doCollapsemessage hides all the messages inside the category
3258:             */
3259:            public void doCollapse_message(RunData data, Context context) {
3260:                String messageId = data.getParameters().getString("messageId");
3261:                SessionState state = ((JetspeedRunData) data)
3262:                        .getPortletSessionState(((JetspeedRunData) data)
3263:                                .getJs_peid());
3264:                try {
3265:                    DiscussionChannel channel = DiscussionService
3266:                            .getDiscussionChannel((String) state
3267:                                    .getAttribute(STATE_CHANNEL_REF));
3268:                    try {
3269:                        DiscussionMessage message = channel
3270:                                .getDiscussionMessage(messageId);
3271:
3272:                        // set the message itself to be collapsed
3273:                        setMessageExpanded(state, message, false, channel);
3274:
3275:                        // the current message been displayed
3276:                        String currentMessageId = ((DisplayMessage) state
3277:                                .getAttribute(STATE_DISPLAY_MESSAGE)).getId();
3278:                        boolean found = false;
3279:
3280:                        Iterator replies = channel.getThread(message);
3281:                        while (replies.hasNext()) {
3282:                            DiscussionMessage nextReply = (DiscussionMessage) replies
3283:                                    .next();
3284:
3285:                            // set the message's reply to be collapsed
3286:                            setMessageExpanded(state, nextReply, false, channel);
3287:
3288:                            if ((!found)
3289:                                    && currentMessageId.equals(nextReply
3290:                                            .getId())) {
3291:                                // remove the current message due to close of thread
3292:                                state.setAttribute(STATE_DISPLAY_MESSAGE,
3293:                                        new DisplayMessage(""));
3294:                                found = true;
3295:                            }
3296:
3297:                        }
3298:                    } catch (IdUnusedException e) {
3299:                        addAlert(state, rb.getString("cannotfin4"));
3300:                    } catch (PermissionException e) {
3301:                        addAlert(state, rb.getString("youarenot5") + " "
3302:                                + rb.getString("toview"));
3303:                    }
3304:                } catch (IdUnusedException e) {
3305:                    addAlert(state, rb.getString("cannotfin5"));
3306:                } catch (PermissionException e) {
3307:                    addAlert(state, rb.getString("youdonot1"));
3308:                }
3309:
3310:                String peid = ((JetspeedRunData) data).getJs_peid();
3311:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3312:                        .mainPanelUpdateId(peid)
3313:                        + "." + CONTROL_PANEL);
3314:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3315:                        .mainPanelUpdateId(peid)
3316:                        + "." + TOOLBAR_PANEL);
3317:
3318:            } // doCollapse_message
3319:
3320:            /**
3321:             * doExpandcategory shows all the topics inside the category
3322:             */
3323:            public void doExpand_category(RunData data, Context context) {
3324:                String category = data.getParameters().getString("category");
3325:                SessionState state = ((JetspeedRunData) data)
3326:                        .getPortletSessionState(((JetspeedRunData) data)
3327:                                .getJs_peid());
3328:
3329:                String channelId = (String) state
3330:                        .getAttribute(STATE_CHANNEL_REF);
3331:                try {
3332:                    // get the current channel ID from state object
3333:                    DiscussionChannel channel = DiscussionService
3334:                            .getDiscussionChannel(channelId);
3335:                    setCategoryExpanded(state, category, true, channel);
3336:                } catch (IdUnusedException e) {
3337:                    addAlert(state, rb.getString("cannotfin5"));
3338:                } catch (PermissionException e) {
3339:                    addAlert(state, rb.getString("youdonot1"));
3340:                }
3341:
3342:            } // doExpand_category
3343:
3344:            /**
3345:             * doCollapsecategory hides all the topics inside the category
3346:             */
3347:            public void doCollapse_category(RunData data, Context context) {
3348:                SessionState state = ((JetspeedRunData) data)
3349:                        .getPortletSessionState(((JetspeedRunData) data)
3350:                                .getJs_peid());
3351:
3352:                String category = data.getParameters().getString("category");
3353:
3354:                String channelId = (String) state
3355:                        .getAttribute(STATE_CHANNEL_REF);
3356:                try {
3357:                    // get the current channel ID from state object
3358:                    DiscussionChannel channel = DiscussionService
3359:                            .getDiscussionChannel(channelId);
3360:
3361:                    String currentId = ((DisplayMessage) state
3362:                            .getAttribute(STATE_DISPLAY_MESSAGE)).getId();
3363:                    if (!currentId.equals("")) {
3364:                        DiscussionMessage message = channel
3365:                                .getDiscussionMessage(currentId);
3366:                        String mCategory = message.getDiscussionHeader()
3367:                                .getCategory();
3368:                        if (mCategory.equals(category)) {
3369:                            // remove current display message due to close of category
3370:                            state.setAttribute(STATE_DISPLAY_MESSAGE,
3371:                                    new DisplayMessage(""));
3372:                        }
3373:                    }
3374:                    setCategoryExpanded(state, category, false, channel);
3375:                } catch (IdUnusedException e) {
3376:                    addAlert(state, rb.getString("cannotfin5"));
3377:                } catch (PermissionException e) {
3378:                    addAlert(state, rb.getString("youdonot1"));
3379:                }
3380:
3381:                String peid = ((JetspeedRunData) data).getJs_peid();
3382:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3383:                        .mainPanelUpdateId(peid)
3384:                        + "." + CONTROL_PANEL);
3385:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3386:                        .mainPanelUpdateId(peid)
3387:                        + "." + TOOLBAR_PANEL);
3388:
3389:            } // doCollapse_category
3390:
3391:            /**
3392:             * the class which is using by one of the iFrames to show the content of selected message
3393:             */
3394:            public class DisplayMessage {
3395:                String m_id = null;
3396:
3397:                public DisplayMessage(String id) {
3398:                    m_id = id;
3399:                }
3400:
3401:                public void setId(String id) {
3402:                    m_id = id;
3403:                }
3404:
3405:                public String getId() {
3406:                    return m_id;
3407:                }
3408:
3409:            } // DisplayMessage
3410:
3411:            /**
3412:             * add the category to the state attribute
3413:             */
3414:            private void addCategory(SessionState state,
3415:                    DiscussionChannel channel, String category)
3416:                    throws InUseException, PermissionException {
3417:                try {
3418:                    channel.addCategory(category);
3419:
3420:                    HashSet expandedCategories = (HashSet) state
3421:                            .getAttribute(STATE_EXPAND_CATEGORY_LIST);
3422:                    expandedCategories.add(category);
3423:                    state.setAttribute(STATE_EXPAND_CATEGORY_LIST,
3424:                            expandedCategories);
3425:
3426:                    Hashtable h = (Hashtable) state
3427:                            .getAttribute(STATE_CATEGORIES_SHOW_LIST);
3428:                    h.put(category, new Vector());
3429:                    state.setAttribute(STATE_CATEGORIES_SHOW_LIST, h);
3430:                } catch (InUseException e) {
3431:                    throw new InUseException(channel.getId());
3432:                } catch (PermissionException e) {
3433:                    throw new PermissionException(null, null, null);
3434:                }
3435:
3436:            } // addCategory
3437:
3438:            /**
3439:             * Fire up the permissions editor, next request cycle
3440:             */
3441:            public void doPermissions(RunData data, Context context) {
3442:                String peid = ((JetspeedRunData) data).getJs_peid();
3443:                SessionState state = ((JetspeedRunData) data)
3444:                        .getPortletSessionState(peid);
3445:
3446:                // trigger the switch on the next request (which is going to happen after this action is processed with its redirect response to the build)
3447:                state.setAttribute(STATE_PERMISSIONS, STATE_PERMISSIONS);
3448:
3449:                // schedule a main refresh to excape from the toolbar panel
3450:                schedulePeerFrameRefresh(mainPanelUpdateId(peid));
3451:            }
3452:
3453:            /**
3454:             * Fire up the permissions editor
3455:             */
3456:            protected void doPermissionsNow(RunData data, Context context) {
3457:                // get into helper mode with this helper tool
3458:                startHelper(data.getRequest(), "sakai.permissions.helper");
3459:
3460:                String peid = ((JetspeedRunData) data).getJs_peid();
3461:                SessionState state = ((JetspeedRunData) data)
3462:                        .getPortletSessionState(peid);
3463:
3464:                String channelRefStr = (String) state
3465:                        .getAttribute(STATE_CHANNEL_REF);
3466:                Reference channelRef = EntityManager
3467:                        .newReference(channelRefStr);
3468:                String siteRef = SiteService.siteReference(channelRef
3469:                        .getContext());
3470:
3471:                // setup for editing the permissions of the site for this tool, using the roles of this site, too
3472:                state.setAttribute(PermissionsHelper.TARGET_REF, siteRef);
3473:
3474:                // ... with this description
3475:                state.setAttribute(PermissionsHelper.DESCRIPTION, rb
3476:                        .getString("setperfor")
3477:                        + SiteService.getSiteDisplay(channelRef.getContext()));
3478:
3479:                // ... showing only locks that are prpefixed with this
3480:                state.setAttribute(PermissionsHelper.PREFIX, "disc.");
3481:
3482:            } // doPermissions
3483:
3484:            /**
3485:             * Handle a \ request.
3486:             */
3487:            public void doSearch(RunData runData, Context context) {
3488:                // access the portlet element id to find our state
3489:                String peid = ((JetspeedRunData) runData).getJs_peid();
3490:                SessionState state = ((JetspeedRunData) runData)
3491:                        .getPortletSessionState(peid);
3492:
3493:                String channelId = (String) state
3494:                        .getAttribute(STATE_CHANNEL_REF);
3495:                // the sorting defaults for the outline view
3496:                String sortedAsc = (String) state
3497:                        .getAttribute(STATE_SORTED_ASC);
3498:                String sortedBy = (String) state.getAttribute(STATE_SORTED_BY);
3499:                if ((!sortedBy.equals(STATE_SORTED_BY_TOPIC))
3500:                        && (!sortedBy.equals(STATE_SORTED_BY_AUTHOR))
3501:                        && (!sortedBy.equals(STATE_SORTED_BY_DATE))) {
3502:                    sortedBy = STATE_SORTED_BY_DATE;
3503:                    state.setAttribute(STATE_SORTED_BY, sortedBy);
3504:                }
3505:
3506:                // read the search form field into the state object
3507:                String search = StringUtil.trimToNull(runData.getParameters()
3508:                        .getString(FORM_SEARCH));
3509:
3510:                Vector searchResultList = new Vector();
3511:
3512:                state.setAttribute(STATE_SEARCH_REFRESH, Boolean.TRUE);
3513:
3514:                // set the flag to go to the prev page on the next list
3515:                if (search == null) {
3516:                    state.removeAttribute(STATE_SEARCH);
3517:                } else {
3518:                    state.setAttribute(STATE_SEARCH, search);
3519:
3520:                    try {
3521:                        // get the current channel ID from state object
3522:                        DiscussionChannel channel = DiscussionService
3523:                                .getDiscussionChannel(channelId);
3524:
3525:                        // detect whether channel is existed
3526:                        if (channel != null) {
3527:                            // get the sorted categories Vector according to the current sorting criteria
3528:                            List categories = sortedCategories(channel,
3529:                                    sortedBy, sortedAsc);
3530:
3531:                            // provide the expanded category list
3532:                            HashSet expandedCategories = (HashSet) state
3533:                                    .getAttribute(STATE_EXPAND_CATEGORY_LIST);
3534:                            Hashtable showList = (Hashtable) state
3535:                                    .getAttribute(STATE_CATEGORIES_SHOW_LIST);
3536:                            Hashtable t = (Hashtable) state
3537:                                    .getAttribute(STATE_EXPAND_MESSAGE_LIST);
3538:                            HashSet s = new HashSet();
3539:
3540:                            if (categories != null) {
3541:                                String currentCategory = "";
3542:
3543:                                for (Iterator i = categories.iterator(); i
3544:                                        .hasNext();) {
3545:                                    // current category
3546:                                    currentCategory = (String) i.next();
3547:
3548:                                    // show list in category
3549:                                    Vector v = (Vector) showList
3550:                                            .get(currentCategory);
3551:                                    if (v == null)
3552:                                        v = new Vector();
3553:
3554:                                    s = (HashSet) t.get(currentCategory);
3555:
3556:                                    Iterator allMessagesInCategory = channel
3557:                                            .getThreads(currentCategory);
3558:
3559:                                    // find the any message in the category matches search result
3560:                                    if ((search != null)
3561:                                            && (!search.equals(""))) {
3562:                                        while (allMessagesInCategory.hasNext()) {
3563:                                            DiscussionMessage message = (DiscussionMessage) allMessagesInCategory
3564:                                                    .next();
3565:                                            if (StringUtil
3566:                                                    .containsIgnoreCase(
3567:                                                            message
3568:                                                                    .getDiscussionHeader()
3569:                                                                    .getSubject(),
3570:                                                            search)
3571:                                                    || StringUtil
3572:                                                            .containsIgnoreCase(
3573:                                                                    FormattedText
3574:                                                                            .convertFormattedTextToPlaintext(message
3575:                                                                                    .getBody()),
3576:                                                                    search)) {
3577:                                                // mark the search finding
3578:                                                searchResultList.add(message
3579:                                                        .getId());
3580:
3581:                                                // once the matching disucssion message is found, mark the corresponding category as expanded
3582:                                                expandedCategories
3583:                                                        .add(currentCategory);
3584:
3585:                                                // recursively mark the all containing messages as expanded
3586:                                                if (message.getReplyToDepth() > 0) {
3587:                                                    // get the parent messages, sorted by depth ascendingly
3588:                                                    Iterator parentMessages = parentMessageIterator(
3589:                                                            message, channel);
3590:                                                    while (parentMessages
3591:                                                            .hasNext()) {
3592:                                                        DiscussionMessage iMessage = (DiscussionMessage) parentMessages
3593:                                                                .next();
3594:
3595:                                                        // mark the message in shown list
3596:                                                        if (!v
3597:                                                                .contains(iMessage
3598:                                                                        .getId())) {
3599:                                                            v.add(iMessage
3600:                                                                    .getId());
3601:                                                        }
3602:
3603:                                                        // mark the message as expanded
3604:                                                        s.add(iMessage);
3605:                                                    }
3606:                                                }
3607:
3608:                                                // mark the message in shown list
3609:                                                if (!v
3610:                                                        .contains(message
3611:                                                                .getId())) {
3612:                                                    v.add(message.getId());
3613:                                                }
3614:                                            }
3615:                                        }
3616:                                    }
3617:
3618:                                    // assign back
3619:                                    showList.put(currentCategory, v);
3620:                                    t.put(currentCategory, s);
3621:                                }
3622:                                // update state variables
3623:                                state.setAttribute(STATE_SEARCH_RESULT,
3624:                                        searchResultList);
3625:                                state.setAttribute(STATE_CATEGORIES_SHOW_LIST,
3626:                                        showList);
3627:                                state.setAttribute(STATE_EXPAND_CATEGORY_LIST,
3628:                                        expandedCategories);
3629:                                state
3630:                                        .setAttribute(
3631:                                                STATE_EXPAND_MESSAGE_LIST, t);
3632:                            } // if: categories not null
3633:                        }
3634:                    } catch (IdUnusedException e) {
3635:                        addAlert(state, rb.getString("cannotfin5"));
3636:                    } catch (PermissionException e) {
3637:                        addAlert(state, rb.getString("youdonot2"));
3638:                    }
3639:                }
3640:
3641:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3642:                        .mainPanelUpdateId(peid)
3643:                        + "." + MONITOR_PANEL);
3644:
3645:                // disable auto-updates while in view mode
3646:                disableObservers(state);
3647:
3648:            } // doSearch
3649:
3650:            /**
3651:             * return an iterator consisting of all parent DiscussionMessage objects of the current DiscussionMessage item. 
3652:             * Sorted by depth ascendingly
3653:             */
3654:            protected Iterator parentMessageIterator(DiscussionMessage message,
3655:                    DiscussionChannel channel) {
3656:
3657:                // start the depth iteration stack with the topics of the channel
3658:                final Stack stack = new Stack();
3659:                DiscussionMessage m_message = message;
3660:
3661:                // construct the stack
3662:                boolean atTopLevel = false;
3663:                while (!atTopLevel) {
3664:                    if (((DiscussionMessage) m_message).getReplyToDepth() > 0) {
3665:                        String pId = ((DiscussionMessage) m_message)
3666:                                .getDiscussionHeader().getReplyTo();
3667:
3668:                        // detect whether channel is existed
3669:                        if (channel != null) {
3670:                            try {
3671:                                DiscussionMessage nMessage = channel
3672:                                        .getDiscussionMessage(pId);
3673:                                // mark the message in shown list
3674:                                if (!stack.contains(nMessage)) {
3675:                                    stack.push(nMessage);
3676:                                }
3677:                                // reassign
3678:                                m_message = nMessage;
3679:                            } catch (Exception e) {
3680:                                Log.warn("chef", e.toString() + pId
3681:                                        + e.toString());
3682:                            }
3683:                        }
3684:                    } else {
3685:                        atTopLevel = true;
3686:                    }
3687:                }
3688:
3689:                // prepare for return
3690:                List rv = new Vector();
3691:                while (!stack.empty()) {
3692:                    rv.add(stack.pop());
3693:                }
3694:                return rv.iterator();
3695:            }
3696:
3697:            /**
3698:             * Handle a Search Clear request.
3699:             */
3700:            public void doSearch_clear(RunData runData, Context context) {
3701:                // access the portlet element id to find our state
3702:                String peid = ((JetspeedRunData) runData).getJs_peid();
3703:                SessionState state = ((JetspeedRunData) runData)
3704:                        .getPortletSessionState(peid);
3705:
3706:                // clear the search
3707:                state.removeAttribute(STATE_SEARCH);
3708:                state.removeAttribute(STATE_SEARCH_RESULT);
3709:
3710:                // turn on auto refresh
3711:                enableObserver(state);
3712:
3713:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3714:                        .mainPanelUpdateId(peid)
3715:                        + "." + MONITOR_PANEL);
3716:
3717:                // make sure auto-updates are enabled
3718:                enableObserver(state);
3719:
3720:            } // doSearch_clear
3721:
3722:            /**
3723:             * Enable the observer, unless we are in search mode, where we want it disabled.
3724:             */
3725:            public void enableObserver(SessionState state) {
3726:                // we leave it disabled if we are searching, or if the user has last selected to be manual
3727:                if (state.getAttribute(STATE_SEARCH) != null) {
3728:                    disableObservers(state);
3729:                } else {
3730:                    enableObservers(state);
3731:                }
3732:
3733:            } // enableObserver
3734:
3735:            public void doView(RunData data, Context context) {
3736:                SessionState state = ((JetspeedRunData) data)
3737:                        .getPortletSessionState(((JetspeedRunData) data)
3738:                                .getJs_peid());
3739:
3740:                String viewMode = data.getParameters().getString("view");
3741:                state.setAttribute(STATE_SELECTED_VIEW, viewMode);
3742:
3743:                if (viewMode.equalsIgnoreCase(rb.getString("rowlay"))) {
3744:                    // not left - right layout
3745:                    state.setAttribute(STATE_LEFT_RIGHT_LAYOUT, new Boolean(
3746:                            false));
3747:
3748:                    String peid = ((JetspeedRunData) data).getJs_peid();
3749:                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
3750:                            .mainPanelUpdateId(peid));
3751:                } else if (viewMode.equalsIgnoreCase(rb.getString("collay"))) {
3752:                    // not left - right layout
3753:                    state.setAttribute(STATE_LEFT_RIGHT_LAYOUT, new Boolean(
3754:                            true));
3755:
3756:                    String peid = ((JetspeedRunData) data).getJs_peid();
3757:                    schedulePeerFrameRefresh(VelocityPortletPaneledAction
3758:                            .mainPanelUpdateId(peid));
3759:                }
3760:            } // doView
3761:
3762:            /**
3763:             * put those variables related to 2ndToolbar into context
3764:             */
3765:            private void add2ndToolbarFields(RunData data, Context context) {
3766:                SessionState state = ((JetspeedRunData) data)
3767:                        .getPortletSessionState(((JetspeedRunData) data)
3768:                                .getJs_peid());
3769:
3770:                context.put("searchString", state.getAttribute(STATE_SEARCH));
3771:                context.put("form_search", FORM_SEARCH);
3772:                context.put("selectedView", state
3773:                        .getAttribute(STATE_SELECTED_VIEW));
3774:
3775:            } // add2ndToolbarFields
3776:
3777:            /**
3778:             * navigate to previous message in the category
3779:             */
3780:            public void doPre_message(RunData data, Context context) {
3781:                SessionState state = ((JetspeedRunData) data)
3782:                        .getPortletSessionState(((JetspeedRunData) data)
3783:                                .getJs_peid());
3784:                String channelId = (String) state
3785:                        .getAttribute(STATE_CHANNEL_REF);
3786:                try {
3787:                    // get the current channel ID from state object
3788:                    DiscussionChannel channel = DiscussionService
3789:                            .getDiscussionChannel(channelId);
3790:
3791:                    DisplayMessage dMessage = (DisplayMessage) state
3792:                            .getAttribute(STATE_DISPLAY_MESSAGE);
3793:                    String currentId = dMessage.getId();
3794:                    if (!currentId.equals("")) {
3795:                        DiscussionMessage message = channel
3796:                                .getDiscussionMessage(currentId);
3797:                        String category = message.getDiscussionHeader()
3798:                                .getCategory();
3799:                        Vector messageIds = (Vector) ((Hashtable) state
3800:                                .getAttribute(STATE_CATEGORIES_SHOW_LIST))
3801:                                .get(category);
3802:                        dMessage.setId((String) messageIds.get(messageIds
3803:                                .indexOf(currentId) - 1));
3804:                        state.setAttribute(STATE_DISPLAY_MESSAGE, dMessage);
3805:                    }
3806:                } catch (IdUnusedException e) {
3807:                    addAlert(state, rb.getString("cannotfin5"));
3808:                } catch (PermissionException e) {
3809:                    addAlert(state, rb.getString("youdonot1"));
3810:                }
3811:
3812:                String peid = ((JetspeedRunData) data).getJs_peid();
3813:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3814:                        .mainPanelUpdateId(peid));
3815:            } // doPre_message
3816:
3817:            /**
3818:             * Navigate to next message in the category
3819:             */
3820:            public void doNext_message(RunData data, Context context) {
3821:                SessionState state = ((JetspeedRunData) data)
3822:                        .getPortletSessionState(((JetspeedRunData) data)
3823:                                .getJs_peid());
3824:                String channelId = (String) state
3825:                        .getAttribute(STATE_CHANNEL_REF);
3826:                try {
3827:                    // get the current channel ID from state object
3828:                    DiscussionChannel channel = DiscussionService
3829:                            .getDiscussionChannel(channelId);
3830:
3831:                    DisplayMessage dMessage = (DisplayMessage) state
3832:                            .getAttribute(STATE_DISPLAY_MESSAGE);
3833:                    String currentId = dMessage.getId();
3834:                    if (!currentId.equals("")) {
3835:                        DiscussionMessage message = channel
3836:                                .getDiscussionMessage(currentId);
3837:                        String category = message.getDiscussionHeader()
3838:                                .getCategory();
3839:                        Vector messageIds = (Vector) ((Hashtable) state
3840:                                .getAttribute(STATE_CATEGORIES_SHOW_LIST))
3841:                                .get(category);
3842:                        dMessage.setId((String) messageIds.get(messageIds
3843:                                .indexOf(currentId) + 1));
3844:                        state.setAttribute(STATE_DISPLAY_MESSAGE, dMessage);
3845:                    }
3846:                } catch (IdUnusedException e) {
3847:                    addAlert(state, rb.getString("cannotfin5"));
3848:                } catch (PermissionException e) {
3849:                    addAlert(state, rb.getString("youdonot1"));
3850:                }
3851:
3852:                String peid = ((JetspeedRunData) data).getJs_peid();
3853:                schedulePeerFrameRefresh(VelocityPortletPaneledAction
3854:                        .mainPanelUpdateId(peid));
3855:
3856:            } // doNext_message
3857:
3858:            /**
3859:             * Processes formatted text that is coming back from the browser (from the formatted text editing widget).
3860:             * 
3861:             * @param state
3862:             *        Used to pass in any user-visible alerts or errors when processing the text
3863:             * @param strFromBrowser
3864:             *        The string from the browser
3865:             * @return The formatted text
3866:             */
3867:            private String processFormattedTextFromBrowser(SessionState state,
3868:                    String strFromBrowser) {
3869:                StringBuffer alertMsg = new StringBuffer();
3870:                try {
3871:                    String text = FormattedText.processFormattedText(
3872:                            strFromBrowser, alertMsg);
3873:                    if (alertMsg.length() > 0)
3874:                        addAlert(state, alertMsg.toString());
3875:                    return text;
3876:                } catch (Exception e) {
3877:                    Log.warn("chef", this  + ": ", e);
3878:                    return strFromBrowser;
3879:                }
3880:            }
3881:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.