Source Code Cross Referenced for ChatAction.java in  » ERP-CRM-Financial » sakai » org » sakaiproject » chat » 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.chat.tool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************************
0002:         * $URL: https://source.sakaiproject.org/svn/chat/tags/sakai_2-4-1/chat-tool/tool/src/java/org/sakaiproject/chat/tool/ChatAction.java $
0003:         * $Id: ChatAction.java 9983 2006-05-25 20:07:58Z ggolden@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.chat.tool;
0021:
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:        import java.util.Vector;
0025:
0026:        import org.apache.commons.logging.Log;
0027:        import org.apache.commons.logging.LogFactory;
0028:        import org.sakaiproject.authz.api.PermissionsHelper;
0029:        import org.sakaiproject.chat.api.ChatChannel;
0030:        import org.sakaiproject.chat.api.ChatChannelEdit;
0031:        import org.sakaiproject.chat.api.ChatMessage;
0032:        import org.sakaiproject.chat.api.ChatMessageEdit;
0033:        import org.sakaiproject.chat.cover.ChatService;
0034:        import org.sakaiproject.cheftool.Context;
0035:        import org.sakaiproject.cheftool.JetspeedRunData;
0036:        import org.sakaiproject.cheftool.PortletConfig;
0037:        import org.sakaiproject.cheftool.RunData;
0038:        import org.sakaiproject.cheftool.VelocityPortlet;
0039:        import org.sakaiproject.cheftool.VelocityPortletPaneledAction;
0040:        import org.sakaiproject.cheftool.api.Menu;
0041:        import org.sakaiproject.cheftool.api.MenuItem;
0042:        import org.sakaiproject.cheftool.menu.MenuEntry;
0043:        import org.sakaiproject.cheftool.menu.MenuImpl;
0044:        import org.sakaiproject.component.cover.ServerConfigurationService;
0045:        import org.sakaiproject.entity.api.Reference;
0046:        import org.sakaiproject.entity.cover.EntityManager;
0047:        import org.sakaiproject.event.api.SessionState;
0048:        import org.sakaiproject.exception.IdInvalidException;
0049:        import org.sakaiproject.exception.IdUnusedException;
0050:        import org.sakaiproject.exception.IdUsedException;
0051:        import org.sakaiproject.exception.PermissionException;
0052:        import org.sakaiproject.presence.cover.PresenceService;
0053:        import org.sakaiproject.site.cover.SiteService;
0054:        import org.sakaiproject.time.api.Time;
0055:        import org.sakaiproject.time.api.TimeBreakdown;
0056:        import org.sakaiproject.time.cover.TimeService;
0057:        import org.sakaiproject.tool.api.Placement;
0058:        import org.sakaiproject.tool.cover.SessionManager;
0059:        import org.sakaiproject.tool.cover.ToolManager;
0060:        import org.sakaiproject.util.FormattedText;
0061:        import org.sakaiproject.util.PresenceObservingCourier;
0062:        import org.sakaiproject.util.ResourceLoader;
0063:        import org.sakaiproject.util.StringUtil;
0064:        import org.sakaiproject.util.Validator;
0065:
0066:        /**
0067:         * <p>
0068:         * ChatAction is the Sakai chat tool.
0069:         * </p>
0070:         */
0071:        public class ChatAction extends VelocityPortletPaneledAction {
0072:            /** Our logger. */
0073:            private static Log M_log = LogFactory.getLog(ChatAction.class);
0074:
0075:            /** Resource bundle using current language locale */
0076:            private static ResourceLoader rb = new ResourceLoader("chat");
0077:
0078:            private static final String MODE_CONFIRM_DELETE_MESSAGE = "confirmmdeletemessage";
0079:
0080:            /** portlet configuration parameter names. */
0081:            private static final String PARAM_CHANNEL = "channel";
0082:
0083:            private static final String PARAM_DISPLAY_DATE = "display-date";
0084:
0085:            private static final String PARAM_DISPLAY_TIME = "display-time";
0086:
0087:            private static final String PARAM_DISPLAY_USER = "display-user";
0088:
0089:            private static final String PARAM_SOUND_ALERT = "sound-alert";
0090:
0091:            private static final String PARAM_MEMBER_FILTER = "member-filter";
0092:
0093:            private static final String PARAM_FILTER_TYPE = "filter-type";
0094:
0095:            private static final String PARAM_FILTER_PARAM = "filter-param";
0096:
0097:            /** Configure form field names. */
0098:            private static final String FORM_CHANNEL = "channel";
0099:
0100:            private static final String FORM_NEW_CHANNEL = "new-channel";
0101:
0102:            private static final String FORM_FILTER_TYPE = "filter-type";
0103:
0104:            private static final String FORM_FILTER_PARAM_DAYS = "filter-param-days";
0105:
0106:            private static final String FORM_FILTER_PARAM_NUMBER = "filter-param-number";
0107:
0108:            /** Message filter names */
0109:            private static final String FILTER_BY_NUMBER = "SelectMessagesByNumber";
0110:
0111:            private static final String FILTER_BY_TIME = "SelectMessagesByTime";
0112:
0113:            private static final String FILTER_TODAY = "SelectTodaysMessages";
0114:
0115:            private static final String FILTER_ALL = "SelectAllMessages";
0116:
0117:            private static final String[] ALL_FILTERS = { FILTER_BY_NUMBER,
0118:                    FILTER_BY_TIME, FILTER_TODAY, FILTER_ALL };
0119:
0120:            /** Default values to use in case of input errors */
0121:            private static final int DEFAULT_PARAM = 0;
0122:
0123:            private static final int DEFAULT_DAYS = 3;
0124:
0125:            private static final int DEFAULT_MSGS = 12;
0126:
0127:            /** Control form field names. */
0128:            private static final String FORM_MESSAGE = "message";
0129:
0130:            /** names and values of request parameters to select sub-panels */
0131:            private static final String MONITOR_PANEL = "List";
0132:
0133:            private static final String CONTROL_PANEL = "Control";
0134:
0135:            private static final String PRESENCE_PANEL = "Presence";
0136:
0137:            private static final String TOOLBAR_PANEL = "Toolbar";
0138:
0139:            /** state attribute names. */
0140:            private static final String STATE_CHANNEL_REF = "channelId";
0141:
0142:            private static final String STATE_SITE = "siteId";
0143:
0144:            private static final String STATE_DISPLAY_DATE = "display-date";
0145:
0146:            private static final String STATE_DISPLAY_TIME = "display-time";
0147:
0148:            private static final String STATE_DISPLAY_USER = "display-user";
0149:
0150:            private static final String STATE_SOUND_ALERT = "sound-alert";
0151:
0152:            private static final String STATE_UPDATE = "update";
0153:
0154:            private static final String STATE_CHANNEL_PROBLEM = "channel-problem";
0155:
0156:            private static final String STATE_FILTER_TYPE = "filter-type";
0157:
0158:            private static final String STATE_FILTER_PARAM = "filter-param";
0159:
0160:            private static final String STATE_MESSAGE_FILTER = "message-filter";
0161:
0162:            private static final String STATE_MORE_SELECTED = "more-selected";
0163:
0164:            private static final String STATE_MORE_MESSAGES_LABEL = "more-messages-label";
0165:
0166:            private static final String STATE_MORE_MESSAGES_FILTER = "more-messages-filter";
0167:
0168:            private static final String STATE_FEWER_MESSAGES_LABEL = "fewer-messages-label";
0169:
0170:            private static final String STATE_FEWER_MESSAGES_FILTER = "fewer-messages-filter";
0171:
0172:            private static final String STATE_BROWSER = "browser";
0173:
0174:            private static final String STATE_CHAT_PRESENCE_OBSERVER = STATE_OBSERVER2;
0175:
0176:            private static final String STATE_COLOR_MAPPER = "color-mapper";
0177:
0178:            private static final String STATE_MAIN_MESSAGE = "message-for-chat-layout";
0179:
0180:            private static final String NEW_CHAT_CHANNEL = "new-chat-channel";
0181:
0182:            /** Resource property on the message indicating that the message had been deleted */
0183:            private static final String PROPERTY_MESSAGE_DELETED = "deleted";
0184:
0185:            private static final String TIME_DATE_SELECT = "selected-time-date-display";
0186:
0187:            /** State attribute set when we need to go into permissions mode. */
0188:            private static final String STATE_PERMISSIONS = "sakai:chat:permissions";
0189:
0190:            /**
0191:             * Populate the state object, if needed.
0192:             */
0193:            protected void initState(SessionState state,
0194:                    VelocityPortlet portlet, JetspeedRunData rundata) {
0195:                super .initState(state, portlet, rundata);
0196:
0197:                // detect that we have not done this, yet
0198:                if (state.getAttribute(STATE_CHANNEL_REF) == null) {
0199:                    PortletConfig config = portlet.getPortletConfig();
0200:
0201:                    // read the channel from configuration, or, if not specified, use the default for the page
0202:                    String channel = StringUtil.trimToNull(config
0203:                            .getInitParameter(PARAM_CHANNEL));
0204:                    if (channel == null) {
0205:                        channel = ChatService.channelReference(ToolManager
0206:                                .getCurrentPlacement().getContext(),
0207:                                SiteService.MAIN_CONTAINER);
0208:                    }
0209:
0210:                    state.setAttribute(STATE_CHANNEL_REF, channel);
0211:
0212:                    if (state.getAttribute(STATE_DISPLAY_DATE) == null) {
0213:                        state.setAttribute(STATE_DISPLAY_DATE, new Boolean(
0214:                                config.getInitParameter(PARAM_DISPLAY_DATE)));
0215:                    }
0216:
0217:                    if (state.getAttribute(STATE_DISPLAY_TIME) == null) {
0218:                        state.setAttribute(STATE_DISPLAY_TIME, new Boolean(
0219:                                config.getInitParameter(PARAM_DISPLAY_TIME)));
0220:                    }
0221:
0222:                    if (state.getAttribute(STATE_DISPLAY_USER) == null) {
0223:                        state.setAttribute(STATE_DISPLAY_USER, new Boolean(
0224:                                config.getInitParameter(PARAM_DISPLAY_USER)));
0225:                    }
0226:
0227:                    if (state.getAttribute(STATE_SOUND_ALERT) == null) {
0228:                        state.setAttribute(STATE_SOUND_ALERT, new Boolean(
0229:                                config.getInitParameter(PARAM_SOUND_ALERT)));
0230:                    }
0231:
0232:                    if (state.getAttribute(STATE_COLOR_MAPPER) == null) {
0233:                        ColorMapper mapper = new ColorMapper();
0234:
0235:                        // always set this user's color to first color (red)
0236:                        mapper.getColor(StringUtil.trimToZero(SessionManager
0237:                                .getCurrentSessionUserId()));
0238:
0239:                        state.setAttribute(STATE_COLOR_MAPPER, mapper);
0240:                    }
0241:
0242:                    if (state.getAttribute(STATE_FILTER_TYPE) == null) {
0243:                        String filter_type = config.getInitParameter(
0244:                                PARAM_FILTER_TYPE, FILTER_BY_TIME);
0245:                        String filter_param = config.getInitParameter(
0246:                                PARAM_FILTER_PARAM, String
0247:                                        .valueOf(DEFAULT_DAYS));
0248:
0249:                        updateMessageFilters(state, filter_type, filter_param);
0250:                    }
0251:
0252:                    // the event resource reference pattern to watch for
0253:                    // setup the observer to notify our MONITOR_PANEL panel (inside the Main panel)
0254:                    if (state.getAttribute(STATE_OBSERVER) == null) {
0255:                        // get the current tool placement
0256:                        Placement placement = ToolManager.getCurrentPlacement();
0257:
0258:                        // location is just placement
0259:                        String location = placement.getId();
0260:
0261:                        // the html element to update on delivery
0262:                        String elementId = MONITOR_PANEL;
0263:                        Reference r = EntityManager.newReference(channel);
0264:                        String pattern = ChatService.messageReference(r
0265:                                .getContext(), r.getId(), "");
0266:                        boolean wantsBeeps = ((Boolean) state
0267:                                .getAttribute(STATE_SOUND_ALERT))
0268:                                .booleanValue();
0269:
0270:                        state.setAttribute(STATE_OBSERVER,
0271:                                new ChatObservingCourier(location, elementId,
0272:                                        pattern, wantsBeeps));
0273:                    }
0274:
0275:                    // the event resource reference pattern to watch for
0276:                    // setup the observer to notify our PRESENCE_PANEL panel (inside the Main panel)
0277:                    if (state.getAttribute(STATE_CHAT_PRESENCE_OBSERVER) == null) {
0278:                        // get the current tool placement
0279:                        Placement placement = ToolManager.getCurrentPlacement();
0280:
0281:                        // location is just placement
0282:                        String location = placement.getId();
0283:
0284:                        // the html element to update on delivery
0285:                        String elementId = PRESENCE_PANEL;
0286:
0287:                        // setup an observer to notify us when presence at this location changes
0288:                        PresenceObservingCourier observer = new PresenceObservingCourier(
0289:                                location, elementId);
0290:
0291:                        state.setAttribute(STATE_CHAT_PRESENCE_OBSERVER,
0292:                                observer);
0293:                    }
0294:                }
0295:                // repopulate state object and title bar when default chat room changes
0296:                else {
0297:                    PortletConfig config = portlet.getPortletConfig();
0298:                    // read the channel from configuration, or, if not specified, use the default for the page
0299:                    String channel = StringUtil.trimToNull(config
0300:                            .getInitParameter(PARAM_CHANNEL));
0301:                    if (channel == null) {
0302:                        channel = ChatService.channelReference(ToolManager
0303:                                .getCurrentPlacement().getContext(),
0304:                                SiteService.MAIN_CONTAINER);
0305:                    }
0306:                    state.setAttribute(STATE_CHANNEL_REF, channel);
0307:                    String channelName = rundata.getParameters().getString(
0308:                            FORM_CHANNEL);
0309:                    // update the tool config
0310:                    Placement placement = ToolManager.getCurrentPlacement();
0311:                    placement.setTitle(rb.getString("chatroom") + "\""
0312:                            + channelName + "\"");
0313:                }
0314:                // make sure the observer is in sync with state
0315:                updateObservationOfChannel(state, portlet.getID());
0316:
0317:            } // initState
0318:
0319:            /**
0320:             * Setup our observer to be watching for change events for our channel.
0321:             * 
0322:             * @param peid
0323:             *        The portlet id.
0324:             */
0325:            private void updateObservationOfChannel(SessionState state,
0326:                    String peid) {
0327:                // make sure the pattern matches the channel we are looking at
0328:                String channel = (String) state.getAttribute(STATE_CHANNEL_REF);
0329:                Reference r = EntityManager.newReference(channel);
0330:                String pattern = ChatService.messageReference(r.getContext(), r
0331:                        .getId(), "");
0332:
0333:                // update the observer looking for new messages
0334:                ChatObservingCourier observer1 = (ChatObservingCourier) state
0335:                        .getAttribute(STATE_OBSERVER);
0336:                observer1.setResourcePattern(pattern);
0337:
0338:            } // updateObservationOfChannel
0339:
0340:            /**
0341:             * Get the channel from ChatService or create it.
0342:             */
0343:            private ChatChannel getChannel(SessionState state, String name) {
0344:                // deal with the channel not yet existing
0345:                ChatChannel channel = null;
0346:                try {
0347:                    channel = ChatService.getChatChannel(name);
0348:                } catch (IdUnusedException ignore) {
0349:                } catch (PermissionException ignore) {
0350:                }
0351:
0352:                if ((channel == null)
0353:                        && (state.getAttribute(STATE_CHANNEL_PROBLEM) == null)) {
0354:                    // create the channel
0355:                    try {
0356:                        ChatChannelEdit edit = ChatService.addChatChannel(name);
0357:                        ChatService.commitChannel(edit);
0358:                        channel = edit;
0359:                    } catch (IdUsedException e) {
0360:                        // strange, the channel already exists!
0361:                        try {
0362:                            channel = ChatService.getChatChannel(name);
0363:                        } catch (IdUnusedException ignore) {
0364:                        } catch (PermissionException ignore) {
0365:                        }
0366:                    } catch (IdInvalidException e) {
0367:                        // stranger, we cannot use this id!
0368:                        state.setAttribute(STATE_CHANNEL_PROBLEM, rb
0369:                                .getString("thischat"));
0370:                        M_log.warn("doSend(): creating channel: ", e);
0371:                    } catch (PermissionException e) {
0372:                        // rats, this user cannot create the channel
0373:                        state.setAttribute(STATE_CHANNEL_PROBLEM, rb
0374:                                .getString("youdonot2"));
0375:                    }
0376:                }
0377:                return channel;
0378:
0379:            } // getChannel
0380:
0381:            /**
0382:             * Update the state message-filtering attributes to use the filtering criteria specified by the filter_type and filter_param parameters.
0383:             * 
0384:             * @param state
0385:             *        The session state.
0386:             * @param filter_type
0387:             *        A string specifying the filter type.
0388:             * @param filter_param
0389:             *        A string specifying the filter param.
0390:             */
0391:            private void updateMessageFilters(SessionState state,
0392:                    String filter_type, String filter_param) {
0393:                state.setAttribute(STATE_MORE_MESSAGES_LABEL, rb
0394:                        .getString("showall"));
0395:                state.setAttribute(STATE_MORE_MESSAGES_FILTER,
0396:                        new SelectAllMessages());
0397:                state.setAttribute(STATE_FILTER_PARAM, String
0398:                        .valueOf(DEFAULT_PARAM));
0399:
0400:                state.setAttribute(STATE_MORE_SELECTED, new Boolean(false));
0401:                state.setAttribute(STATE_FILTER_TYPE, filter_type);
0402:                if (filter_type.equals(FILTER_ALL)) {
0403:                    state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0404:                            new SelectMessagesByTime(DEFAULT_DAYS));
0405:                    state.setAttribute(STATE_FEWER_MESSAGES_LABEL, rb
0406:                            .getString("showpast")
0407:                            + " " + DEFAULT_DAYS + " " + rb.getString("days"));
0408:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0409:                            .getAttribute(STATE_MORE_MESSAGES_FILTER));
0410:                    state.setAttribute(STATE_MORE_SELECTED, new Boolean(true));
0411:                } else if (filter_type.equals(FILTER_TODAY)) {
0412:                    state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0413:                            new SelectTodaysMessages());
0414:                    state.setAttribute(STATE_FEWER_MESSAGES_LABEL, rb
0415:                            .getString("showtoday"));
0416:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0417:                            .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0418:                } else if (filter_type.equals(FILTER_BY_NUMBER)) {
0419:                    int number = DEFAULT_MSGS;
0420:                    try {
0421:                        number = Integer.parseInt(filter_param);
0422:                        if (number <= 0) {
0423:                            throw new Exception();
0424:                        }
0425:                        state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0426:                                new SelectMessagesByNumber(number));
0427:                        state.setAttribute(STATE_FILTER_PARAM, filter_param);
0428:                    } catch (Exception e) {
0429:                        // M_log.warn("updateMessageFilters() invalid param: " );
0430:                    }
0431:                    state.setAttribute(STATE_FILTER_PARAM, String
0432:                            .valueOf(number));
0433:                    state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0434:                            new SelectMessagesByNumber(number));
0435:                    state.setAttribute(STATE_FEWER_MESSAGES_LABEL, rb
0436:                            .getString("showlast")
0437:                            + " " + number + " " + rb.getString("messages"));
0438:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0439:                            .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0440:                } else if (filter_type.equals(FILTER_BY_TIME)) {
0441:                    int number = DEFAULT_DAYS;
0442:                    try {
0443:                        number = Integer.parseInt(filter_param);
0444:                        if (number <= 0) {
0445:                            throw new Exception();
0446:                        }
0447:                    } catch (Exception e) {
0448:                        // M_log.warn("updateMessageFilters() invalid param: " );
0449:                    }
0450:                    state.setAttribute(STATE_FILTER_PARAM, String
0451:                            .valueOf(number));
0452:                    state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0453:                            new SelectMessagesByTime(number));
0454:                    state.setAttribute(STATE_FEWER_MESSAGES_LABEL, rb
0455:                            .getString("showpast")
0456:                            + " " + number + " " + rb.getString("days"));
0457:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0458:                            .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0459:                } else {
0460:                    state.setAttribute(STATE_FILTER_PARAM, String
0461:                            .valueOf(DEFAULT_DAYS));
0462:                    state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0463:                            new SelectMessagesByTime(DEFAULT_DAYS));
0464:                    state.setAttribute(STATE_FEWER_MESSAGES_LABEL, rb
0465:                            .getString("showpast")
0466:                            + " " + DEFAULT_DAYS + " " + rb.getString("days"));
0467:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0468:                            .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0469:                }
0470:
0471:            } // updateMessageFilters
0472:
0473:            /**
0474:             * build the context for the Main (Layout) panel
0475:             * 
0476:             * @return (optional) template name for this panel
0477:             */
0478:            public String buildMainPanelContext(VelocityPortlet portlet,
0479:                    Context context, RunData rundata, SessionState state) {
0480:                context.put("tlang", rb);
0481:                // if there's an alert message specifically targetted for main fraim, display it
0482:                String msg = (String) state.getAttribute(STATE_MAIN_MESSAGE);
0483:                context.put("alertMessage", msg);
0484:                state.removeAttribute(STATE_MAIN_MESSAGE);
0485:
0486:                String mode = (String) state.getAttribute(STATE_MODE);
0487:                if (MODE_OPTIONS.equals(mode)) {
0488:                    return buildOptionsPanelContext(portlet, context, rundata,
0489:                            state);
0490:                } else if (MODE_CONFIRM_DELETE_MESSAGE.equals(mode)) {
0491:                    return buildConfirmDeleteMessagePanelContext(portlet,
0492:                            context, rundata, state);
0493:                }
0494:
0495:                List focus_elements = new Vector();
0496:                focus_elements.add(CONTROL_PANEL);
0497:                focus_elements.add(FORM_MESSAGE);
0498:
0499:                context.put("focus_path", focus_elements);
0500:
0501:                context.put("panel-control", CONTROL_PANEL);
0502:                context.put("panel-monitor", MONITOR_PANEL);
0503:                context.put("panel-presence", PRESENCE_PANEL);
0504:                context.put("panel-toolbar", TOOLBAR_PANEL);
0505:
0506:                // the url for the chat courier, using a quick 10 second refresh
0507:                setVmCourier(rundata.getRequest(), 10);
0508:
0509:                return (String) getContext(rundata).get("template") + "-Layout";
0510:
0511:            } // buildLayoutPanelContext
0512:
0513:            /**
0514:             * Handle a user clicking on the view-date menu.
0515:             */
0516:            public void doToggle_date_display(RunData runData, Context context) {
0517:                toggleState(runData, STATE_DISPLAY_DATE);
0518:
0519:                // schedule a refresh of the monitor panel
0520:                String peid = ((JetspeedRunData) runData).getJs_peid();
0521:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
0522:                        + MONITOR_PANEL);
0523:
0524:                // schedule a return of focus to Control panel (from the parent's perspective)
0525:                String[] focusPath = { CONTROL_PANEL, FORM_MESSAGE };
0526:                scheduleFocusRefresh(focusPath);
0527:
0528:            } // doToggle_date_display
0529:
0530:            /**
0531:             * Handle a user clicking on the view-time menu.
0532:             */
0533:            public void doToggle_time_display(RunData runData, Context context) {
0534:                toggleState(runData, STATE_DISPLAY_TIME);
0535:
0536:                // schedule a refresh of the monitor panel
0537:                String peid = ((JetspeedRunData) runData).getJs_peid();
0538:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
0539:                        + MONITOR_PANEL);
0540:
0541:                // schedule a return of focus to Control panel (from the parent's perspective)
0542:                String[] focusPath = { CONTROL_PANEL, FORM_MESSAGE };
0543:                scheduleFocusRefresh(focusPath);
0544:
0545:            } // doToggle_time_display
0546:
0547:            /**
0548:             * Handle a user clicking on the time-date dropdown.
0549:             */
0550:            public void doChange_time_date_display(RunData runData,
0551:                    Context context) {
0552:                String peid = ((JetspeedRunData) runData).getJs_peid();
0553:                SessionState state = ((JetspeedRunData) runData)
0554:                        .getPortletSessionState(peid);
0555:
0556:                String time_date = runData.getParameters().getString(
0557:                        "changeView");
0558:
0559:                boolean oldTime = ((Boolean) state
0560:                        .getAttribute(STATE_DISPLAY_TIME)).booleanValue();
0561:                boolean oldDate = ((Boolean) state
0562:                        .getAttribute(STATE_DISPLAY_DATE)).booleanValue();
0563:
0564:                if (time_date.equals(rb.getString("bar.onlytime"))) {
0565:                    // if the time is not shown, toggle to show it
0566:                    if (!oldTime) {
0567:                        toggleState(runData, STATE_DISPLAY_TIME);
0568:                    }
0569:                    // if the date is being shown, toggle to hide it
0570:                    if (oldDate) {
0571:                        toggleState(runData, STATE_DISPLAY_DATE);
0572:                    }
0573:                } else if (time_date.equals(rb.getString("bar.datetime"))) {
0574:                    // if the time is not shown, toggle to show it
0575:                    if (!oldTime) {
0576:                        toggleState(runData, STATE_DISPLAY_TIME);
0577:                    }
0578:                    // if the date is not shown, toggle to show it
0579:                    if (!oldDate) {
0580:                        toggleState(runData, STATE_DISPLAY_DATE);
0581:                    }
0582:                } else if (time_date.equals(rb.getString("bar.onlydate"))) {
0583:                    // if the time is being shown, toggle to hide it
0584:                    if (oldTime) {
0585:                        toggleState(runData, STATE_DISPLAY_TIME);
0586:                    }
0587:                    // if the date is not shown, toggle to show it
0588:                    if (!oldDate) {
0589:                        toggleState(runData, STATE_DISPLAY_DATE);
0590:                    }
0591:                } else if (time_date.equals(rb.getString("bar.nodatetime"))) {
0592:                    // if the time is being shown, toggle to hide it
0593:                    if (oldTime) {
0594:                        toggleState(runData, STATE_DISPLAY_TIME);
0595:                    }
0596:                    // if the date is being shown, toggle to hide it
0597:                    if (oldDate) {
0598:                        toggleState(runData, STATE_DISPLAY_DATE);
0599:                    }
0600:                }
0601:
0602:                state.setAttribute(TIME_DATE_SELECT, time_date);
0603:
0604:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
0605:                        + MONITOR_PANEL);
0606:
0607:                // schedule a return of focus to Control panel (from the parent's perspective)
0608:                String[] focusPath = { CONTROL_PANEL, FORM_MESSAGE };
0609:                scheduleFocusRefresh(focusPath);
0610:
0611:            } // doChange_time_date_display
0612:
0613:            /**
0614:             * Handle a user clicking on the sound-alert button.
0615:             */
0616:            public void doToggle_sound_alert(RunData runData, Context context) {
0617:                String peid = ((JetspeedRunData) runData).getJs_peid();
0618:                SessionState state = ((JetspeedRunData) runData)
0619:                        .getPortletSessionState(peid);
0620:
0621:                // toggle the state setting
0622:                boolean newValue = !((Boolean) state
0623:                        .getAttribute(STATE_SOUND_ALERT)).booleanValue();
0624:                state.setAttribute(STATE_SOUND_ALERT, new Boolean(newValue));
0625:                ChatObservingCourier observer = (ChatObservingCourier) state
0626:                        .getAttribute(STATE_OBSERVER);
0627:                observer.alertEnabled(newValue);
0628:
0629:                // schedule a return of focus to Control panel (from the parent's perspective)
0630:                String[] focusPath = { CONTROL_PANEL, FORM_MESSAGE };
0631:                scheduleFocusRefresh(focusPath);
0632:
0633:            } // doToggle_sound_alert
0634:
0635:            /**
0636:             * Toggle the state attribute
0637:             * 
0638:             * @param stateName
0639:             *        The name of the state attribute to toggle
0640:             */
0641:            private void toggleState(RunData runData, String stateName) {
0642:                // access the portlet element id to find our state
0643:                // %%% use CHEF api instead of Jetspeed to get state
0644:                String peid = ((JetspeedRunData) runData).getJs_peid();
0645:                SessionState state = ((JetspeedRunData) runData)
0646:                        .getPortletSessionState(peid);
0647:
0648:                // toggle the state setting
0649:                boolean newValue = !((Boolean) state.getAttribute(stateName))
0650:                        .booleanValue();
0651:                state.setAttribute(stateName, new Boolean(newValue));
0652:
0653:            } // toggleState
0654:
0655:            /**
0656:             * Handle a user clicking on the show-all/show-some button.
0657:             */
0658:            public void doToggle_filter(RunData runData, Context context) {
0659:                // access the portlet element id to find our state
0660:                // %%% use CHEF api instead of Jetspeed to get state
0661:                String peid = ((JetspeedRunData) runData).getJs_peid();
0662:                SessionState state = ((JetspeedRunData) runData)
0663:                        .getPortletSessionState(peid);
0664:
0665:                // toggle the filter setting between show-more and show-fewer
0666:                if (((Boolean) state.getAttribute(STATE_MORE_SELECTED))
0667:                        .booleanValue()) {
0668:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0669:                            .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0670:                } else {
0671:                    state.setAttribute(STATE_MESSAGE_FILTER, state
0672:                            .getAttribute(STATE_MORE_MESSAGES_FILTER));
0673:                }
0674:                toggleState(runData, STATE_MORE_SELECTED);
0675:
0676:                if (((String) state.getAttribute(STATE_FILTER_TYPE))
0677:                        .equals(FILTER_BY_NUMBER)) {
0678:                    if (!((Boolean) state.getAttribute(STATE_MORE_SELECTED))
0679:                            .booleanValue()) {
0680:                        try {
0681:                            int number = Integer.parseInt((String) state
0682:                                    .getAttribute(STATE_FILTER_PARAM));
0683:                            state.setAttribute(STATE_FEWER_MESSAGES_FILTER,
0684:                                    new SelectMessagesByNumber(number));
0685:                            state.setAttribute(STATE_MESSAGE_FILTER, state
0686:                                    .getAttribute(STATE_FEWER_MESSAGES_FILTER));
0687:                        } catch (NumberFormatException e) {
0688:                        }
0689:                    }
0690:                }
0691:
0692:                // schedule a refresh of the monitor panel
0693:                schedulePeerFrameRefresh(mainPanelUpdateId(peid) + "."
0694:                        + MONITOR_PANEL);
0695:
0696:                // schedule a return of focus to Control panel (from the parent's perspective)
0697:                String[] focusPath = { CONTROL_PANEL, FORM_MESSAGE };
0698:                scheduleFocusRefresh(focusPath);
0699:
0700:            } // doToggle_filter
0701:
0702:            /**
0703:             * build the context for the Toolbar panel
0704:             * 
0705:             * @return (optional) template name for this panel
0706:             */
0707:            public String buildToolbarPanelContext(VelocityPortlet portlet,
0708:                    Context context, RunData rundata, SessionState state) {
0709:                // we might be on the way to a permissions...
0710:                if (state.getAttribute(STATE_PERMISSIONS) != null) {
0711:                    state.removeAttribute(STATE_PERMISSIONS);
0712:                    doPermissionsNow(rundata, context);
0713:                }
0714:
0715:                context.put("tlang", rb);
0716:                // build the menu
0717:                Menu bar = new MenuImpl(portlet, rundata, (String) state
0718:                        .getAttribute(STATE_ACTION));
0719:                /*
0720:                 * boolean displayDate = ((Boolean)state.getAttribute(STATE_DISPLAY_DATE)).booleanValue(); bar.add( new MenuEntry((displayDate ? rb.getString("hided") + " " : " " + rb.getString("showd")), null, true, (displayDate ? MenuItem.CHECKED_TRUE :
0721:                 * MenuItem.CHECKED_FALSE), "doToggle_date_display") ); boolean displayTime = ((Boolean)state.getAttribute(STATE_DISPLAY_TIME)).booleanValue(); bar.add( new MenuEntry((displayTime ? rb.getString("hidet") + " " : " " + rb.getString("showt")), null,
0722:                 * true, (displayTime ? MenuItem.CHECKED_TRUE : MenuItem.CHECKED_FALSE), "doToggle_time_display") );
0723:                 */
0724:                context.put("selectedView", state
0725:                        .getAttribute(TIME_DATE_SELECT));
0726:
0727:                // if the java beep is disabled, don't offer the alert
0728:                if (ServerConfigurationService.getBoolean("java.beep", false)) {
0729:                    boolean soundAlert = ((Boolean) state
0730:                            .getAttribute(STATE_SOUND_ALERT)).booleanValue();
0731:                    bar.add(new MenuEntry((soundAlert ? rb.getString("turnoff")
0732:                            + " " : " " + rb.getString("turnon")), null, true,
0733:                            (soundAlert ? MenuItem.CHECKED_TRUE
0734:                                    : MenuItem.CHECKED_FALSE),
0735:                            "doToggle_sound_alert"));
0736:                }
0737:
0738:                boolean moreSelected = ((Boolean) state
0739:                        .getAttribute(STATE_MORE_SELECTED)).booleanValue();
0740:                /*
0741:                 * bar.add( new MenuEntry((moreSelected ? (String)state.getAttribute(STATE_FEWER_MESSAGES_LABEL) : (String)state.getAttribute(STATE_MORE_MESSAGES_LABEL)), null, true, (moreSelected ? MenuItem.CHECKED_TRUE : MenuItem.CHECKED_FALSE),
0742:                 * "doToggle_filter") );
0743:                 */
0744:                String pastLabel = "";
0745:                String fewerLabel = (String) state
0746:                        .getAttribute(STATE_FEWER_MESSAGES_LABEL);
0747:                String moreLabel = (String) state
0748:                        .getAttribute(STATE_MORE_MESSAGES_LABEL);
0749:                context.put("pastLabel",
0750:                        (moreSelected ? moreLabel : fewerLabel));
0751:                context.put("fewerLabel", fewerLabel);
0752:                context.put("moreLabel", moreLabel);
0753:
0754:                // add options if allowed
0755:                addOptionsMenu(bar, (JetspeedRunData) rundata);
0756:
0757:                // add permissions, if allowed
0758:                if (SiteService.allowUpdateSite(ToolManager
0759:                        .getCurrentPlacement().getContext())) {
0760:                    bar.add(new MenuEntry(rb.getString("permis"),
0761:                            "doPermissions"));
0762:                }
0763:
0764:                context.put(Menu.CONTEXT_MENU, bar);
0765:                context.put(Menu.CONTEXT_ACTION, state
0766:                        .getAttribute(STATE_ACTION));
0767:
0768:                return null; // (String)getContext(rundata).get("template") + "-Toolbar";
0769:
0770:            } // buildToolbarPanelContext
0771:
0772:            /**
0773:             * build the context for the List panel
0774:             * 
0775:             * @return (optional) template name for this panel
0776:             */
0777:            public String buildListPanelContext(VelocityPortlet portlet,
0778:                    Context context, RunData rundata, SessionState state) {
0779:                // display info
0780:                context.put("tlang", rb);
0781:                context.put("display_date", state
0782:                        .getAttribute(STATE_DISPLAY_DATE));
0783:                context.put("display_time", state
0784:                        .getAttribute(STATE_DISPLAY_TIME));
0785:                context.put("display_user", state
0786:                        .getAttribute(STATE_DISPLAY_USER));
0787:                context.put("sound_alert", state
0788:                        .getAttribute(STATE_SOUND_ALERT));
0789:
0790:                // provide a color mapper to keep track of user color coding for the session
0791:                context.put("color_mapper", (ColorMapper) state
0792:                        .getAttribute(STATE_COLOR_MAPPER));
0793:
0794:                // find the channel and get the messages
0795:                try {
0796:                    ChatFilter filter = (ChatFilter) state
0797:                            .getAttribute(STATE_MESSAGE_FILTER);
0798:
0799:                    // // TODO: TIMING
0800:                    // if (CurrentService.getInThread("DEBUG") == null)
0801:                    // CurrentService.setInThread("DEBUG", new StringBuffer());
0802:                    // long startTime = System.currentTimeMillis();
0803:
0804:                    List msgs = ChatService.getMessages((String) state
0805:                            .getAttribute(STATE_CHANNEL_REF), filter
0806:                            .getAfterDate(), filter.getLimitedToLatest(), true, // asc
0807:                            true, // TODO: inc drafts
0808:                            false // not pubview onyl
0809:                            );
0810:
0811:                    // // TODO: TIMING
0812:                    // long endTime = System.currentTimeMillis();
0813:                    // if (endTime-startTime > /*5*/000)
0814:                    // {
0815:                    // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
0816:                    // if (buf != null)
0817:                    // {
0818:                    // buf.insert(0,"ChatAction.list: "
0819:                    // + state.getAttribute(STATE_CHANNEL_REF)
0820:                    // + " time: " + (endTime - startTime));
0821:                    // }
0822:                    // }
0823:
0824:                    context.put("chat_messages", msgs);
0825:
0826:                    // boolean allowed = ChatService.allowRemoveChannel((String)state.getAttribute(STATE_CHANNEL_REF));
0827:                    // context.put("allowRemoveMessage", new Boolean(allowed));
0828:
0829:                    ChatChannel channel = getChannel(state, (String) state
0830:                            .getAttribute(STATE_CHANNEL_REF));
0831:                    context.put("channel", channel);
0832:
0833:                } catch (PermissionException e) {
0834:                    context.put("alertMessage", rb.getString("youdonot1"));
0835:                } catch (Exception e) {
0836:                    M_log.warn("buildListPanelContext()", e);
0837:                }
0838:
0839:                // inform the observing courier that we just updated the page...
0840:                // if there are pending requests to do so they can be cleared
0841:                justDelivered(state);
0842:
0843:                return null;
0844:
0845:            } // buildListPanelContext
0846:
0847:            /**
0848:             * build the context for the Control panel (has a send field)
0849:             * 
0850:             * @return (optional) template name for this panel
0851:             */
0852:            public String buildControlPanelContext(VelocityPortlet portlet,
0853:                    Context context, RunData rundata, SessionState state) {
0854:                context.put("tlang", rb);
0855:                // put this pannel's name for the return url
0856:                context.put("panel-control", CONTROL_PANEL);
0857:
0858:                // set the action for form processing
0859:                context.put(Menu.CONTEXT_ACTION, state
0860:                        .getAttribute(STATE_ACTION));
0861:
0862:                // set the form field name for the send button
0863:                context.put("form-submit", BUTTON + "doSend");
0864:
0865:                // set the form field name for the send button
0866:                context.put("form-message", FORM_MESSAGE);
0867:
0868:                // is this user going to be able to post (add permission on the channel)
0869:                boolean allowed = ChatService.allowAddChannel((String) state
0870:                        .getAttribute(STATE_CHANNEL_REF));
0871:                if (!allowed) {
0872:                    context.put("alertMessage", rb.getString("youdonot3")); // %%% or no message?
0873:                }
0874:                context.put("allow-send", new Boolean(allowed));
0875:
0876:                return null;
0877:
0878:            } // buildControlPanelContext
0879:
0880:            /**
0881:             * build the context for the Presence panel (has a send field)
0882:             * 
0883:             * @return (optional) template name for this panel
0884:             */
0885:            public String buildPresencePanelContext(VelocityPortlet portlet,
0886:                    Context context, RunData rundata, SessionState state) {
0887:                context.put("tlang", rb);
0888:                String template = null;
0889:
0890:                // get the observer
0891:                PresenceObservingCourier observer = (PresenceObservingCourier) state
0892:                        .getAttribute(STATE_CHAT_PRESENCE_OBSERVER);
0893:
0894:                // put into context a list of sessions with chat presence
0895:                String location = observer.getLocation();
0896:
0897:                // refresh our presence at the location
0898:                PresenceService.setPresence(location);
0899:
0900:                // get the current presence list (User objects) for this page
0901:                List users = PresenceService.getPresentUsers(location);
0902:                context.put("users", users);
0903:
0904:                // inform the observing courier that we just updated the page...
0905:                // if there are pending requests to do so they can be cleared
0906:                observer.justDelivered();
0907:
0908:                return null;
0909:
0910:            } // buildPresencePanelContext
0911:
0912:            /**
0913:             * Handle a user posting a new chat message.
0914:             */
0915:            public void doSend(RunData runData, Context context) {
0916:                // access the portlet element id to find our state
0917:                // %%% use CHEF api instead of Jetspeed to get state
0918:                String peid = ((JetspeedRunData) runData).getJs_peid();
0919:                SessionState state = ((JetspeedRunData) runData)
0920:                        .getPortletSessionState(peid);
0921:
0922:                // read in the message input
0923:                // %%% JANDERSE - The user enters plaintext, but messages are now stored as formatted text;
0924:                // therefore, the plaintext must be converted to formatted text when it is returned from the browser.
0925:                String message = runData.getParameters().getCleanString(
0926:                        FORM_MESSAGE);
0927:                message = FormattedText
0928:                        .convertPlaintextToFormattedText(message);
0929:
0930:                // ignore empty messages
0931:                if ((message == null) || (message.length() == 0))
0932:                    return;
0933:
0934:                // deal with the channel not yet existing
0935:                // TODO: we don't really need to read the channel to post... -ggolden
0936:
0937:                // // TODO: TIMING
0938:                // if (CurrentService.getInThread("DEBUG") == null)
0939:                // CurrentService.setInThread("DEBUG", new StringBuffer());
0940:                // long startTime = System.currentTimeMillis();
0941:
0942:                ChatChannel channel = getChannel(state, (String) state
0943:                        .getAttribute(STATE_CHANNEL_REF));
0944:
0945:                // // TODO: TIMING
0946:                // long endTime = System.currentTimeMillis();
0947:                // if (endTime-startTime > /*5*/000)
0948:                // {
0949:                // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
0950:                // if (buf != null)
0951:                // {
0952:                // buf.insert(0,"ChatAction.doSend: "
0953:                // + state.getAttribute(STATE_CHANNEL_REF)
0954:                // + " time: " + (endTime - startTime));
0955:                // }
0956:                // }
0957:
0958:                // post the message
0959:                if (channel != null) {
0960:                    try {
0961:                        ChatMessageEdit edit = channel.addChatMessage();
0962:                        edit.setBody(message);
0963:                        channel.commitMessage(edit);
0964:                    } catch (PermissionException e) {
0965:                        addAlert(state, rb.getString("youdonot3"));
0966:                    } catch (Exception e) // %%% why?
0967:                    {
0968:                        addAlert(state, rb.getString("therewaspro"));
0969:                        M_log.warn("doSend()", e);
0970:                    }
0971:                } else {
0972:                    addAlert(state, (String) state
0973:                            .getAttribute(STATE_CHANNEL_PROBLEM));
0974:                }
0975:
0976:            } // doSend
0977:
0978:            /**
0979:             * Setup for the options panel.
0980:             */
0981:            public String buildOptionsPanelContext(VelocityPortlet portlet,
0982:                    Context context, RunData rundata, SessionState state) {
0983:                context.put("tlang", rb);
0984:                // provide "filter_type" with the current default value for filtering messages
0985:                context.put("filter_type", (String) state
0986:                        .getAttribute(STATE_FILTER_TYPE));
0987:
0988:                // provide "filter_type_form" with form field name for selecting a message filter
0989:                context.put("filter_type_form", FORM_FILTER_TYPE);
0990:
0991:                // provide "filter_days_param" as current value or default value for number of days
0992:                context.put("filter_days_param", (String) state
0993:                        .getAttribute(STATE_FILTER_PARAM));
0994:
0995:                // provide "filter_days_param_form" with form field name for filter parameter (number of days/messages)
0996:                context.put("filter_days_param_form", FORM_FILTER_PARAM_DAYS);
0997:
0998:                // provide "filter_param" as current value or default value for number of days/messages
0999:                context.put("filter_number_param", (String) state
1000:                        .getAttribute(STATE_FILTER_PARAM));
1001:
1002:                // provide "filter_param_form" with form field name for filter parameter (number of days/messages)
1003:                context.put("filter_number_param_form",
1004:                        FORM_FILTER_PARAM_NUMBER);
1005:
1006:                // provide "default_chat_channel" with the dafault channel-id for the user/group
1007:                context.put("default_chat_channel", SiteService.MAIN_CONTAINER);
1008:
1009:                // provide "chat_channel" with the current channel's id
1010:                String placementContext = ToolManager.getCurrentPlacement()
1011:                        .getContext();
1012:                String defaultChannel = ChatService.channelReference(
1013:                        placementContext, SiteService.MAIN_CONTAINER);
1014:                String sitePrefix = defaultChannel.substring(0, defaultChannel
1015:                        .lastIndexOf(SiteService.MAIN_CONTAINER));
1016:                String currentChannel = ((String) state
1017:                        .getAttribute(STATE_CHANNEL_REF)).substring(sitePrefix
1018:                        .length());
1019:                context.put("chat_channel", currentChannel);
1020:
1021:                // provide "chat_channels" as a list of channels belonging to this site
1022:
1023:                // // TODO: TIMING
1024:                // if (CurrentService.getInThread("DEBUG") == null)
1025:                // CurrentService.setInThread("DEBUG", new StringBuffer());
1026:                // long startTime = System.currentTimeMillis();
1027:
1028:                Iterator aChannel = ChatService.getChannelIds(placementContext)
1029:                        .iterator();
1030:
1031:                // // TODO: TIMING
1032:                // long endTime = System.currentTimeMillis();
1033:                // if (endTime-startTime > /*5*/000)
1034:                // {
1035:                // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
1036:                // if (buf != null)
1037:                // {
1038:                // buf.insert(0,"ChatAction.options: "
1039:                // + state.getAttribute(STATE_CHANNEL_REF)
1040:                // + " time: " + (endTime - startTime));
1041:                // }
1042:                // }
1043:
1044:                List channel_list = new Vector();
1045:                while (aChannel.hasNext()) {
1046:                    String theChannel = (String) aChannel.next();
1047:                    if (!theChannel.equals(SiteService.MAIN_CONTAINER)
1048:                            && !theChannel.equals(currentChannel)) {
1049:                        channel_list.add(theChannel);
1050:                    }
1051:                }
1052:                context.put("chat_channels", channel_list);
1053:
1054:                // provide "new_chat_channel" as flag to create a new channel
1055:                context.put("new_chat_channel", NEW_CHAT_CHANNEL);
1056:
1057:                // provide "form_new_channel" with form field name for specifying a new channel name
1058:                context.put("form_new_channel", FORM_NEW_CHANNEL);
1059:
1060:                // provide "chat_channel_form" with the form name for the new channel selection field
1061:                context.put("chat_channel_form", FORM_CHANNEL);
1062:
1063:                // set the action for form processing
1064:                context.put(Menu.CONTEXT_ACTION, state
1065:                        .getAttribute(STATE_ACTION));
1066:                context.put("form-submit", BUTTON + "doUpdate");
1067:                context.put("form-cancel", BUTTON + "doCancel");
1068:
1069:                // pick the "-customize" template based on the standard template name
1070:                String template = (String) getContext(rundata).get("template");
1071:                return template + "-customize";
1072:
1073:            } // buildOptionsPanelContext
1074:
1075:            public String buildConfirmDeleteMessagePanelContext(
1076:                    VelocityPortlet portlet, Context context, RunData rundata,
1077:                    SessionState state) {
1078:                context.put("tlang", rb);
1079:                // Put the message object into the context (the message that is about to be deleted)
1080:                try {
1081:                    // String messageRef = ChatService.messageReference(
1082:                    // (String) state.getAttribute(STATE_CHANNEL_REF),
1083:                    // (String) state.getAttribute("messageid"));
1084:                    // Reference msgRef = new Reference(messageRef);
1085:
1086:                    // // TODO: TIMING
1087:                    // if (CurrentService.getInThread("DEBUG") == null)
1088:                    // CurrentService.setInThread("DEBUG", new StringBuffer());
1089:                    // long startTime = System.currentTimeMillis();
1090:
1091:                    // Message msg = ChatService.getMessage(msgRef);
1092:                    String messageid = (String) state.getAttribute("messageid");
1093:                    ChatChannel channel = ChatService
1094:                            .getChatChannel((String) state
1095:                                    .getAttribute(STATE_CHANNEL_REF));
1096:                    ChatMessage msg = channel.getChatMessage(messageid);
1097:
1098:                    // // TODO: TIMING
1099:                    // long endTime = System.currentTimeMillis();
1100:                    // if (endTime-startTime > /*5*/000)
1101:                    // {
1102:                    // StringBuffer buf = (StringBuffer) CurrentService.getInThread("DEBUG");
1103:                    // if (buf != null)
1104:                    // {
1105:                    // buf.insert(0,"ChatAction.confirmDelete: "
1106:                    // + state.getAttribute(STATE_CHANNEL_REF)
1107:                    // + " time: " + (endTime - startTime));
1108:                    // }
1109:                    // }
1110:
1111:                    context.put("message", msg);
1112:                } catch (PermissionException e) {
1113:                    context.put("alertMessage", rb.getString("youdonot4"));
1114:                } catch (IdUnusedException e) {
1115:                } catch (Exception e) {
1116:                    M_log.warn("buildConfirmDeleteMessagePanelContext()", e);
1117:                }
1118:
1119:                String template = (String) getContext(rundata).get("template");
1120:                return template + "-delete";
1121:            }
1122:
1123:            /**
1124:             * Handle a user clicking the "Done" button in the Options panel
1125:             */
1126:            public void doUpdate(RunData data, Context context) {
1127:                // access the portlet element id to find our state
1128:                // %%% use CHEF api instead of Jetspeed to get state
1129:                String peid = ((JetspeedRunData) data).getJs_peid();
1130:                SessionState state = ((JetspeedRunData) data)
1131:                        .getPortletSessionState(peid);
1132:
1133:                String placementContext = ToolManager.getCurrentPlacement()
1134:                        .getContext();
1135:                String newChannel = data.getParameters()
1136:                        .getString(FORM_CHANNEL);
1137:                String currentChannel = ((String) state
1138:                        .getAttribute(STATE_CHANNEL_REF))
1139:                        .substring(placementContext.length() + 1);
1140:
1141:                if (newChannel != null && newChannel.equals(NEW_CHAT_CHANNEL)) {
1142:                    newChannel = data.getParameters().getString(
1143:                            FORM_NEW_CHANNEL);
1144:                    // make sure channel name is valid Resource ID (for items entered by user)
1145:                    if (!Validator.checkResourceId(newChannel)) {
1146:                        // if name is not valid, save error message and return to Options panel
1147:                        addAlert(state, rb.getString("youent") + " \" "
1148:                                + newChannel + " \" " + rb.getString("forchat"));
1149:                        return;
1150:                    }
1151:                }
1152:                if (newChannel != null && !newChannel.equals(currentChannel)) {
1153:                    state.setAttribute(STATE_CHANNEL_REF, ChatService
1154:                            .channelReference(placementContext, newChannel));
1155:                    if (M_log.isDebugEnabled())
1156:                        M_log.debug("doUpdate(): newChannel: " + newChannel);
1157:                    // ChatChannel chan = getChannel(state, newChannel);
1158:                    updateObservationOfChannel(state, peid);
1159:
1160:                    // update the tool config
1161:                    Placement placement = ToolManager.getCurrentPlacement();
1162:                    placement.getPlacementConfig().setProperty(PARAM_CHANNEL,
1163:                            (String) state.getAttribute(STATE_CHANNEL_REF));
1164:                    placement.setTitle(rb.getString("chatroom") + " \" "
1165:                            + newChannel + " \" ");
1166:
1167:                    // deliver an update to the title panel (to show the new title)
1168:                    String titleId = titlePanelUpdateId(peid);
1169:                    schedulePeerFrameRefresh(titleId);
1170:                }
1171:
1172:                // filter
1173:                String filter_type = data.getParameters().getString(
1174:                        FORM_FILTER_TYPE);
1175:                if (filter_type != null) {
1176:                    if (filter_type.equals(FILTER_ALL)) {
1177:                        if (!filter_type.equals((String) state
1178:                                .getAttribute(STATE_FILTER_TYPE))) {
1179:                            updateMessageFilters(state, filter_type, null);
1180:
1181:                            // update the tool config
1182:                            Placement placement = ToolManager
1183:                                    .getCurrentPlacement();
1184:                            placement.getPlacementConfig().setProperty(
1185:                                    PARAM_FILTER_TYPE,
1186:                                    (String) state
1187:                                            .getAttribute(STATE_FILTER_TYPE));
1188:                            placement.getPlacementConfig().setProperty(
1189:                                    PARAM_FILTER_PARAM,
1190:                                    (String) state
1191:                                            .getAttribute(STATE_FILTER_PARAM));
1192:                        }
1193:                    } else if (filter_type.equals(FILTER_BY_TIME)) {
1194:                        String filter_days_param = data.getParameters()
1195:                                .getString(FORM_FILTER_PARAM_DAYS);
1196:                        if (filter_days_param != null) {
1197:                            if (!filter_type.equals((String) state
1198:                                    .getAttribute(STATE_FILTER_TYPE))
1199:                                    || !filter_days_param.equals((String) state
1200:                                            .getAttribute(STATE_FILTER_PARAM))) {
1201:                                updateMessageFilters(state, filter_type,
1202:                                        filter_days_param);
1203:
1204:                                // update the tool config
1205:                                Placement placement = ToolManager
1206:                                        .getCurrentPlacement();
1207:                                placement
1208:                                        .getPlacementConfig()
1209:                                        .setProperty(
1210:                                                PARAM_FILTER_TYPE,
1211:                                                (String) state
1212:                                                        .getAttribute(STATE_FILTER_TYPE));
1213:                                placement
1214:                                        .getPlacementConfig()
1215:                                        .setProperty(
1216:                                                PARAM_FILTER_PARAM,
1217:                                                (String) state
1218:                                                        .getAttribute(STATE_FILTER_PARAM));
1219:                            }
1220:                        }
1221:                    } else if (filter_type.equals(FILTER_BY_NUMBER)) {
1222:                        String filter_number_param = data.getParameters()
1223:                                .getString(FORM_FILTER_PARAM_NUMBER);
1224:                        if (filter_number_param != null) {
1225:                            if (!filter_type.equals((String) state
1226:                                    .getAttribute(STATE_FILTER_TYPE))
1227:                                    || !filter_number_param
1228:                                            .equals((String) state
1229:                                                    .getAttribute(STATE_FILTER_PARAM))) {
1230:                                updateMessageFilters(state, filter_type,
1231:                                        filter_number_param);
1232:
1233:                                // update the tool config
1234:                                Placement placement = ToolManager
1235:                                        .getCurrentPlacement();
1236:                                placement
1237:                                        .getPlacementConfig()
1238:                                        .setProperty(
1239:                                                PARAM_FILTER_TYPE,
1240:                                                (String) state
1241:                                                        .getAttribute(STATE_FILTER_TYPE));
1242:                                placement
1243:                                        .getPlacementConfig()
1244:                                        .setProperty(
1245:                                                PARAM_FILTER_PARAM,
1246:                                                (String) state
1247:                                                        .getAttribute(STATE_FILTER_PARAM));
1248:                            }
1249:                        }
1250:                    }
1251:                }
1252:
1253:                // we are done with customization... back to the main mode
1254:                state.removeAttribute(STATE_MODE);
1255:
1256:                // re-enable auto-updates when leaving options
1257:                enableObservers(state);
1258:
1259:                // commit the change
1260:                saveOptions();
1261:
1262:            } // doUpdate
1263:
1264:            /**
1265:             * Handle a user clicking the "Done" button in the Options panel
1266:             */
1267:            public void doCancel(RunData data, Context context) {
1268:                // access the portlet element id to find our state
1269:                // %%% use CHEF api instead of Jetspeed to get state
1270:                String peid = ((JetspeedRunData) data).getJs_peid();
1271:                SessionState state = ((JetspeedRunData) data)
1272:                        .getPortletSessionState(peid);
1273:
1274:                // we are done with customization... back to the main mode
1275:                state.removeAttribute(STATE_MODE);
1276:
1277:                // re-enable auto-updates when leaving options
1278:                enableObservers(state);
1279:
1280:                // cancel the options
1281:                cancelOptions();
1282:
1283:            } // doCancel
1284:
1285:            /**
1286:             * Handle a user deleting a message - put up a confirmation page
1287:             */
1288:            public void doConfirmDeleteMessage(RunData data, Context context) {
1289:                // access the portlet element id to find our state
1290:                // %%% use CHEF api instead of Jetspeed to get state
1291:                String peid = ((JetspeedRunData) data).getJs_peid();
1292:                SessionState state = ((JetspeedRunData) data)
1293:                        .getPortletSessionState(peid);
1294:
1295:                String messageid = data.getParameters().getString("messageid");
1296:
1297:                state.setAttribute("messageid", messageid);
1298:                state.setAttribute(STATE_MODE, MODE_CONFIRM_DELETE_MESSAGE);
1299:
1300:                // schedule a main refresh
1301:                schedulePeerFrameRefresh(mainPanelUpdateId(peid));
1302:            }
1303:
1304:            /**
1305:             * Handle a user deleting a message - they've already confirmed the deletion, just delete it now
1306:             */
1307:            public void doDeleteMessage(RunData data, Context context) {
1308:                // access the portlet element id to find our state
1309:                // %%% use CHEF api instead of Jetspeed to get state
1310:                String peid = ((JetspeedRunData) data).getJs_peid();
1311:                SessionState state = ((JetspeedRunData) data)
1312:                        .getPortletSessionState(peid);
1313:
1314:                // find the message and delete it now!
1315:                try {
1316:                    String messageid = (String) state.getAttribute("messageid");
1317:                    ChatChannel channel = ChatService
1318:                            .getChatChannel((String) state
1319:                                    .getAttribute(STATE_CHANNEL_REF));
1320:                    channel.removeMessage(messageid);
1321:                } catch (PermissionException e) {
1322:                    context.put("alertMessage", rb.getString("youdonot4"));
1323:                } catch (IdUnusedException e) {
1324:                } catch (Exception e) {
1325:                    M_log.warn("doDeleteMessage()", e);
1326:                }
1327:
1328:                state.removeAttribute("messageid");
1329:                state.removeAttribute(STATE_MODE);
1330:            }
1331:
1332:            interface ChatFilter {
1333:                Time getAfterDate();
1334:
1335:                int getLimitedToLatest();
1336:            }
1337:
1338:            /** A filter */
1339:            class SelectMessagesByTime implements  ChatFilter {
1340:                /** The number of days back to accept messages. */
1341:                private int m_days = 0;
1342:
1343:                /** The cutoff time - messages before this are rejected. */
1344:                private Time m_cutoff = null;
1345:
1346:                /**
1347:                 * Constructor
1348:                 * 
1349:                 * @param days
1350:                 *        The number of days back to accept messages.
1351:                 */
1352:                public SelectMessagesByTime(int days) {
1353:                    // Log.info("chef", this + ".SelectMessagesByTime(" + days + ")");
1354:                    m_days = days;
1355:
1356:                    // compute the cutoff - Note: use the filter fast - the clock is ticking.
1357:                    m_cutoff = TimeService.newTime(System.currentTimeMillis()
1358:                            - ((long) days * 24l * 60l * 60l * 1000l));
1359:
1360:                } // SelectMessagesByTime
1361:
1362:                public Time getAfterDate() {
1363:                    return m_cutoff;
1364:                }
1365:
1366:                public int getLimitedToLatest() {
1367:                    return 0;
1368:                }
1369:
1370:                public String toString() {
1371:                    return this .getClass().getName() + " "
1372:                            + Integer.toString(m_days);
1373:                }
1374:            }
1375:
1376:            /** A filter */
1377:            class SelectMessagesByNumber implements  ChatFilter {
1378:                /** The cutoff value - messages before this date/time are rejected. */
1379:                private Time m_first;
1380:
1381:                /** the number of messages to select */
1382:                private int m_number;
1383:
1384:                /**
1385:                 * Constructor
1386:                 * 
1387:                 * @param number
1388:                 *        The number of the messages to be returned
1389:                 */
1390:                public SelectMessagesByNumber(int number) {
1391:                    // Log.info("chef", this + ".SelectMessagesByNumber(" + number + ")");
1392:                    m_number = number;
1393:                }
1394:
1395:                public Time getAfterDate() {
1396:                    return null;
1397:                }
1398:
1399:                public int getLimitedToLatest() {
1400:                    return m_number;
1401:                }
1402:
1403:                public String toString() {
1404:                    return this .getClass().getName() + " " + m_number;
1405:
1406:                } // toString
1407:
1408:            } // SelectMessagesByNumber
1409:
1410:            /** A filter */
1411:            class SelectAllMessages implements  ChatFilter {
1412:                /** Constructor for the SelectAllMessages object */
1413:                public SelectAllMessages() {
1414:                    // Log.info("chef", this + ".SelectAllMessages()");
1415:                } // SelectAllMessages
1416:
1417:                public Time getAfterDate() {
1418:                    return null;
1419:                }
1420:
1421:                public int getLimitedToLatest() {
1422:                    return 0;
1423:                }
1424:
1425:                public String toString() {
1426:                    return this .getClass().getName();
1427:
1428:                } // toString
1429:
1430:            } // SelectAllMessages
1431:
1432:            /** A filter that gets all messages since midnight today, local time */
1433:            class SelectTodaysMessages implements  ChatFilter {
1434:                /** The cutoff time - messages before this are rejected. */
1435:                private Time m_cutoff = null;
1436:
1437:                /** Constructor for the SelectTodaysMessages object */
1438:                public SelectTodaysMessages() {
1439:                    super ();
1440:                    // Log.info("chef", this + ".SelectTodaysMessages()");
1441:
1442:                    TimeBreakdown now = (TimeService.newTime(System
1443:                            .currentTimeMillis())).breakdownLocal();
1444:                    // compute the cutoff for midnight today.
1445:                    m_cutoff = TimeService.newTimeLocal(now.getYear(), now
1446:                            .getMonth(), now.getDay(), 0, 0, 0, 0);
1447:
1448:                } // SelectTodaysMessages
1449:
1450:                public Time getAfterDate() {
1451:                    return m_cutoff;
1452:                }
1453:
1454:                public int getLimitedToLatest() {
1455:                    return 0;
1456:                }
1457:
1458:                public String toString() {
1459:                    return this .getClass().getName();
1460:
1461:                } // toString
1462:
1463:            } // SelectTodaysMessages
1464:
1465:            /**
1466:             * Handle a request to set options.
1467:             */
1468:            public void doOptions(RunData runData, Context context) {
1469:                super .doOptions(runData, context);
1470:
1471:                // access the portlet element id to find our state
1472:                String peid = ((JetspeedRunData) runData).getJs_peid();
1473:                SessionState state = ((JetspeedRunData) runData)
1474:                        .getPortletSessionState(peid);
1475:
1476:                // if there's an alert message, divert it to the main frame
1477:                String msg = (String) state.getAttribute(STATE_MESSAGE);
1478:                state.setAttribute(STATE_MAIN_MESSAGE, msg);
1479:                state
1480:                        .removeAttribute(VelocityPortletPaneledAction.STATE_MESSAGE);
1481:
1482:            } // doOptions
1483:
1484:            /**
1485:             * Fire up the permissions editor, next request cycle
1486:             */
1487:            public void doPermissions(RunData data, Context context) {
1488:                String peid = ((JetspeedRunData) data).getJs_peid();
1489:                SessionState state = ((JetspeedRunData) data)
1490:                        .getPortletSessionState(peid);
1491:
1492:                // trigger the switch on the next request (which is going to happen after this action is processed with its redirect response to the build)
1493:                state.setAttribute(STATE_PERMISSIONS, STATE_PERMISSIONS);
1494:
1495:                // schedule a main refresh to excape from the toolbar panel
1496:                schedulePeerFrameRefresh(mainPanelUpdateId(peid));
1497:            }
1498:
1499:            /**
1500:             * Fire up the permissions editor
1501:             */
1502:            protected void doPermissionsNow(RunData data, Context context) {
1503:                // get into helper mode with this helper tool
1504:                startHelper(data.getRequest(), "sakai.permissions.helper");
1505:
1506:                String peid = ((JetspeedRunData) data).getJs_peid();
1507:                SessionState state = ((JetspeedRunData) data)
1508:                        .getPortletSessionState(peid);
1509:
1510:                String channelRefStr = (String) state
1511:                        .getAttribute(STATE_CHANNEL_REF);
1512:                Reference channelRef = EntityManager
1513:                        .newReference(channelRefStr);
1514:                String siteRef = SiteService.siteReference(channelRef
1515:                        .getContext());
1516:
1517:                // setup for editing the permissions of the site for this tool, using the roles of this site, too
1518:                state.setAttribute(PermissionsHelper.TARGET_REF, siteRef);
1519:
1520:                // ... with this description
1521:                state.setAttribute(PermissionsHelper.DESCRIPTION, rb
1522:                        .getString("setpermis")
1523:                        + " "
1524:                        + SiteService.getSiteDisplay(channelRef.getContext()));
1525:
1526:                // ... showing only locks that are prpefixed with this
1527:                state.setAttribute(PermissionsHelper.PREFIX, "chat.");
1528:            }
1529:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.